1e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Protocol Buffers - Google's data interchange format 2e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Copyright 2008 Google Inc. All rights reserved. 3e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// http://code.google.com/p/protobuf/ 4e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// 5e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// Redistribution and use in source and binary forms, with or without 6e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// modification, are permitted provided that the following conditions are 7e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// met: 8e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// 9e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// * Redistributions of source code must retain the above copyright 10e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// notice, this list of conditions and the following disclaimer. 11e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// * Redistributions in binary form must reproduce the above 12e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// copyright notice, this list of conditions and the following disclaimer 13e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// in the documentation and/or other materials provided with the 14e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// distribution. 15e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// * Neither the name of Google Inc. nor the names of its 16e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// contributors may be used to endorse or promote products derived from 17e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// this software without specific prior written permission. 18e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// 19e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 31e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillepackage com.google.protobuf.micro; 32e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 33e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savilleimport java.io.UnsupportedEncodingException; 34e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 35e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville/** 36e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Immutable array of bytes. 37e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * 38e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @author crazybob@google.com Bob Lee 39e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @author kenton@google.com Kenton Varda 40e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 41e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Savillepublic final class ByteStringMicro { 42e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville private final byte[] bytes; 43e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 44e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville private ByteStringMicro(final byte[] bytes) { 45e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville this.bytes = bytes; 46e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 47e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 48e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 49e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Gets the byte at the given index. 50e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * 51e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size 52e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 53e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public byte byteAt(final int index) { 54e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return bytes[index]; 55e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 56e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 57e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 58e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Gets the number of bytes. 59e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 60e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public int size() { 61e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return bytes.length; 62e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 63e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 64e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 65e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. 66e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 67e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public boolean isEmpty() { 68e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return bytes.length == 0; 69e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 70e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 71e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // ================================================================= 72e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // byte[] -> ByteStringMicro 73e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 74e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 75e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Empty ByteStringMicro. 76e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 77e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public static final ByteStringMicro EMPTY = new ByteStringMicro(new byte[0]); 78e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 79e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 80e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Copies the given bytes into a {@code ByteStringMicro}. 81e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 82e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public static ByteStringMicro copyFrom(final byte[] bytes, final int offset, 83e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int size) { 84e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final byte[] copy = new byte[size]; 85e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville System.arraycopy(bytes, offset, copy, 0, size); 86e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return new ByteStringMicro(copy); 87e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 88e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 89e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 90e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Copies the given bytes into a {@code ByteStringMicro}. 91e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 92e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public static ByteStringMicro copyFrom(final byte[] bytes) { 93e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return copyFrom(bytes, 0, bytes.length); 94e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 95e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 96e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 97e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Encodes {@code text} into a sequence of bytes using the named charset 98e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * and returns the result as a {@code ByteStringMicro}. 99e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 100e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public static ByteStringMicro copyFrom(final String text, final String charsetName) 101e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville throws UnsupportedEncodingException { 102e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return new ByteStringMicro(text.getBytes(charsetName)); 103e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 104e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 105e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 106e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Encodes {@code text} into a sequence of UTF-8 bytes and returns the 107e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * result as a {@code ByteStringMicro}. 108e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 109e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public static ByteStringMicro copyFromUtf8(final String text) { 110e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville try { 111e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return new ByteStringMicro(text.getBytes("UTF-8")); 112e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } catch (UnsupportedEncodingException e) { 113e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville throw new RuntimeException("UTF-8 not supported?"); 114e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 115e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 116e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 117e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // ================================================================= 118e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // ByteStringMicro -> byte[] 119e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 120e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 121e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Copies bytes into a buffer at the given offset. 122e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * 123e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param target buffer to copy into 124e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param offset in the target buffer 125e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 126e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public void copyTo(final byte[] target, final int offset) { 127e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville System.arraycopy(bytes, 0, target, offset, bytes.length); 128e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 129e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 130e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 131e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Copies bytes into a buffer. 132e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * 133e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param target buffer to copy into 134e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param sourceOffset offset within these bytes 135e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param targetOffset offset within the target buffer 136e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * @param size number of bytes to copy 137e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 138e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public void copyTo(final byte[] target, final int sourceOffset, 139e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int targetOffset, 140e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int size) { 141e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville System.arraycopy(bytes, sourceOffset, target, targetOffset, size); 142e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 143e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 144e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 145e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Copies bytes to a {@code byte[]}. 146e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 147e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public byte[] toByteArray() { 148e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int size = bytes.length; 149e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final byte[] copy = new byte[size]; 150e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville System.arraycopy(bytes, 0, copy, 0, size); 151e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return copy; 152e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 153e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 154e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 155e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Constructs a new {@code String} by decoding the bytes using the 156e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * specified charset. 157e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 158e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public String toString(final String charsetName) 159e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville throws UnsupportedEncodingException { 160e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return new String(bytes, charsetName); 161e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 162e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 163e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville /** 164e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville * Constructs a new {@code String} by decoding the bytes as UTF-8. 165e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville */ 166e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public String toStringUtf8() { 167e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville try { 168e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return new String(bytes, "UTF-8"); 169e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } catch (UnsupportedEncodingException e) { 170e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville throw new RuntimeException("UTF-8 not supported?"); 171e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 172e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 173e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 174e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // ================================================================= 175e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville // equals() and hashCode() 176e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 177e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville //@Override for compatibility with Java 1.3 code we can't use annotations 178e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public boolean equals(final Object o) { 179e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (o == this) { 180e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return true; 181e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 182e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 183e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (!(o instanceof ByteStringMicro)) { 184e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return false; 185e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 186e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 187e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final ByteStringMicro other = (ByteStringMicro) o; 188e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int size = bytes.length; 189e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (size != other.bytes.length) { 190e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return false; 191e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 192e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 193e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final byte[] thisBytes = bytes; 194e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final byte[] otherBytes = other.bytes; 195e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville for (int i = 0; i < size; i++) { 196e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (thisBytes[i] != otherBytes[i]) { 197e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return false; 198e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 199e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 200e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 201e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return true; 202e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 203e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 204e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville private volatile int hash = 0; 205e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 206e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville //@Override for compatibility with Java 1.3 code we can't use annotations 207e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville public int hashCode() { 208e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville int h = hash; 209e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 210e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (h == 0) { 211e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final byte[] thisBytes = bytes; 212e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville final int size = bytes.length; 213e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 214e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville h = size; 215e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville for (int i = 0; i < size; i++) { 216e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville h = h * 31 + thisBytes[i]; 217e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 218e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville if (h == 0) { 219e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville h = 1; 220e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 221e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 222e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville hash = h; 223e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 224e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville 225e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville return h; 226e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville } 227e2d542951c059563a3b7f74c257dac4f222d9dc5Wink Saville} 228