OSDN Git Service

auto import from //depot/cupcake/@135843
[android-x86/packages-apps-IM.git] / src / com / android / im / imps / SmsSplitter.java
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package com.android.im.imps;
18
19 import java.nio.ByteBuffer;
20
21 /**
22  * A helper class to split the payload into several segments to meet the size
23  * constraint of the sms.
24  *
25  */
26 public class SmsSplitter {
27     private static final int MAX_SEGMENT_COUNT = 26;
28
29     private ByteBuffer mOutBuffer;
30     private int mMaxSegmentLen;
31
32     private byte[] mData;
33     private int mPreambleEnd;
34
35     private int mCurrentSegment;
36     private int mSegmentCount;
37
38     public SmsSplitter(int maxLen) {
39         mMaxSegmentLen = maxLen;
40         mOutBuffer = ByteBuffer.allocate(maxLen);
41     }
42
43     /**
44      * Split the data into several segments to meet the size constraint.
45      *
46      * @param data
47      *            The data to split. MUST be a valid PTS primitive.
48      * @return The count of segments of the result or -1 if the data is too long.
49      */
50     public int split(byte[] data) {
51         mData = data;
52         mCurrentSegment = 0;
53         calculateSegments();
54         if (mSegmentCount > MAX_SEGMENT_COUNT) {
55             mSegmentCount = -1;
56         }
57         return mSegmentCount;
58     }
59
60     public boolean hasNext() {
61         return mCurrentSegment < mSegmentCount;
62     }
63
64     /**
65      * Gets the next segment.
66      *
67      * @return The next segment.
68      * @throws IndexOutOfBoundsException
69      */
70     public byte[] getNext() {
71         if (mCurrentSegment >= mSegmentCount) {
72             throw new IndexOutOfBoundsException();
73         }
74         byte[] segment;
75         if (mSegmentCount == 1) {
76             segment = mData;
77         } else {
78             mOutBuffer.clear();
79             // The original preamble
80             mOutBuffer.put(mData, 0, mPreambleEnd);
81             // Two character of DD
82             mOutBuffer.put((byte) ('a' + mCurrentSegment));
83             mOutBuffer.put((byte) ('a' + mSegmentCount - 1));
84             // The space after preamble
85             mOutBuffer.put((byte) ' ');
86
87             // The payload
88             int segmentPayload = mMaxSegmentLen - mPreambleEnd - 3;
89             int offset = mPreambleEnd + 1 + segmentPayload * mCurrentSegment;
90             int len = (offset + segmentPayload > mData.length) ?
91                     mData.length - offset : segmentPayload;
92             mOutBuffer.put(mData, offset, len);
93
94             mOutBuffer.flip();
95             segment = new byte[mOutBuffer.limit()];
96             mOutBuffer.get(segment);
97         }
98         mCurrentSegment++;
99         return segment;
100     }
101
102     private void calculateSegments() {
103         int totalLen = mData.length;
104         if (totalLen < mMaxSegmentLen) {
105             mSegmentCount = 1;
106         } else {
107             searchPreambleEnd();
108             int newPreambleLen = mPreambleEnd + 2;
109             int segmentPayload = mMaxSegmentLen - newPreambleLen - 1;
110             int totalPayload = totalLen - mPreambleEnd - 1;
111             mSegmentCount = (totalPayload + segmentPayload -1) / segmentPayload;
112         }
113     }
114
115     private void searchPreambleEnd() {
116         byte[] data = mData;
117         int index = 0;
118         while(index < data.length && data[index] != ' ') {
119             index++;
120         }
121         mPreambleEnd = index;
122     }
123 }