/* * Copyright (C) 2008 Esmertec AG. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.im.imps; import java.nio.ByteBuffer; /** * A helper class to split the payload into several segments to meet the size * constraint of the sms. * */ public class SmsSplitter { private static final int MAX_SEGMENT_COUNT = 26; private ByteBuffer mOutBuffer; private int mMaxSegmentLen; private byte[] mData; private int mPreambleEnd; private int mCurrentSegment; private int mSegmentCount; public SmsSplitter(int maxLen) { mMaxSegmentLen = maxLen; mOutBuffer = ByteBuffer.allocate(maxLen); } /** * Split the data into several segments to meet the size constraint. * * @param data * The data to split. MUST be a valid PTS primitive. * @return The count of segments of the result or -1 if the data is too long. */ public int split(byte[] data) { mData = data; mCurrentSegment = 0; calculateSegments(); if (mSegmentCount > MAX_SEGMENT_COUNT) { mSegmentCount = -1; } return mSegmentCount; } public boolean hasNext() { return mCurrentSegment < mSegmentCount; } /** * Gets the next segment. * * @return The next segment. * @throws IndexOutOfBoundsException */ public byte[] getNext() { if (mCurrentSegment >= mSegmentCount) { throw new IndexOutOfBoundsException(); } byte[] segment; if (mSegmentCount == 1) { segment = mData; } else { mOutBuffer.clear(); // The original preamble mOutBuffer.put(mData, 0, mPreambleEnd); // Two character of DD mOutBuffer.put((byte) ('a' + mCurrentSegment)); mOutBuffer.put((byte) ('a' + mSegmentCount - 1)); // The space after preamble mOutBuffer.put((byte) ' '); // The payload int segmentPayload = mMaxSegmentLen - mPreambleEnd - 3; int offset = mPreambleEnd + 1 + segmentPayload * mCurrentSegment; int len = (offset + segmentPayload > mData.length) ? mData.length - offset : segmentPayload; mOutBuffer.put(mData, offset, len); mOutBuffer.flip(); segment = new byte[mOutBuffer.limit()]; mOutBuffer.get(segment); } mCurrentSegment++; return segment; } private void calculateSegments() { int totalLen = mData.length; if (totalLen < mMaxSegmentLen) { mSegmentCount = 1; } else { searchPreambleEnd(); int newPreambleLen = mPreambleEnd + 2; int segmentPayload = mMaxSegmentLen - newPreambleLen - 1; int totalPayload = totalLen - mPreambleEnd - 1; mSegmentCount = (totalPayload + segmentPayload -1) / segmentPayload; } } private void searchPreambleEnd() { byte[] data = mData; int index = 0; while(index < data.length && data[index] != ' ') { index++; } mPreambleEnd = index; } }