// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.protobuf; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FilterOutputStream; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.List; /** * Immutable array of bytes. * * @author crazybob@google.com Bob Lee * @author kenton@google.com Kenton Varda */ public final class ByteString { private final byte[] bytes; private ByteString(final byte[] bytes) { this.bytes = bytes; } /** * Gets the byte at the given index. * * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size */ public byte byteAt(final int index) { return bytes[index]; } /** * Gets the number of bytes. */ public int size() { return bytes.length; } /** * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. */ public boolean isEmpty() { return bytes.length == 0; } // ================================================================= // byte[] -> ByteString /** * Empty ByteString. */ public static final ByteString EMPTY = new ByteString(new byte[0]); /** * Copies the given bytes into a {@code ByteString}. */ public static ByteString copyFrom(final byte[] bytes, final int offset, final int size) { final byte[] copy = new byte[size]; System.arraycopy(bytes, offset, copy, 0, size); return new ByteString(copy); } /** * Copies the given bytes into a {@code ByteString}. */ public static ByteString copyFrom(final byte[] bytes) { return copyFrom(bytes, 0, bytes.length); } /** * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into * a {@code ByteString}. */ public static ByteString copyFrom(final ByteBuffer bytes, final int size) { final byte[] copy = new byte[size]; bytes.get(copy); return new ByteString(copy); } /** * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into * a {@code ByteString}. */ public static ByteString copyFrom(final ByteBuffer bytes) { return copyFrom(bytes, bytes.remaining()); } /** * Encodes {@code text} into a sequence of bytes using the named charset * and returns the result as a {@code ByteString}. */ public static ByteString copyFrom(final String text, final String charsetName) throws UnsupportedEncodingException { return new ByteString(text.getBytes(charsetName)); } /** * Encodes {@code text} into a sequence of UTF-8 bytes and returns the * result as a {@code ByteString}. */ public static ByteString copyFromUtf8(final String text) { try { return new ByteString(text.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8 not supported?", e); } } /** * Concatenates all byte strings in the list and returns the result. * *
The returned {@code ByteString} is not necessarily a unique object.
* If the list is empty, the returned object is the singleton empty
* {@code ByteString}. If the list has only one element, that
* {@code ByteString} will be returned without copying.
*/
public static ByteString copyFrom(List This is package-private because it's a somewhat confusing interface.
* Users can call {@link Message#toByteString()} instead of calling this
* directly.
*
* @param size The target byte size of the {@code ByteString}. You must
* write exactly this many bytes before building the result.
*/
static CodedBuilder newCodedBuilder(final int size) {
return new CodedBuilder(size);
}
/** See {@link ByteString#newCodedBuilder(int)}. */
static final class CodedBuilder {
private final CodedOutputStream output;
private final byte[] buffer;
private CodedBuilder(final int size) {
buffer = new byte[size];
output = CodedOutputStream.newInstance(buffer);
}
public ByteString build() {
output.checkNoSpaceLeft();
// We can be confident that the CodedOutputStream will not modify the
// underlying bytes anymore because it already wrote all of them. So,
// no need to make a copy.
return new ByteString(buffer);
}
public CodedOutputStream getCodedOutput() {
return output;
}
}
}