1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepackage com.google.protobuf; 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.InputStream; 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.ByteArrayInputStream; 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.ByteArrayOutputStream; 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.FilterOutputStream; 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.UnsupportedEncodingException; 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.nio.ByteBuffer; 39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleimport java.util.List; 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/** 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Immutable array of bytes. 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author crazybob@google.com Bob Lee 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author kenton@google.com Kenton Varda 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepublic final class ByteString { 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private final byte[] bytes; 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private ByteString(final byte[] bytes) { 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville this.bytes = bytes; 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Gets the byte at the given index. 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public byte byteAt(final int index) { 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return bytes[index]; 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Gets the number of bytes. 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public int size() { 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return bytes.length; 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public boolean isEmpty() { 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return bytes.length == 0; 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ================================================================= 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // byte[] -> ByteString 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Empty ByteString. 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static final ByteString EMPTY = new ByteString(new byte[0]); 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Copies the given bytes into a {@code ByteString}. 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static ByteString copyFrom(final byte[] bytes, final int offset, 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int size) { 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] copy = new byte[size]; 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville System.arraycopy(bytes, offset, copy, 0, size); 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteString(copy); 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Copies the given bytes into a {@code ByteString}. 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static ByteString copyFrom(final byte[] bytes) { 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return copyFrom(bytes, 0, bytes.length); 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into 104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * a {@code ByteString}. 105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville */ 106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville public static ByteString copyFrom(final ByteBuffer bytes, final int size) { 107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville final byte[] copy = new byte[size]; 108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bytes.get(copy); 109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new ByteString(copy); 110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville /** 113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into 114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * a {@code ByteString}. 115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville */ 116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville public static ByteString copyFrom(final ByteBuffer bytes) { 117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return copyFrom(bytes, bytes.remaining()); 118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville /** 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Encodes {@code text} into a sequence of bytes using the named charset 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * and returns the result as a {@code ByteString}. 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static ByteString copyFrom(final String text, final String charsetName) 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville throws UnsupportedEncodingException { 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteString(text.getBytes(charsetName)); 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Encodes {@code text} into a sequence of UTF-8 bytes and returns the 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * result as a {@code ByteString}. 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static ByteString copyFromUtf8(final String text) { 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try { 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteString(text.getBytes("UTF-8")); 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } catch (UnsupportedEncodingException e) { 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville throw new RuntimeException("UTF-8 not supported?", e); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville /** 142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * Concatenates all byte strings in the list and returns the result. 143d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * 144d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * <p>The returned {@code ByteString} is not necessarily a unique object. 145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * If the list is empty, the returned object is the singleton empty 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * {@code ByteString}. If the list has only one element, that 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville * {@code ByteString} will be returned without copying. 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville */ 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville public static ByteString copyFrom(List<ByteString> list) { 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (list.size() == 0) { 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EMPTY; 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else if (list.size() == 1) { 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return list.get(0); 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 156d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int size = 0; 157d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (ByteString str : list) { 158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size += str.size(); 159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 160d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville byte[] bytes = new byte[size]; 161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int pos = 0; 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (ByteString str : list) { 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville System.arraycopy(str.bytes, 0, bytes, pos, str.size()); 164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += str.size(); 165d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 166d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new ByteString(bytes); 167d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 168d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ================================================================= 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ByteString -> byte[] 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Copies bytes into a buffer at the given offset. 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param target buffer to copy into 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param offset in the target buffer 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public void copyTo(final byte[] target, final int offset) { 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville System.arraycopy(bytes, 0, target, offset, bytes.length); 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Copies bytes into a buffer. 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param target buffer to copy into 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param sourceOffset offset within these bytes 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param targetOffset offset within the target buffer 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param size number of bytes to copy 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public void copyTo(final byte[] target, final int sourceOffset, 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int targetOffset, 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int size) { 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville System.arraycopy(bytes, sourceOffset, target, targetOffset, size); 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Copies bytes to a {@code byte[]}. 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public byte[] toByteArray() { 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int size = bytes.length; 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] copy = new byte[size]; 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville System.arraycopy(bytes, 0, copy, 0, size); 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return copy; 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Constructs a new read-only {@code java.nio.ByteBuffer} with the 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * same backing byte array. 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public ByteBuffer asReadOnlyByteBuffer() { 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return byteBuffer.asReadOnlyBuffer(); 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Constructs a new {@code String} by decoding the bytes using the 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * specified charset. 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public String toString(final String charsetName) 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville throws UnsupportedEncodingException { 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new String(bytes, charsetName); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Constructs a new {@code String} by decoding the bytes as UTF-8. 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public String toStringUtf8() { 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try { 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new String(bytes, "UTF-8"); 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } catch (UnsupportedEncodingException e) { 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville throw new RuntimeException("UTF-8 not supported?", e); 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ================================================================= 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // equals() and hashCode() 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville @Override 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public boolean equals(final Object o) { 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (o == this) { 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!(o instanceof ByteString)) { 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final ByteString other = (ByteString) o; 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int size = bytes.length; 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (size != other.bytes.length) { 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] thisBytes = bytes; 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] otherBytes = other.bytes; 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (thisBytes[i] != otherBytes[i]) { 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private volatile int hash = 0; 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville @Override 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public int hashCode() { 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int h = hash; 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (h == 0) { 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] thisBytes = bytes; 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final int size = bytes.length; 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville h = size; 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville h = h * 31 + thisBytes[i]; 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (h == 0) { 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville h = 1; 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash = h; 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return h; 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ================================================================= 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Input stream 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Creates an {@code InputStream} which can be used to read the bytes. 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public InputStream newInput() { 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteArrayInputStream(bytes); 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Creates a {@link CodedInputStream} which can be used to read the bytes. 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Using this is more efficient than creating a {@link CodedInputStream} 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * wrapping the result of {@link #newInput()}. 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public CodedInputStream newCodedInput() { 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We trust CodedInputStream not to modify the bytes, or to give anyone 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // else access to them. 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return CodedInputStream.newInstance(bytes); 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ================================================================= 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Output stream 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Creates a new {@link Output} with the given initial capacity. 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static Output newOutput(final int initialCapacity) { 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new Output(new ByteArrayOutputStream(initialCapacity)); 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Creates a new {@link Output}. 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static Output newOutput() { 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return newOutput(32); 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * create the {@code ByteString} instance. 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public static final class Output extends FilterOutputStream { 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private final ByteArrayOutputStream bout; 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Constructs a new output with the given initial capacity. 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private Output(final ByteArrayOutputStream bout) { 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville super(bout); 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville this.bout = bout; 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Creates a {@code ByteString} instance from this {@code Output}. 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public ByteString toByteString() { 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville final byte[] byteArray = bout.toByteArray(); 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteString(byteArray); 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Constructs a new ByteString builder, which allows you to efficiently 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * construct a {@code ByteString} by writing to a {@link CodedOutputStream}. 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Using this is much more efficient than calling {@code newOutput()} and 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * wrapping that in a {@code CodedOutputStream}. 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * <p>This is package-private because it's a somewhat confusing interface. 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Users can call {@link Message#toByteString()} instead of calling this 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * directly. 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @param size The target byte size of the {@code ByteString}. You must 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * write exactly this many bytes before building the result. 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */ 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static CodedBuilder newCodedBuilder(final int size) { 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new CodedBuilder(size); 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /** See {@link ByteString#newCodedBuilder(int)}. */ 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static final class CodedBuilder { 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private final CodedOutputStream output; 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private final byte[] buffer; 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private CodedBuilder(final int size) { 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer = new byte[size]; 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output = CodedOutputStream.newInstance(buffer); 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public ByteString build() { 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output.checkNoSpaceLeft(); 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We can be confident that the CodedOutputStream will not modify the 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // underlying bytes anymore because it already wrote all of them. So, 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // no need to make a copy. 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new ByteString(buffer); 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public CodedOutputStream getCodedOutput() { 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return output; 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 392