ByteArray.java revision de75089fb7216d19e9c22cce4dc62a49513477d3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.util; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.DataInputStream; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 2499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Wrapper for a {@code byte[]}, which provides read-only access and 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can "reveal" a partial slice of the underlying array. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>Note:</b> Multibyte accessors all use big-endian order. 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class ByteArray { 3099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} underlying array */ 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final byte[] bytes; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0}; start index of the slice (inclusive) */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int start; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0, <= bytes.length}; size computed as 3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code end - start} (in the constructor) */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int size; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} the underlying array 4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param start {@code >= 0;} start index of the slice (inclusive) 4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param end {@code >= start, <= bytes.length;} end index of 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the slice (exclusive) 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ByteArray(byte[] bytes, int start, int end) { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes == null) { 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("bytes == null"); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start < 0) { 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("start < 0"); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (end < start) { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("end < start"); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (end > bytes.length) { 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("end > bytes.length"); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.bytes = bytes; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.start = start; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.size = end - start; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Constructs an instance from an entire {@code byte[]}. 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} the underlying array 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ByteArray(byte[] bytes) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(bytes, 0, bytes.length); 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the size of the array, in bytes. 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the size 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int size() { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return size; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a slice (that is, a sub-array) of this instance. 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param start {@code >= 0;} start index of the slice (inclusive) 9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param end {@code >= start, <= size();} end index of 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the slice (exclusive) 9499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the slice 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ByteArray slice(int start, int end) { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(start, end); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new ByteArray(bytes, start + this.start, end + this.start); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the offset into the given array represented by the given 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * offset into this instance. 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param offset offset into this instance 10699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} (alleged) underlying array 10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return corresponding offset into {@code bytes} 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @throws IllegalArgumentException thrown if {@code bytes} is 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not the underlying array of this instance 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int underlyingOffset(int offset, byte[] bytes) { 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes != this.bytes) { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("wrong bytes"); 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return start + offset; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code signed byte} value at a particular offset. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < size();} offset to fetch 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code signed byte} at that offset 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getByte(int off) { 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 1); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getByte0(off); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code signed short} value at a particular offset. 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < (size() - 1);} offset to fetch 13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code signed short} at that offset 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getShort(int off) { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 2); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (getByte0(off) << 8) | getUnsignedByte0(off + 1); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 14299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code signed int} value at a particular offset. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < (size() - 3);} offset to fetch 14599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code signed int} at that offset 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getInt(int off) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 4); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (getByte0(off) << 24) | 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 1) << 16) | 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 2) << 8) | 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getUnsignedByte0(off + 3); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code signed long} value at a particular offset. 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 15899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < (size() - 7);} offset to fetch 15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code signed int} at that offset 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long getLong(int off) { 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 8); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int part1 = (getByte0(off) << 24) | 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 1) << 16) | 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 2) << 8) | 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getUnsignedByte0(off + 3); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int part2 = (getByte0(off + 4) << 24) | 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 5) << 16) | 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (getUnsignedByte0(off + 6) << 8) | 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getUnsignedByte0(off + 7); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (part2 & 0xffffffffL) | ((long) part1) << 32; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 17699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code unsigned byte} value at a particular offset. 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 17899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < size();} offset to fetch 17999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code unsigned byte} at that offset 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getUnsignedByte(int off) { 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 1); 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getUnsignedByte0(off); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code unsigned short} value at a particular offset. 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param off {@code >= 0, < (size() - 1);} offset to fetch 19099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code unsigned short} at that offset 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getUnsignedShort(int off) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkOffsets(off, off + 2); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copies the contents of this instance into the given raw 19999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code byte[]} at the given offset. The given array must be 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * large enough. 201de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} array to hold the output 20399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param offset {@code non-null;} index into {@code out} for the first 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte of output 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void getBytes(byte[] out, int offset) { 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((out.length - offset) < size) { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IndexOutOfBoundsException("(out.length - offset) < " + 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "size()"); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(bytes, start, out, offset, size); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Checks a range of offsets for validity, throwing if invalid. 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param s start offset (inclusive) 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param e end offset (exclusive) 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void checkOffsets(int s, int e) { 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((s < 0) || (e < s) || (e > size)) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bad range: " + s + ".." + e + 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "; actual size " + size); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 22999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code signed byte} value at the given offset, 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * without doing any argument checking. 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param off offset to fetch 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return byte at that offset 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getByte0(int off) { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes[start + off]; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 24099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code unsigned byte} value at the given offset, 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * without doing any argument checking. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param off offset to fetch 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return byte at that offset 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getUnsignedByte0(int off) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes[start + off] & 0xff; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 25199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets a {@code DataInputStream} that reads from this instance, 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the cursor starting at the beginning of this instance's data. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>Note:</b> The returned instance may be cast to {@link #GetCursor} 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if needed. 255de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 25699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed 25799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code DataInputStream} instance 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MyDataInputStream makeDataInputStream() { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new MyDataInputStream(makeInputStream()); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 26499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets a {@code InputStream} that reads from this instance, 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the cursor starting at the beginning of this instance's data. 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>Note:</b> The returned instance may be cast to {@link #GetCursor} 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if needed. 268de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 26999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed 27099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code InputStream} instancex 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MyInputStream makeInputStream() { 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new MyInputStream(); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper interface that allows one to get the cursor (of a stream). 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public interface GetCursor { 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the current cursor. 282de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 28399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 0..size();} the cursor 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getCursor(); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper class for {@link #makeInputStream}, which implements the 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stream functionality. 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public class MyInputStream extends InputStream { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 0..size; the cursor */ 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int cursor; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 0..size; the mark */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int mark; 298de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MyInputStream() { 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cursor = 0; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mark = 0; 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read() throws IOException { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cursor >= size) { 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = getUnsignedByte0(cursor); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cursor++; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(byte[] arr, int offset, int length) { 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((offset + length) > arr.length) { 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = arr.length - offset; 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 318de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxLength = size - cursor; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length > maxLength) { 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = maxLength; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324508a92917e983723cd94915592d837a114b69110Jesse Wilson System.arraycopy(bytes, cursor + start, arr, offset, length); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cursor += length; 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return length; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int available() { 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return size - cursor; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void mark(int reserve) { 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mark = cursor; 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void reset() { 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cursor = mark; 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean markSupported() { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper class for {@link #makeDataInputStream}. This is used 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * simply so that the cursor of a wrapped {@link #MyInputStream} 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance may be easily determined. 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3514b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein public static class MyDataInputStream extends DataInputStream { 35299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the underlying {@link #MyInputStream} */ 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final MyInputStream wrapped; 354de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MyDataInputStream(MyInputStream wrapped) { 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(wrapped); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.wrapped = wrapped; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 362