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