ByteString.java revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
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;
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/**
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Immutable array of bytes.
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author crazybob@google.com Bob Lee
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author kenton@google.com Kenton Varda
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepublic final class ByteString {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final byte[] bytes;
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private ByteString(final byte[] bytes) {
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.bytes = bytes;
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Gets the byte at the given index.
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public byte byteAt(final int index) {
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return bytes[index];
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Gets the number of bytes.
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int size() {
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return bytes.length;
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean isEmpty() {
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return bytes.length == 0;
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // byte[] -> ByteString
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Empty ByteString.
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static final ByteString EMPTY = new ByteString(new byte[0]);
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Copies the given bytes into a {@code ByteString}.
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static ByteString copyFrom(final byte[] bytes, final int offset,
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                    final int size) {
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte[] copy = new byte[size];
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    System.arraycopy(bytes, offset, copy, 0, size);
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new ByteString(copy);
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Copies the given bytes into a {@code ByteString}.
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static ByteString copyFrom(final byte[] bytes) {
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return copyFrom(bytes, 0, bytes.length);
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Encodes {@code text} into a sequence of bytes using the named charset
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * and returns the result as a {@code ByteString}.
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static ByteString copyFrom(final String text, final String charsetName)
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws UnsupportedEncodingException {
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new ByteString(text.getBytes(charsetName));
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Encodes {@code text} into a sequence of UTF-8 bytes and returns the
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * result as a {@code ByteString}.
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static ByteString copyFromUtf8(final String text) {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    try {
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new ByteString(text.getBytes("UTF-8"));
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } catch (UnsupportedEncodingException e) {
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new RuntimeException("UTF-8 not supported?", e);
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // ByteString -> byte[]
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Copies bytes into a buffer at the given offset.
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param target buffer to copy into
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param offset in the target buffer
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void copyTo(final byte[] target, final int offset) {
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    System.arraycopy(bytes, 0, target, offset, bytes.length);
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Copies bytes into a buffer.
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param target buffer to copy into
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param sourceOffset offset within these bytes
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param targetOffset offset within the target buffer
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param size number of bytes to copy
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void copyTo(final byte[] target, final int sourceOffset,
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     final int targetOffset,
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int size) {
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    System.arraycopy(bytes, sourceOffset, target, targetOffset, size);
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Copies bytes to a {@code byte[]}.
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public byte[] toByteArray() {
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int size = bytes.length;
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte[] copy = new byte[size];
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    System.arraycopy(bytes, 0, copy, 0, size);
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return copy;
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Constructs a new read-only {@code java.nio.ByteBuffer} with the
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * same backing byte array.
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public ByteBuffer asReadOnlyByteBuffer() {
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return byteBuffer.asReadOnlyBuffer();
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Constructs a new {@code String} by decoding the bytes using the
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * specified charset.
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public String toString(final String charsetName)
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws UnsupportedEncodingException {
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new String(bytes, charsetName);
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Constructs a new {@code String} by decoding the bytes as UTF-8.
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public String toStringUtf8() {
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    try {
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new String(bytes, "UTF-8");
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } catch (UnsupportedEncodingException e) {
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new RuntimeException("UTF-8 not supported?", e);
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // equals() and hashCode()
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  @Override
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean equals(final Object o) {
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (o == this) {
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return true;
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!(o instanceof ByteString)) {
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final ByteString other = (ByteString) o;
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int size = bytes.length;
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size != other.bytes.length) {
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte[] thisBytes = bytes;
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte[] otherBytes = other.bytes;
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < size; i++) {
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (thisBytes[i] != otherBytes[i]) {
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private volatile int hash = 0;
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  @Override
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int hashCode() {
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int h = hash;
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (h == 0) {
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte[] thisBytes = bytes;
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int size = bytes.length;
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      h = size;
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      for (int i = 0; i < size; i++) {
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        h = h * 31 + thisBytes[i];
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (h == 0) {
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        h = 1;
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      hash = h;
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return h;
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Input stream
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Creates an {@code InputStream} which can be used to read the bytes.
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public InputStream newInput() {
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new ByteArrayInputStream(bytes);
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Creates a {@link CodedInputStream} which can be used to read the bytes.
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Using this is more efficient than creating a {@link CodedInputStream}
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * wrapping the result of {@link #newInput()}.
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public CodedInputStream newCodedInput() {
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We trust CodedInputStream not to modify the bytes, or to give anyone
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // else access to them.
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return CodedInputStream.newInstance(bytes);
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Output stream
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Creates a new {@link Output} with the given initial capacity.
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static Output newOutput(final int initialCapacity) {
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new Output(new ByteArrayOutputStream(initialCapacity));
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Creates a new {@link Output}.
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static Output newOutput() {
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newOutput(32);
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * create the {@code ByteString} instance.
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static final class Output extends FilterOutputStream {
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private final ByteArrayOutputStream bout;
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    /**
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     * Constructs a new output with the given initial capacity.
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     */
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private Output(final ByteArrayOutputStream bout) {
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      super(bout);
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.bout = bout;
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    /**
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     * Creates a {@code ByteString} instance from this {@code Output}.
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     */
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public ByteString toByteString() {
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte[] byteArray = bout.toByteArray();
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new ByteString(byteArray);
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Constructs a new ByteString builder, which allows you to efficiently
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * construct a {@code ByteString} by writing to a {@link CodedOutputStream}.
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Using this is much more efficient than calling {@code newOutput()} and
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * wrapping that in a {@code CodedOutputStream}.
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * <p>This is package-private because it's a somewhat confusing interface.
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Users can call {@link Message#toByteString()} instead of calling this
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * directly.
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param size The target byte size of the {@code ByteString}.  You must
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *             write exactly this many bytes before building the result.
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  static CodedBuilder newCodedBuilder(final int size) {
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new CodedBuilder(size);
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** See {@link ByteString#newCodedBuilder(int)}. */
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  static final class CodedBuilder {
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private final CodedOutputStream output;
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private final byte[] buffer;
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private CodedBuilder(final int size) {
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      buffer = new byte[size];
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      output = CodedOutputStream.newInstance(buffer);
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public ByteString build() {
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      output.checkNoSpaceLeft();
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We can be confident that the CodedOutputStream will not modify the
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // underlying bytes anymore because it already wrote all of them.  So,
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // no need to make a copy.
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new ByteString(buffer);
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public CodedOutputStream getCodedOutput() {
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return output;
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
345