ByteString.java revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
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