16c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato/* 26c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Copyright (C) 2012 The Android Open Source Project 36c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 46c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 56c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * you may not use this file except in compliance with the License. 66c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * You may obtain a copy of the License at 76c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 86c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 96c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Unless required by applicable law or agreed to in writing, software 116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * See the License for the specific language governing permissions and 146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * limitations under the License. 156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onoratopackage android.util.proto; 186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onoratoimport android.annotation.TestApi; 206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onoratoimport android.util.Log; 216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onoratoimport java.util.ArrayList; 236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato/** 256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * A stream of bytes containing a read pointer and a write pointer, 266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * backed by a set of fixed-size buffers. There are write functions for the 276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * primitive types stored by protocol buffers, but none of the logic 286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * for tags, inner objects, or any of that. 296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Terminology: 316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * *Pos: Position in the whole data set (as if it were a single buffer). 326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * *Index: Position within a buffer. 336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * *BufIndex: Index of a buffer within the mBuffers list 346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * @hide 356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato@TestApi 376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onoratopublic final class EncodedBuffer { 386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private static final String TAG = "EncodedBuffer"; 396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private final ArrayList<byte[]> mBuffers = new ArrayList<byte[]>(); 416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private final int mChunkSize; 436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The number of buffers in mBuffers. Stored separately to avoid the extra 466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * function call to size() everywhere for bounds checking. 476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mBufferCount; 496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The buffer we are currently writing to. 526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private byte[] mWriteBuffer; 546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The index into mWriteBuffer that we will write to next. 576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * It may point to the end of the buffer, in which case, 586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * the NEXT write will allocate a new buffer. 596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mWriteIndex; 616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The index of mWriteBuffer in mBuffers. 646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mWriteBufIndex; 666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The buffer we are currently reading from. 696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private byte[] mReadBuffer; 716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The index of mReadBuffer in mBuffers. 746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mReadBufIndex; 766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The index into mReadBuffer that we will read from next. 796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * It may point to the end of the buffer, in which case, 806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * the NEXT read will advance to the next buffer. 816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mReadIndex; 836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * The amount of data in the last buffer. 866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mReadLimit = -1; 886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * How much data there is total. 916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private int mReadableSize = -1; 936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public EncodedBuffer() { 956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato this(0); 966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Construct an EncodedBuffer object. 1006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 1016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * @param chunkSize The size of the buffers to use. If chunkSize <= 0, a default 1026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * size will be used instead. 1036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public EncodedBuffer(int chunkSize) { 1056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (chunkSize <= 0) { 1066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato chunkSize = 8 * 1024; 1076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mChunkSize = chunkSize; 1096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = new byte[mChunkSize]; 1106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.add(mWriteBuffer); 1116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBufferCount = 1; 1126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 1156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Buffer management. 1166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 1176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Rewind the read and write pointers, and record how much data was last written. 1206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void startEditing() { 1226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadableSize = ((mWriteBufIndex) * mChunkSize) + mWriteIndex; 1236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadLimit = mWriteIndex; 1246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = mBuffers.get(0); 1266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = 0; 1276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex = 0; 1286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBuffer = mWriteBuffer; 1306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBufIndex = 0; 1316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex = 0; 1326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Rewind the read pointer. Don't touch the write pointer. 1366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void rewindRead() { 1386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBuffer = mBuffers.get(0); 1396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBufIndex = 0; 1406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex = 0; 1416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Only valid after startEditing. Returns -1 before that. 1456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getReadableSize() { 1476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return mReadableSize; 1486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 1516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Reading from the read position. 1526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 1536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Only valid after startEditing. 1566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getReadPos() { 1586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return ((mReadBufIndex) * mChunkSize) + mReadIndex; 1596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Skip over _amount_ bytes. 1636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void skipRead(int amount) { 1656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (amount < 0) { 1666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new RuntimeException("skipRead with negative amount=" + amount); 1676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (amount == 0) { 1696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return; 1706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (amount <= mChunkSize - mReadIndex) { 1726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex += amount; 1736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 1746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato amount -= mChunkSize - mReadIndex; 1756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex = amount % mChunkSize; 1766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mReadIndex == 0) { 1776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex = mChunkSize; 1786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBufIndex += (amount / mChunkSize); 1796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 1806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBufIndex += 1 + (amount / mChunkSize); 1816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBuffer = mBuffers.get(mReadBufIndex); 1836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 1866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 1876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Read one byte from the stream and advance the read pointer. 1886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 1896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * @throws IndexOutOfBoundsException if the read point is past the end of 1906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * the buffer or past the read limit previously set by startEditing(). 1916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 1926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public byte readRawByte() { 1936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mReadBufIndex > mBufferCount 1946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato || (mReadBufIndex == mBufferCount - 1 && mReadIndex >= mReadLimit)) { 1956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new IndexOutOfBoundsException("Trying to read too much data" 1966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mReadBufIndex=" + mReadBufIndex + " mBufferCount=" + mBufferCount 1976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mReadIndex=" + mReadIndex + " mReadLimit=" + mReadLimit); 1986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 1996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mReadIndex >= mChunkSize) { 2006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBufIndex++; 2016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadBuffer = mBuffers.get(mReadBufIndex); 2026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mReadIndex = 0; 2036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return mReadBuffer[mReadIndex++]; 2056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Read an unsigned varint. The value will be returend in a java signed long. 2096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public long readRawUnsigned() { 2116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int bits = 0; 2126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato long result = 0; 2136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato while (true) { 2146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final byte b = readRawByte(); 2156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato result |= ((long)(b & 0x7F)) << bits; 2166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((b & 0x80) == 0) { 2176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return result; 2186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato bits += 7; 2206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (bits > 64) { 2216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new ProtoParseException("Varint too long -- " + getDebugString()); 2226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Read 32 little endian bits from the stream. 2286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int readRawFixed32() { 2306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return (readRawByte() & 0x0ff) 2316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((readRawByte() & 0x0ff) << 8) 2326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((readRawByte() & 0x0ff) << 16) 2336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((readRawByte() & 0x0ff) << 24); 2346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 2376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Writing at a the end of the stream. 2386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 2396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Advance to the next write buffer, allocating it if necessary. 2426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 2436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Must be called immediately <b>before</b> the next write, not after a write, 2446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * so that a dangling empty buffer is not created. Doing so will interfere 2456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * with the expectation that mWriteIndex will point past the end of the buffer 2466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * until the next read happens. 2476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private void nextWriteBuffer() { 2496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex++; 2506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mWriteBufIndex >= mBufferCount) { 2516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = new byte[mChunkSize]; 2526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.add(mWriteBuffer); 2536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBufferCount++; 2546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 2556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = mBuffers.get(mWriteBufIndex); 2566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = 0; 2586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write a single byte to the stream. 2626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawByte(byte val) { 2646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mWriteIndex >= mChunkSize) { 2656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato nextWriteBuffer(); 2666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer[mWriteIndex++] = val; 2686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Return how many bytes a 32 bit unsigned varint will take when written to the stream. 2726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public static int getRawVarint32Size(int val) { 2746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffff << 7)) == 0) return 1; 2756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffff << 14)) == 0) return 2; 2766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffff << 21)) == 0) return 3; 2776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffff << 28)) == 0) return 4; 2786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return 5; 2796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write an unsigned varint to the stream. A signed value would need to take 10 bytes. 2836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 2846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * @param val treated as unsigned. 2856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 2866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawVarint32(int val) { 2876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato while (true) { 2886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & ~0x7F) == 0) { 2896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)val); 2906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return; 2916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 2926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)((val & 0x7F) | 0x80)); 2936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato val >>>= 7; 2946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 2976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 2986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 2996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Return how many bytes a 32 bit signed zig zag value will take when written to the stream. 3006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public static int getRawZigZag32Size(int val) { 3026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return getRawVarint32Size(zigZag32(val)); 3036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write a zig-zag encoded value. 3076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 3086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * @param val treated as signed 3096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawZigZag32(int val) { 3116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawVarint32(zigZag32(val)); 3126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Return how many bytes a 64 bit varint will take when written to the stream. 3166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public static int getRawVarint64Size(long val) { 3186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 7)) == 0) return 1; 3196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 14)) == 0) return 2; 3206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 21)) == 0) return 3; 3216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 28)) == 0) return 4; 3226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 35)) == 0) return 5; 3236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 42)) == 0) return 6; 3246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 49)) == 0) return 7; 3256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 56)) == 0) return 8; 3266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & (0xffffffffffffffffL << 63)) == 0) return 9; 3276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return 10; 3286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write a 64 bit varint to the stream. 3326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawVarint64(long val) { 3346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato while (true) { 3356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if ((val & ~0x7FL) == 0) { 3366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)val); 3376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return; 3386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 3396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)((val & 0x7F) | 0x80)); 3406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato val >>>= 7; 3416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Return how many bytes a signed 64 bit zig zag value will take when written to the stream. 3476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public static int getRawZigZag64Size(long val) { 3496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return getRawVarint64Size(zigZag64(val)); 3506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write a 64 bit signed zig zag value to the stream. 3546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawZigZag64(long val) { 3566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawVarint64(zigZag64(val)); 3576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write 4 little endian bytes to the stream. 3616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawFixed32(int val) { 3636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val)); 3646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 8)); 3656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 16)); 3666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 24)); 3676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write 8 little endian bytes to the stream. 3716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawFixed64(long val) { 3736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val)); 3746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 8)); 3756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 16)); 3766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 24)); 3776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 32)); 3786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 40)); 3796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 48)); 3806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawByte((byte)(val >> 56)); 3816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write a buffer to the stream. Writes nothing if val is null or zero-length. 3856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawBuffer(byte[] val) { 3876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (val != null && val.length > 0) { 3886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeRawBuffer(val, 0, val.length); 3896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 3926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 3936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Write part of an array of bytes. 3946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 3956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeRawBuffer(byte[] val, int offset, int length) { 3966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (val == null) { 3976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return; 3986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 3996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Write up to the amount left in the first chunk to write. 4006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int amt = length < (mChunkSize - mWriteIndex) ? length : (mChunkSize - mWriteIndex); 4016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (amt > 0) { 4026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato System.arraycopy(val, offset, mWriteBuffer, mWriteIndex, amt); 4036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex += amt; 4046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato length -= amt; 4056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato offset += amt; 4066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato while (length > 0) { 4086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // We know we're now at the beginning of a chunk 4096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato nextWriteBuffer(); 4106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato amt = length < mChunkSize ? length : mChunkSize; 4116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato System.arraycopy(val, offset, mWriteBuffer, mWriteIndex, amt); 4126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex += amt; 4136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato length -= amt; 4146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato offset += amt; 4156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 4186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 4196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Copies data _size_ bytes of data within this buffer from _srcOffset_ 4206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * to the current write position. Like memmov but handles the chunked buffer. 4216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 4226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void writeFromThisBuffer(int srcOffset, int size) { 4236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mReadLimit < 0) { 4246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new IllegalStateException("writeFromThisBuffer before startEditing"); 4256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (srcOffset < getWritePos()) { 4276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new IllegalArgumentException("Can only move forward in the buffer --" 4286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " srcOffset=" + srcOffset + " size=" + size + " " + getDebugString()); 4296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (srcOffset + size > mReadableSize) { 4316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new IllegalArgumentException("Trying to move more data than there is --" 4326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " srcOffset=" + srcOffset + " size=" + size + " " + getDebugString()); 4336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (size == 0) { 4356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return; 4366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (srcOffset == ((mWriteBufIndex) * mChunkSize) + mWriteIndex /* write pos */) { 4386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Writing to the same location. Just advance the write pointer. We already 4396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // checked that size is in bounds, so we don't need to do any more range 4406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // checking. 4416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (size <= mChunkSize - mWriteIndex) { 4426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex += size; 4436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 4446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato size -= mChunkSize - mWriteIndex; 4456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = size % mChunkSize; 4466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mWriteIndex == 0) { 4476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Roll it back so nextWriteBuffer can do its job 4486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // on the next call (also makes mBuffers.get() not 4496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // fail if we're at the end). 4506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = mChunkSize; 4516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex += (size / mChunkSize); 4526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 4536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex += 1 + (size / mChunkSize); 4546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = mBuffers.get(mWriteBufIndex); 4566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 4586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Loop through the buffer, copying as much as we can each time. 4596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // We already bounds checked so we don't need to do it again here, 4606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // and nextWriteBuffer will never allocate. 4616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int readBufIndex = srcOffset / mChunkSize; 4626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato byte[] readBuffer = mBuffers.get(readBufIndex); 4636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int readIndex = srcOffset % mChunkSize; 4646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato while (size > 0) { 4656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mWriteIndex >= mChunkSize) { 4666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato nextWriteBuffer(); 4676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (readIndex >= mChunkSize) { 4696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato readBufIndex++; 4706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato readBuffer = mBuffers.get(readBufIndex); 4716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato readIndex = 0; 4726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int spaceInWriteBuffer = mChunkSize - mWriteIndex; 4746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int availableInReadBuffer = mChunkSize - readIndex; 4756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int amt = Math.min(size, Math.min(spaceInWriteBuffer, availableInReadBuffer)); 4766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato System.arraycopy(readBuffer, readIndex, mWriteBuffer, mWriteIndex, amt); 4776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex += amt; 4786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato readIndex += amt; 4796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato size -= amt; 4806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 4846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 4856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Writing at a particular location. 4866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 4876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 4886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 4896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Returns the index into the virtual array of the write pointer. 4906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 4916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getWritePos() { 4926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return ((mWriteBufIndex) * mChunkSize) + mWriteIndex; 4936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 4946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 4956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 4966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Resets the write pointer to a virtual location as returned by getWritePos. 4976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 4986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void rewindWriteTo(int writePos) { 4996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (writePos > getWritePos()) { 5006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato throw new RuntimeException("rewindWriteTo only can go backwards" + writePos); 5016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex = writePos / mChunkSize; 5036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = writePos % mChunkSize; 5046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (mWriteIndex == 0 && mWriteBufIndex != 0) { 5056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Roll back so nextWriteBuffer can do its job on the next call 5066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // but at the first write we're at 0. 5076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteIndex = mChunkSize; 5086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBufIndex--; 5096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mWriteBuffer = mBuffers.get(mWriteBufIndex); 5116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Read a 32 bit value from the stream. 5156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 5166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Doesn't touch or affect mWritePos. 5176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getRawFixed32At(int pos) { 5196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return (0x00ff & (int)mBuffers.get(pos / mChunkSize)[pos % mChunkSize]) 5206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((0x0ff & (int)mBuffers.get((pos+1) / mChunkSize)[(pos+1) % mChunkSize]) << 8) 5216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((0x0ff & (int)mBuffers.get((pos+2) / mChunkSize)[(pos+2) % mChunkSize]) << 16) 5226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato | ((0x0ff & (int)mBuffers.get((pos+3) / mChunkSize)[(pos+3) % mChunkSize]) << 24); 5236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Overwrite a 32 bit value in the stream. 5276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * 5286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Doesn't touch or affect mWritePos. 5296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void editRawFixed32(int pos, int val) { 5316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.get(pos / mChunkSize)[pos % mChunkSize] = (byte)(val); 5326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.get((pos+1) / mChunkSize)[(pos+1) % mChunkSize] = (byte)(val >> 8); 5336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.get((pos+2) / mChunkSize)[(pos+2) % mChunkSize] = (byte)(val >> 16); 5346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato mBuffers.get((pos+3) / mChunkSize)[(pos+3) % mChunkSize] = (byte)(val >> 24); 5356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 5386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Zigging and zagging 5396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 5406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Zig-zag encode a 32 bit value. 5436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private static int zigZag32(int val) { 5456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return (val << 1) ^ (val >> 31); 5466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Zig-zag encode a 64 bit value. 5506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private static long zigZag64(long val) { 5526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return (val << 1) ^ (val >> 63); 5536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 5566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // Debugging / testing 5576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // 5586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // VisibleForTesting 5596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Get a copy of the first _size_ bytes of data. This is not range 5626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * checked, and if the bounds are outside what has been written you will 5636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * get garbage and if it is outside the buffers that have been allocated, 5646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * you will get an exception. 5656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public byte[] getBytes(int size) { 5676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final byte[] result = new byte[size]; 5686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int bufCount = size / mChunkSize; 5706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int bufIndex; 5716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int writeIndex = 0; 5726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato for (bufIndex=0; bufIndex<bufCount; bufIndex++) { 5746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato System.arraycopy(mBuffers.get(bufIndex), 0, result, writeIndex, mChunkSize); 5756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato writeIndex += mChunkSize; 5766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int lastSize = size - (bufCount * mChunkSize); 5796c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (lastSize > 0) { 5806c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato System.arraycopy(mBuffers.get(bufIndex), 0, result, writeIndex, lastSize); 5816c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5826c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5836c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return result; 5846c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5856c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5866c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5876c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Get the number of chunks allocated. 5886c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5896c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // VisibleForTesting 5906c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getChunkCount() { 5916c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return mBuffers.size(); 5926c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 5936c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 5946c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 5956c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Get the write position inside the current write chunk. 5966c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 5976c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // VisibleForTesting 5986c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getWriteIndex() { 5996c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return mWriteIndex; 6006c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6016c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 6026c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 6036c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Get the index of the current write chunk in the list of chunks. 6046c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 6056c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato // VisibleForTesting 6066c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public int getWriteBufIndex() { 6076c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return mWriteBufIndex; 6086c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6096c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 6106c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 6116c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Return debugging information about this EncodedBuffer object. 6126c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 6136c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public String getDebugString() { 6146c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return "EncodedBuffer( mChunkSize=" + mChunkSize + " mBuffers.size=" + mBuffers.size() 6156c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mBufferCount=" + mBufferCount + " mWriteIndex=" + mWriteIndex 6166c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mWriteBufIndex=" + mWriteBufIndex + " mReadBufIndex=" + mReadBufIndex 6176c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mReadIndex=" + mReadIndex + " mReadableSize=" + mReadableSize 6186c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato + " mReadLimit=" + mReadLimit + " )"; 6196c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6206c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 6216c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 6226c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Print the internal buffer chunks. 6236c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 6246c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public void dumpBuffers(String tag) { 6256c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int N = mBuffers.size(); 6266c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int start = 0; 6276c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato for (int i=0; i<N; i++) { 6286c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato start += dumpByteString(tag, "{" + i + "} ", start, mBuffers.get(i)); 6296c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6306c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6316c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 6326c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 6336c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Print the internal buffer chunks. 6346c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 6356c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato public static void dumpByteString(String tag, String prefix, byte[] buf) { 6366c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato dumpByteString(tag, prefix, 0, buf); 6376c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6386c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato 6396c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato /** 6406c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato * Print the internal buffer chunks. 6416c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato */ 6426c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato private static int dumpByteString(String tag, String prefix, int start, byte[] buf) { 6436c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato StringBuffer sb = new StringBuffer(); 6446c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int length = buf.length; 6456c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato final int lineLen = 16; 6466c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato int i; 6476c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato for (i=0; i<length; i++) { 6486c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (i % lineLen == 0) { 6496c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (i != 0) { 6506c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato Log.d(tag, sb.toString()); 6516c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb = new StringBuffer(); 6526c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6536c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append(prefix); 6546c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append('['); 6556c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append(start + i); 6566c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append(']'); 6576c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append(' '); 6586c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 6596c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append(' '); 6606c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6616c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato byte b = buf[i]; 6626c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato byte c = (byte)((b >> 4) & 0x0f); 6636c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (c < 10) { 6646c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append((char)('0' + c)); 6656c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 6666c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append((char)('a' - 10 + c)); 6676c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6686c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato byte d = (byte)(b & 0x0f); 6696c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato if (d < 10) { 6706c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append((char)('0' + d)); 6716c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } else { 6726c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato sb.append((char)('a' - 10 + d)); 6736c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6746c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6756c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato Log.d(tag, sb.toString()); 6766c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato return length; 6776c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato } 6786c9547d8e1c35d7afa9bc9be11d5ff86ec60db14Joe Onorato} 679