diff options
Diffstat (limited to 'src/com/google/common/io')
-rw-r--r-- | src/com/google/common/io/protocol/BoundInputStream.java | 91 | ||||
-rw-r--r-- | src/com/google/common/io/protocol/ProtoBuf.java | 1339 | ||||
-rw-r--r-- | src/com/google/common/io/protocol/ProtoBufType.java | 170 | ||||
-rw-r--r-- | src/com/google/common/io/protocol/ProtoBufUtil.java | 285 | ||||
-rw-r--r-- | src/com/google/common/io/protocol/package.html | 5 |
5 files changed, 0 insertions, 1890 deletions
diff --git a/src/com/google/common/io/protocol/BoundInputStream.java b/src/com/google/common/io/protocol/BoundInputStream.java deleted file mode 100644 index dbccca75..00000000 --- a/src/com/google/common/io/protocol/BoundInputStream.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. - -package com.google.common.io.protocol; - -import java.io.*; - -/** - * An input stream backed by another input stream, where reading from the - * underlying input stream is limited to a fixed number of bytes. Also does - * some buffering. - * - */ -public class BoundInputStream extends InputStream { - - /** Buffer size */ - static final int BUF_SIZE = 4096; - - /** Number of bytes that may still be read from the underlying stream */ - private int remaining; - - /** Small buffer to avoid making OS calls for each byte read. */ - private byte[] buf; - - /** Current position in the buffer */ - private int bufPos; - - /** Filled size of the buffer */ - private int bufSize; - - /** Underlying stream to read from */ - private InputStream base; - - public BoundInputStream(InputStream base, int len) { - this.base = base; - this.remaining = len; - - buf = new byte[Math.min(len, BUF_SIZE)]; - } - - /** - * Make sure there is at least one byte in the buffer. If not possible, - * return false. - */ - private boolean checkBuf() throws IOException { - if (remaining <= 0) { - return false; - } - - if (bufPos >= bufSize) { - bufSize = base.read(buf, 0, Math.min(remaining, buf.length)); - if (bufSize <= 0) { - remaining = 0; - return false; - } - bufPos = 0; - } - return true; - } - - public int available() { - return bufSize - bufPos; - } - - public int read() throws IOException { - if (!checkBuf()) { - return -1; - } - remaining--; - return buf[bufPos++] & 255; - } - - public int read(byte[] data, int start, int count) throws IOException { - if (!checkBuf()) { - return -1; - } - count = Math.min(count, bufSize - bufPos); - System.arraycopy(buf, bufPos, data, start, count); - bufPos += count; - remaining -= count; - return count; - } - - /** - * How many bytes are remaining, based on the length provided to the - * constructor. The underlying stream may terminate earlier. Provided mainly - * for testing purposes. - */ - public int getRemaining() { - return remaining; - } -} diff --git a/src/com/google/common/io/protocol/ProtoBuf.java b/src/com/google/common/io/protocol/ProtoBuf.java deleted file mode 100644 index 2a2f8b77..00000000 --- a/src/com/google/common/io/protocol/ProtoBuf.java +++ /dev/null @@ -1,1339 +0,0 @@ -// Copyright 2007 The Android Open Source Project -// All Rights Reserved. - -package com.google.common.io.protocol; - -import java.io.*; -import java.util.*; - -/** - * Protocol buffer message object. Currently, it is assumed that tags ids are - * not large. This could be improved by storing a start offset, reducing the - * assumption to a dense number space. - * <p> - * ProtoBuf instances may or may not reference a ProtoBufType instance, - * representing information from a corresponding .proto file, which defines tag - * data types. The type can only be set in the constructor, it cannot be - * changed later. - * <p> - * If the type is null, the ProtoBuffer should be used only for reading or - * as a local persistent storage buffer. An untyped Protocol Buffer must never - * be sent to a server. - * <p> - * If a ProtoBufType is set, unknown values are read from the stream and - * preserved, but it is not possible to add values for undefined tags using - * this API. Attempts to set undefined tags will result in an exception. - * <p> - * This class provides two different sets of access methods for simple and - * repeated tags. Simple access methods are has(tag), getXXX(tag), - * and setXXX(tag, value). Access methods for repeated tags are getCount(tag), - * getXXX(tag, index), remove(tag, index), insert(tag, index, value) and - * addXXX(tag, value). Note that both sets of methods can be used in both cases, - * but only the simple methods take default values into account. The reason for - * this behavior is that default values cannot be removed -- they would reappear - * after a serialization cycle. If a tag has repeated values, setXXX(tag, value) - * will overwrite all of them and getXXX(tag) will throw an exception. - * - */ - -public class ProtoBuf { - - public static final Boolean FALSE = new Boolean(false); - public static final Boolean TRUE = new Boolean(true); - - private static final String MSG_EOF = "Unexp.EOF"; - private static final String MSG_MISMATCH = "Type mismatch"; - private static final String MSG_UNSUPPORTED = "Unsupp.Type"; - - // names copied from //net/proto2/internal/wire_format.cc - static final int WIRETYPE_END_GROUP = 4; - static final int WIRETYPE_FIXED32 = 5; - static final int WIRETYPE_FIXED64 = 1; - static final int WIRETYPE_LENGTH_DELIMITED = 2; - static final int WIRETYPE_START_GROUP = 3; - static final int WIRETYPE_VARINT = 0; - - /** Maximum number of bytes for VARINT wire format (64 bit, 7 bit/byte) */ - private static final int VARINT_MAX_BYTES = 10; - - private static Long[] SMALL_NUMBERS = { - new Long(0), new Long(1), new Long(2), new Long(3), new Long(4), - new Long(5), new Long(6), new Long(7), new Long(8), new Long(9), - new Long(10), new Long(11), new Long(12), new Long(13), new Long(14), - new Long(15)}; - - private ProtoBufType msgType; - private final Vector values = new Vector(); - - /** - * Wire types picked up on the wire or implied by setters (if no other - * type information is available. - */ - private final StringBuffer wireTypes = new StringBuffer(); - - /** - * Creates a protocol message according to the given description. The - * description is required if it is necessary to write the protocol buffer for - * data exchange with other systems relying on the .proto file. - */ - public ProtoBuf(ProtoBufType type) { - this.msgType = type; - } - - /** - * Clears all data stored in this ProtoBuf. - */ - public void clear() { - values.setSize(0); - wireTypes.setLength(0); - } - - /** - * Creates a new instance of the group with the given tag. - */ - public ProtoBuf createGroup(int tag) { - return new ProtoBuf((ProtoBufType) getType().getData(tag)); - } - - /** - * Appends the given (repeated) tag with the given boolean value. - */ - public void addBool(int tag, boolean value){ - insertBool(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given byte[] value. - */ - public void addBytes(int tag, byte[] value){ - insertBytes(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given int value. - */ - public void addInt(int tag, int value){ - insertInt(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given long value. - */ - public void addLong(int tag, long value){ - insertLong(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given float value. - */ - public void addFloat(int tag, float value) { - insertFloat(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given double value. - */ - public void addDouble(int tag, double value) { - insertDouble(tag, getCount(tag), value); - } - - /** - * Appends the given (repeated) tag with the given group or message value. - */ - public void addProtoBuf(int tag, ProtoBuf value){ - insertProtoBuf(tag, getCount(tag), value); - } - - /** - * Adds a new protobuf for the specified tag, setting the child protobuf's - * type correctly for the tag. - * @param tag the tag for which to create a new protobuf - * @return the newly created protobuf - */ - public ProtoBuf addNewProtoBuf(int tag) { - ProtoBuf child = newProtoBufForTag(tag); - addProtoBuf(tag, child); - return child; - } - - /** - * Creates and returns a new protobuf for the specified tag, setting the new - * protobuf's type correctly for the tag. - * @param tag the tag for which to create a new protobuf - * @return the newly created protobuf - */ - public ProtoBuf newProtoBufForTag(int tag) { - return new ProtoBuf((ProtoBufType) msgType.getData(tag)); - } - - /** - * Appends the given (repeated) tag with the given String value. - */ - public void addString(int tag, String value){ - insertString(tag, getCount(tag), value); - } - - /** - * Returns the boolean value for the given tag. - */ - public boolean getBool(int tag) { - return ((Boolean) getObject(tag, ProtoBufType.TYPE_BOOL)) - .booleanValue(); - } - - /** - * Returns the boolean value for the given repeated tag at the given index. - */ - public boolean getBool(int tag, int index) { - return ((Boolean) getObject(tag, index, ProtoBufType.TYPE_BOOL)) - .booleanValue(); - } - - /** - * Returns the given string tag as byte array. - */ - public byte[] getBytes(int tag) { - return (byte[]) getObject(tag, ProtoBufType.TYPE_DATA); - } - - /** - * Returns the given repeated string tag at the given index as byte array. - */ - public byte[] getBytes(int tag, int index) { - return (byte[]) getObject(tag, index, ProtoBufType.TYPE_DATA); - } - - /** - * Returns the integer value for the given tag. - */ - public int getInt(int tag) { - return (int) ((Long) getObject(tag, ProtoBufType.TYPE_INT32)).longValue(); - } - - /** - * Returns the integer value for the given repeated tag at the given index. - */ - public int getInt(int tag, int index) { - return (int) ((Long) getObject(tag, index, - ProtoBufType.TYPE_INT32)).longValue(); - } - - /** - * Returns the long value for the given tag. - */ - public long getLong(int tag) { - return ((Long) getObject(tag, ProtoBufType.TYPE_INT64)).longValue(); - } - - /** - * Returns the long value for the given repeated tag at the given index. - */ - public long getLong(int tag, int index) { - return ((Long) getObject(tag, index, ProtoBufType.TYPE_INT64)).longValue(); - } - - /** - * Returns the float value for the given tag. - */ - public float getFloat(int tag) { - return Float.intBitsToFloat(getInt(tag)); - } - - /** - * Returns the float value for the given repeated tag at the given index. - */ - public float getFloat(int tag, int index) { - return Float.intBitsToFloat(getInt(tag, index)); - } - - /** - * Returns the double value for the given tag. - */ - public double getDouble(int tag) { - return Double.longBitsToDouble(getLong(tag)); - } - - /** - * Returns the double value for the given repeated tag at the given index. - */ - public double getDouble(int tag, int index) { - return Double.longBitsToDouble(getLong(tag, index)); - } - - /** - * Returns the group or nested message for the given tag. - */ - public ProtoBuf getProtoBuf(int tag) { - return (ProtoBuf) getObject(tag, ProtoBufType.TYPE_GROUP); - } - - /** - * Returns the group or nested message for the given repeated tag at the given - * index. - */ - public ProtoBuf getProtoBuf(int tag, int index) { - return (ProtoBuf) getObject(tag, index, ProtoBufType.TYPE_GROUP); - } - - /** - * Returns the string value for a given tag converted to a Java String - * assuming UTF-8 encoding. - */ - public String getString(int tag) { - return (String) getObject(tag, ProtoBufType.TYPE_TEXT); - } - - /** - * Returns the string value for a given repeated tag at the given index - * converted to a Java String assuming UTF-8 encoding. - */ - public String getString(int tag, int index) { - return (String) getObject(tag, index, ProtoBufType.TYPE_TEXT); - } - - /** - * Returns the type definition of this protocol buffer or group -- if set. - */ - public ProtoBufType getType() { - return msgType; - } - - /** - * Sets the type definition of this protocol buffer. Used internally in - * ProtoBufUtil for incremental reading. - * - * @param type the new type - */ - void setType(ProtoBufType type) { - if (values.size() != 0 || - (msgType != null && type != null && type != msgType)) { - throw new IllegalArgumentException(); - } - this.msgType = type; - } - - /** - * Convenience method for determining whether a tag has a value. Note: in - * contrast to getCount(tag) > 0, this method takes the default value - * into account. - */ - public boolean has(int tag){ - return getCount(tag) > 0 || getDefault(tag) != null; - } - - /** - * Reads the contents of this ProtocolMessage from the given byte array. - * Currently, this is a shortcut for parse(new ByteArrayInputStream(data)). - * However, this may change in future versions for efficiency reasons. - * - * @param data the byte array the ProtocolMessage is read from - * @throws IOException if an unexpected "End of file" is encountered in - * the byte array - */ - public ProtoBuf parse(byte[] data) throws IOException { - parse(new ByteArrayInputStream(data), data.length); - return this; - } - - /** - * Reads the contents of this ProtocolMessage from the given stream. - * - * @param is the input stream providing the contents - * @return this - * @throws IOException raised if an IO exception occurs in the underlying - * stream or the end of the stream is reached at an unexpected - * position - */ - - public ProtoBuf parse(InputStream is) throws IOException { - parse(is, Integer.MAX_VALUE); - return this; - } - - /** - * Reads the contents of this ProtocolMessage from the given stream, consuming - * at most the given number of bytes. - * - * @param is the input stream providing the contents - * @param available maximum number of bytes to read - * @return this - * @throws IOException raised if an IO exception occurs in the - * underlying stream or the end of the stream is reached at - * an unexpected position - */ - public int parse(InputStream is, int available) throws IOException { - - clear(); - while (available > 0) { - long tagAndType = readVarInt(is, true /* permits EOF */); - - if (tagAndType == -1){ - break; - } - available -= getVarIntSize(tagAndType); - int wireType = ((int) tagAndType) & 0x07; - if (wireType == WIRETYPE_END_GROUP) { - break; - } - int tag = (int) (tagAndType >>> 3); - while (wireTypes.length() <= tag){ - wireTypes.append((char) ProtoBufType.TYPE_UNDEFINED); - } - wireTypes.setCharAt(tag, (char) wireType); - - // first step: decode tag value - Object value; - switch (wireType) { - case WIRETYPE_VARINT: - long v = readVarInt(is, false); - available -= getVarIntSize(v); - if (isZigZagEncodedType(tag)) { - v = zigZagDecode(v); - } - value = (v >= 0 && v < SMALL_NUMBERS.length) ? - SMALL_NUMBERS[(int) v] : new Long(v); - break; - - // also used for fixed values - case WIRETYPE_FIXED32: - case WIRETYPE_FIXED64: - v = 0; - int shift = 0; - int count = (wireType == WIRETYPE_FIXED32) ? 4 : 8; - available -= count; - - while (count-- > 0) { - long l = is.read(); - v |= l << shift; - shift += 8; - } - - value = (v >= 0 && v < SMALL_NUMBERS.length) - ? SMALL_NUMBERS[(int) v] - : new Long(v); - break; - - case WIRETYPE_LENGTH_DELIMITED: - int total = (int) readVarInt(is, false); - available -= getVarIntSize(total); - available -= total; - - if (getType(tag) == ProtoBufType.TYPE_MESSAGE) { - ProtoBuf msg = new ProtoBuf((ProtoBufType) msgType.getData(tag)); - msg.parse(is, total); - value = msg; - } else { - byte[] data = new byte[total]; - int pos = 0; - while (pos < total) { - count = is.read(data, pos, total - pos); - if (count <= 0) { - throw new IOException(MSG_EOF); - } - pos += count; - } - value = data; - } - break; - - case WIRETYPE_START_GROUP: - ProtoBuf group = new ProtoBuf(msgType == null - ? null - : ((ProtoBufType) msgType.getData(tag))); - available = group.parse(is, available); - value = group; - break; - - default: - throw new RuntimeException(MSG_UNSUPPORTED + wireType); - } - insertObject(tag, getCount(tag), value); - } - - if (available < 0){ - throw new IOException(); - } - - return available; - } - - /** - * Removes the tag value at the given index. - */ - public void remove(int tag, int index){ - int count = getCount(tag); - if (index >= count){ - throw new ArrayIndexOutOfBoundsException(); - } - if (count == 1){ - values.setElementAt(null, tag); - } else { - Vector v = (Vector) values.elementAt(tag); - v.removeElementAt(index); - } - } - - /** - * Returns the number of repeated and optional (0..1) values for a given tag. - * Note: Default values are not counted (and in general not considered in - * access methods for repeated tags), but considered for has(tag). - */ - public int getCount(int tag) { - if (tag >= values.size()){ - return 0; - } - Object o = values.elementAt(tag); - if (o == null){ - return 0; - } - return (o instanceof Vector) ? ((Vector) o).size() : 1; - } - - /** - * Returns the tag type of the given tag (one of the ProtoBufType.TYPE_XXX - * constants). If no ProtoBufType is set, the wire type is returned. If no - * wire type is available, the wire type is determined by looking at the - * tag value (making sure the wire type is consistent for all values). If - * no value is set, TYPE_UNDEFINED is returned. - */ - public int getType(int tag){ - int tagType = ProtoBufType.TYPE_UNDEFINED; - if (msgType != null){ - tagType = msgType.getType(tag); - } - - if (tagType == ProtoBufType.TYPE_UNDEFINED && tag < wireTypes.length()) { - tagType = wireTypes.charAt(tag); - } - - if (tagType == ProtoBufType.TYPE_UNDEFINED && getCount(tag) > 0) { - Object o = getObject(tag, 0, ProtoBufType.TYPE_UNDEFINED); - - tagType = (o instanceof Long) || (o instanceof Boolean) - ? WIRETYPE_VARINT : WIRETYPE_LENGTH_DELIMITED; - } - - return tagType; - } - - /** - * Returns the number of bytes needed to store this protocol buffer - */ - public int getDataSize() { - int size = 0; - for (int tag = 0; tag <= maxTag(); tag++) { - for (int i = 0; i < getCount(tag); i++) { - size += getDataSize(tag, i); - } - } - return size; - } - - - /** - * Returns the size of the given value - */ - private int getDataSize(int tag, int i) { - int tagSize = getVarIntSize(tag << 3); - - switch(getWireType(tag)){ - case WIRETYPE_FIXED32: - return tagSize + 4; - case WIRETYPE_FIXED64: - return tagSize + 8; - case WIRETYPE_VARINT: - long value = getLong(tag, i); - if (isZigZagEncodedType(tag)) { - value = zigZagEncode(value); - } - return tagSize + getVarIntSize(value); - case WIRETYPE_START_GROUP: - // take end group into account.... - return tagSize + getProtoBuf(tag, i).getDataSize() + tagSize; - } - - // take the object as stored - Object o = getObject(tag, i, ProtoBufType.TYPE_UNDEFINED); - - int contentSize; - - if (o instanceof byte[]){ - contentSize = ((byte[]) o).length; - } else if (o instanceof String) { - contentSize = encodeUtf8((String) o, null, 0); - } else { - contentSize = ((ProtoBuf) o).getDataSize(); - } - - return tagSize + getVarIntSize(contentSize) + contentSize; - } - - /** - * Returns the number of bytes needed to encode the given value using - * WIRETYPE_VARINT - */ - private static int getVarIntSize(long i) { - if (i < 0) { - return 10; - } - int size = 1; - while (i >= 128) { - size++; - i >>= 7; - } - return size; - } - - /** - * Writes this and nested protocol buffers to the given output stream. - * - * @param os target output stream - * @throws IOException thrown if there is an IOException - */ - public void outputTo(OutputStream os) throws IOException { - for (int tag = 0; tag <= maxTag(); tag++) { - int size = getCount(tag); - int wireType = getWireType(tag); - - // ignore default values - for (int i = 0; i < size; i++) { - writeVarInt(os, (tag << 3) | wireType); - - switch (wireType) { - case WIRETYPE_FIXED32: - case WIRETYPE_FIXED64: - long v = ((Long) getObject(tag, i, ProtoBufType.TYPE_INT64)) - .longValue(); - int cnt = (wireType == WIRETYPE_FIXED32) ? 4 : 8; - for (int b = 0; b < cnt; b++) { - os.write((int) (v & 0x0ff)); - v >>= 8; - } - break; - - case WIRETYPE_VARINT: - v = ((Long) getObject(tag, i, ProtoBufType.TYPE_INT64)).longValue(); - if (isZigZagEncodedType(tag)) { - v = zigZagEncode(v); - } - writeVarInt(os, v); - break; - - case WIRETYPE_LENGTH_DELIMITED: - Object o = getObject(tag, i, - getType(tag) == ProtoBufType.TYPE_MESSAGE - ? ProtoBufType.TYPE_UNDEFINED - : ProtoBufType.TYPE_DATA); - - if (o instanceof byte[]){ - byte[] data = (byte[]) o; - writeVarInt(os, data.length); - os.write(data); - } else { - ProtoBuf msg = (ProtoBuf) o; - writeVarInt(os, msg.getDataSize()); - msg.outputTo(os); - } - break; - - case WIRETYPE_START_GROUP: - ((ProtoBuf) getObject(tag, i, ProtoBufType.TYPE_GROUP)) - .outputTo(os); - writeVarInt(os, (tag << 3) | WIRETYPE_END_GROUP); - break; - - default: - throw new IllegalArgumentException(); - } - } - } - } - - /** - * Returns true if the given tag has a signed type that should be ZigZag- - * encoded on the wire. - * - * ZigZag encoding turns a signed number into - * a non-negative number by mapping negative input numbers to positive odd - * numbers in the output space, and positive input numbers to positive even - * numbers in the output space. This is useful because the wire format - * for protocol buffers requires a large number of bytes to encode - * negative integers, while positive integers take up a smaller number - * of bytes proportional to their magnitude. - */ - private boolean isZigZagEncodedType(int tag) { - int declaredType = getType(tag); - return declaredType == ProtoBufType.TYPE_SINT32 || - declaredType == ProtoBufType.TYPE_SINT64; - } - - /** - * Converts a signed number into a non-negative ZigZag-encoded number. - */ - private static long zigZagEncode(long v) { - v = ((v << 1) ^ -(v >>> 63)); - return v; - } - - /** - * Converts a non-negative ZigZag-encoded number back into a signed number. - */ - private static long zigZagDecode(long v) { - v = (v >>> 1) ^ -(v & 1); - return v; - } - - /** - * Writes this and nested protocol buffers to a byte array. - * - * @throws IOException thrown if there is problem writing the byte array - */ - public byte[] toByteArray() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - outputTo(baos); - return baos.toByteArray(); - } - - /** - * Returns the largest tag id used in this message (to simplify testing). - */ - public int maxTag() { - return values.size() - 1; - } - - /** - * Sets the given tag to the given boolean value. - */ - public void setBool(int tag, boolean value) { - setObject(tag, value ? TRUE : FALSE); - } - - /** - * Sets the given tag to the given data bytes. - */ - public void setBytes(int tag, byte[] value) { - setObject(tag, value); - } - - /** - * Sets the given tag to the given integer value. - */ - public void setInt(int tag, int value) { - setLong(tag, value); - } - - /** - * Sets the given tag to the given long value. - */ - public void setLong(int tag, long value) { - setObject(tag, value >= 0 && value < SMALL_NUMBERS.length - ? SMALL_NUMBERS[(int) value] : new Long(value)); - } - - /** - * Sets the given tag to the given double value. - */ - public void setDouble(int tag, double value) { - setLong(tag, Double.doubleToLongBits(value)); - } - - /** - * Sets the given tag to the given float value. - */ - public void setFloat(int tag, float value) { - setInt(tag, Float.floatToIntBits(value)); - } - - /** - * Sets the given tag to the given Group or nested Message. - */ - public void setProtoBuf(int tag, ProtoBuf pb) { - setObject(tag, pb); - } - - /** - * Sets a new protobuf for the specified tag, setting the child protobuf's - * type correctly for the tag. - * @param tag the tag for which to create a new protobuf - * @return the newly created protobuf - */ - public ProtoBuf setNewProtoBuf(int tag) { - ProtoBuf child = newProtoBufForTag(tag); - setProtoBuf(tag, child); - return child; - } - - /** - * Sets the given tag to the given String value. - */ - public void setString(int tag, String value) { - setObject(tag, value); - } - - /** - * Inserts the given boolean value for the given tag at the given index. - */ - public void insertBool(int tag, int index, boolean value) { - insertObject(tag, index, value ? TRUE : FALSE); - } - - /** - * Inserts the given byte array value for the given tag at the given index. - */ - public void insertBytes(int tag, int index, byte[] value) { - insertObject(tag, index, value); - } - - /** - * Inserts the given int value for the given tag at the given index. - */ - public void insertInt(int tag, int index, int value) { - insertLong(tag, index, value); - } - - /** - * Inserts the given long value for the given tag at the given index. - */ - public void insertLong(int tag, int index, long value) { - insertObject(tag, index, value >= 0 && value < SMALL_NUMBERS.length - ? SMALL_NUMBERS[(int) value] : new Long(value)); - } - - /** - * Inserts the given float value for the given tag at the given index. - */ - public void insertFloat(int tag, int index, float value) { - insertInt(tag, index, Float.floatToIntBits(value)); - } - - /** - * Inserts the given double value for the given tag at the given index. - */ - public void insertDouble(int tag, int index, double value) { - insertLong(tag, index, Double.doubleToLongBits(value)); - } - - /** - * Inserts the given group or message for the given tag at the given index. - */ - public void insertProtoBuf(int tag, int index, ProtoBuf pb) { - insertObject(tag, index, pb); - } - - /** - * Inserts the given string value for the given tag at the given index. - */ - public void insertString(int tag, int index, String value) { - insertObject(tag, index, value); - } - - // ----------------- private stuff below this line ------------------------ - - private void assertTypeMatch(int tag, Object object){ - int tagType = getType(tag); - if (tagType == ProtoBufType.TYPE_UNDEFINED && msgType == null) { - return; - } - - if (object instanceof Boolean) { - if (tagType == ProtoBufType.TYPE_BOOL - || tagType == WIRETYPE_VARINT) { - return; - } - } else if (object instanceof Long) { - switch(tagType){ - case WIRETYPE_FIXED32: - case WIRETYPE_FIXED64: - case WIRETYPE_VARINT: - case ProtoBufType.TYPE_BOOL: - case ProtoBufType.TYPE_ENUM: - case ProtoBufType.TYPE_FIXED32: - case ProtoBufType.TYPE_FIXED64: - case ProtoBufType.TYPE_INT32: - case ProtoBufType.TYPE_INT64: - case ProtoBufType.TYPE_SFIXED32: - case ProtoBufType.TYPE_SFIXED64: - case ProtoBufType.TYPE_UINT32: - case ProtoBufType.TYPE_UINT64: - case ProtoBufType.TYPE_SINT32: - case ProtoBufType.TYPE_SINT64: - case ProtoBufType.TYPE_FLOAT: - case ProtoBufType.TYPE_DOUBLE: - return; - } - } else if (object instanceof byte[]){ - switch (tagType){ - case WIRETYPE_LENGTH_DELIMITED: - case ProtoBufType.TYPE_DATA: - case ProtoBufType.TYPE_MESSAGE: - case ProtoBufType.TYPE_TEXT: - case ProtoBufType.TYPE_BYTES: - case ProtoBufType.TYPE_STRING: - return; - } - } else if (object instanceof ProtoBuf) { - switch (tagType){ - case WIRETYPE_LENGTH_DELIMITED: - case WIRETYPE_START_GROUP: - case ProtoBufType.TYPE_DATA: - case ProtoBufType.TYPE_GROUP: - case ProtoBufType.TYPE_MESSAGE: - if (msgType == null || msgType.getData(tag) == null || - ((ProtoBuf) object).msgType == null || - ((ProtoBuf) object).msgType == msgType.getData(tag)) { - return; - } - } - } else if (object instanceof String){ - switch (tagType){ - case WIRETYPE_LENGTH_DELIMITED: - case ProtoBufType.TYPE_DATA: - case ProtoBufType.TYPE_TEXT: - case ProtoBufType.TYPE_STRING: - return; - } - } - throw new IllegalArgumentException(MSG_MISMATCH + " type:" + msgType + - " tag:" + tag); - } - - /** - * Returns the default value for the given tag. - */ - private Object getDefault(int tag){ - - switch(getType(tag)){ - case ProtoBufType.TYPE_UNDEFINED: - case ProtoBufType.TYPE_GROUP: - case ProtoBufType.TYPE_MESSAGE: - return null; - default: - return msgType.getData(tag); - } - } - - /** - * Returns the indicated value converted to the given type. - * - * @throws ArrayIndexOutOfBoundsException for invalid tags and indices - * @throws IllegalArgumentException if count is greater than one. - */ - private Object getObject(int tag, int desiredType) { - - int count = getCount(tag); - - if (count == 0){ - return getDefault(tag); - } - - if (count > 1){ - throw new IllegalArgumentException(); - } - - return getObject(tag, 0, desiredType); - } - - /** - * Returns the indicated value converted to the given type. - * - * @throws ArrayIndexOutOfBoundsException for invalid tags and indices - */ - private Object getObject(int tag, int index, int desiredType) { - - if (index >= getCount(tag)) { - throw new ArrayIndexOutOfBoundsException(); - } - - Object o = values.elementAt(tag); - - Vector v = null; - if (o instanceof Vector) { - v = (Vector) o; - o = v.elementAt(index); - } - - Object o2 = convert(o, desiredType); - - if (o2 != o && o != null) { - if (v == null){ - setObject(tag, o2); - } else { - v.setElementAt(o2, index); - } - } - - return o2; - } - - /** - * Returns the wire type for the given tag. Calls getType() internally, - * so a wire type should be found for all non-empty tags, even if no - * message type is set and the tag was not previously read. - */ - private final int getWireType(int tag) { - - int tagType = getType(tag); - - switch (tagType) { - case WIRETYPE_VARINT: - case WIRETYPE_FIXED32: - case WIRETYPE_FIXED64: - case WIRETYPE_LENGTH_DELIMITED: - case WIRETYPE_START_GROUP: - case ProtoBufType.TYPE_UNDEFINED: - return tagType; - - case ProtoBufType.TYPE_BOOL: - case ProtoBufType.TYPE_INT32: - case ProtoBufType.TYPE_INT64: - case ProtoBufType.TYPE_UINT32: - case ProtoBufType.TYPE_UINT64: - case ProtoBufType.TYPE_SINT32: - case ProtoBufType.TYPE_SINT64: - case ProtoBufType.TYPE_ENUM: - return WIRETYPE_VARINT; - case ProtoBufType.TYPE_DATA: - case ProtoBufType.TYPE_MESSAGE: - case ProtoBufType.TYPE_TEXT: - case ProtoBufType.TYPE_BYTES: - case ProtoBufType.TYPE_STRING: - return WIRETYPE_LENGTH_DELIMITED; - case ProtoBufType.TYPE_DOUBLE: - case ProtoBufType.TYPE_FIXED64: - case ProtoBufType.TYPE_SFIXED64: - return WIRETYPE_FIXED64; - case ProtoBufType.TYPE_FLOAT: - case ProtoBufType.TYPE_FIXED32: - case ProtoBufType.TYPE_SFIXED32: - return WIRETYPE_FIXED32; - case ProtoBufType.TYPE_GROUP: - return WIRETYPE_START_GROUP; - default: - throw new RuntimeException(MSG_UNSUPPORTED + ':' + msgType + '/' + - tag + '/' + tagType); - } - } - - /** - * Inserts a value. - */ - private void insertObject(int tag, int index, Object o) { - assertTypeMatch(tag, o); - - int count = getCount(tag); - - if (count == 0) { - setObject(tag, o); - } else { - Object curr = values.elementAt(tag); - Vector v; - if (curr instanceof Vector) { - v = (Vector) curr; - } else { - v = new Vector(); - v.addElement(curr); - values.setElementAt(v, tag); - } - v.insertElementAt(o, index); - } - } - - /** - * Converts the object if a better suited class exists for the given .proto - * type. If the formats are not compatible, an exception is thrown. - */ - private Object convert(Object obj, int tagType) { - switch (tagType) { - case ProtoBufType.TYPE_UNDEFINED: - return obj; - - case ProtoBufType.TYPE_BOOL: - if (obj instanceof Boolean) { - return obj; - } - switch ((int) ((Long) obj).longValue()) { - case 0: - return FALSE; - case 1: - return TRUE; - default: - throw new IllegalArgumentException(MSG_MISMATCH); - } - case ProtoBufType.TYPE_FIXED32: - case ProtoBufType.TYPE_FIXED64: - case ProtoBufType.TYPE_INT32: - case ProtoBufType.TYPE_INT64: - case ProtoBufType.TYPE_SFIXED32: - case ProtoBufType.TYPE_SFIXED64: - case ProtoBufType.TYPE_SINT32: - case ProtoBufType.TYPE_SINT64: - if (obj instanceof Boolean) { - return SMALL_NUMBERS[((Boolean) obj).booleanValue() ? 1 : 0]; - } - return obj; - case ProtoBufType.TYPE_DATA: - case ProtoBufType.TYPE_BYTES: - if (obj instanceof String) { - return encodeUtf8((String) obj); - } else if (obj instanceof ProtoBuf) { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - try { - ((ProtoBuf) obj).outputTo(buf); - return buf.toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e.toString()); - } - } - return obj; - case ProtoBufType.TYPE_TEXT: - case ProtoBufType.TYPE_STRING: - if (obj instanceof byte[]) { - byte[] data = (byte[]) obj; - return decodeUtf8(data, 0, data.length, true); - } - return obj; - case ProtoBufType.TYPE_GROUP: - case ProtoBufType.TYPE_MESSAGE: - if (obj instanceof byte[]) { - try { - return new ProtoBuf(null).parse((byte[]) obj); - } catch (IOException e) { - throw new RuntimeException(e.toString()); - } - } - return obj; - default: - // default includes FLOAT and DOUBLE - throw new RuntimeException(MSG_UNSUPPORTED); - } - } - - /** - * Reads a variable-size integer (up to 10 bytes for 64 bit) from the - * given input stream. - * - * @param is the stream to read from - * @param permitEOF if true, -1 is returned when EOF is reached instead of - * throwing an IOException - * @return the integer value read from the stream, or -1 if EOF is - * reached and permitEOF is true - * @throws IOException thrown for underlying IO issues and if EOF - * is reached and permitEOF is false - */ - static long readVarInt(InputStream is, boolean permitEOF) throws IOException { - - long result = 0; - int shift = 0; - - // max 10 byte wire format for 64 bit integer (7 bit data per byte) - - for (int i = 0; i < VARINT_MAX_BYTES; i++) { - int in = is.read(); - - if (in == -1) { - if (i == 0 && permitEOF) { - return -1; - } else { - throw new IOException("EOF"); - } - } - result |= ((long) (in & 0x07f)) << shift; - - if ((in & 0x80) == 0){ - break; // get out early - } - - shift += 7; - } - return result; - } - - /** - * Internal helper method to set a (single) value. Overwrites all existing - * values. - */ - private void setObject(int tag, Object o) { - if (values.size() <= tag) { - values.setSize(tag + 1); - } - if (o != null) { - assertTypeMatch(tag, o); - } - values.setElementAt(o, tag); - } - - /** - * Write a variable-size integer to the given output stream. - */ - static void writeVarInt(OutputStream os, long value) throws IOException { - for (int i = 0; i < VARINT_MAX_BYTES; i++) { - - int toWrite = (int) (value & 0x7f); - - value >>>= 7; - - if (value == 0) { - os.write(toWrite); - break; - } else { - os.write(toWrite | 0x080); - } - } - } - - /** - * Returns a byte array containing the given string, encoded as UTF-8. The - * returned byte array contains at least s.length() bytes and at most - * 4 * s.length() bytes. UTF-16 surrogates are transcoded to UTF-8. - * - * @param s input string to be encoded - * @return UTF-8 encoded input string - */ - static byte[] encodeUtf8(String s) { - int len = encodeUtf8(s, null, 0); - byte[] result = new byte[len]; - encodeUtf8(s, result, 0); - return result; - } - - /** - * Encodes the given string to UTF-8 in the given buffer or calculates - * the space needed if the buffer is null. - * - * @param s the string to be UTF-8 encoded - * @param buf byte array to write to - * @return new buffer position after writing (which equals the required size - * if pos is 0) - */ - static int encodeUtf8(String s, byte[] buf, int pos){ - int len = s.length(); - for (int i = 0; i < len; i++){ - int code = s.charAt(i); - - // surrogate 0xd800 .. 0xdfff? - if (code >= 0x0d800 && code <= 0x0dfff && i + 1 < len){ - int codeLo = s.charAt(i + 1); - - // 0xfc00 is the surrogate id mask (first six bit of 16 set) - // 0x03ff is the surrogate data mask (remaining 10 bit) - // check if actually a surrogate pair (d800 ^ dc00 == 0400) - if (((codeLo & 0xfc00) ^ (code & 0x0fc00)) == 0x0400){ - - i += 1; - - int codeHi; - if ((codeLo & 0xfc00) == 0x0d800){ - codeHi = codeLo; - codeLo = code; - } else { - codeHi = code; - } - code = (((codeHi & 0x3ff) << 10) | (codeLo & 0x3ff)) + 0x10000; - } - } - if (code <= 0x007f) { - if (buf != null){ - buf[pos] = (byte) code; - } - pos += 1; - } else if (code <= 0x07FF) { - // non-ASCII <= 0x7FF - if (buf != null){ - buf[pos] = (byte) (0xc0 | (code >> 6)); - buf[pos + 1] = (byte) (0x80 | (code & 0x3F)); - } - pos += 2; - } else if (code <= 0xFFFF){ - // 0x7FF < code <= 0xFFFF - if (buf != null){ - buf[pos] = (byte) ((0xe0 | (code >> 12))); - buf[pos + 1] = (byte) ((0x80 | ((code >> 6) & 0x3F))); - buf[pos + 2] = (byte) ((0x80 | (code & 0x3F))); - } - pos += 3; - } else { - if (buf != null){ - buf[pos] = (byte) ((0xf0 | (code >> 18))); - buf[pos + 1] = (byte) ((0x80 | ((code >> 12) & 0x3F))); - buf[pos + 2] = (byte) ((0x80 | ((code >> 6) & 0x3F))); - buf[pos + 3] = (byte) ((0x80 | (code & 0x3F))); - } - pos += 4; - } - } - - return pos; - } - - /** - * Decodes an array of UTF-8 bytes to a Java string (UTF-16). The tolerant - * flag determines what to do in case of illegal or unsupported sequences. - * - * @param data input byte array containing UTF-8 data - * @param start decoding start position in byte array - * @param end decoding end position in byte array - * @param tolerant if true, an IllegalArgumentException is thrown for illegal - * UTF-8 codes - * @return the string containing the UTF-8 decoding result - */ - static String decodeUtf8(byte[] data, int start, int end, - boolean tolerant){ - - StringBuffer sb = new StringBuffer(end - start); - int pos = start; - - while (pos < end){ - int b = data[pos++] & 0x0ff; - if (b <= 0x7f){ - sb.append((char) b); - } else if (b >= 0xf5){ // byte sequence too long - if (!tolerant){ - throw new IllegalArgumentException("Invalid UTF8"); - } - sb.append((char) b); - } else { - int border = 0xe0; - int count = 1; - int minCode = 128; - int mask = 0x01f; - while (b >= border){ - border = (border >> 1) | 0x80; - minCode = minCode << (count == 1 ? 4 : 5); - count++; - mask = mask >> 1; - } - int code = b & mask; - - for (int i = 0; i < count; i++){ - code = code << 6; - if (pos >= end){ - if (!tolerant){ - throw new IllegalArgumentException("Invalid UTF8"); - } - // otherwise, assume zeroes - } else { - if (!tolerant && (data[pos] & 0xc0) != 0x80){ - throw new IllegalArgumentException("Invalid UTF8"); - } - code |= (data[pos++] & 0x3f); // six bit - } - } - - // illegal code or surrogate code - if (!tolerant && code < minCode || (code >= 0xd800 && code <= 0xdfff)){ - throw new IllegalArgumentException("Invalid UTF8"); - } - - if (code <= 0x0ffff){ - sb.append((char) code); - } else { // surrogate UTF16 - code -= 0x10000; - sb.append((char) (0xd800 | (code >> 10))); // high 10 bit - sb.append((char) (0xdc00 | (code & 0x3ff))); // low 10 bit - } - } - } - return sb.toString(); - } - -} diff --git a/src/com/google/common/io/protocol/ProtoBufType.java b/src/com/google/common/io/protocol/ProtoBufType.java deleted file mode 100644 index 4b6408e8..00000000 --- a/src/com/google/common/io/protocol/ProtoBufType.java +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2007 Google Inc. -// All Rights Reserved. - -package com.google.common.io.protocol; - -import java.util.*; - -/** - * This class can be used to create a memory model of a .proto file. Currently, - * it is assumed that tags ids are not large. This could be improved by storing - * a start offset, relaxing the assumption to a dense number space. - */ -public class ProtoBufType { - // Note: Values 0..15 are reserved for wire types! - public static final int TYPE_UNDEFINED = 16; - public static final int TYPE_DOUBLE = 17; - public static final int TYPE_FLOAT = 18; - public static final int TYPE_INT64 = 19; - public static final int TYPE_UINT64 = 20; - public static final int TYPE_INT32 = 21; - public static final int TYPE_FIXED64 = 22; - public static final int TYPE_FIXED32 = 23; - public static final int TYPE_BOOL = 24; - public static final int TYPE_DATA = 25; - public static final int TYPE_GROUP = 26; - public static final int TYPE_MESSAGE = 27; - public static final int TYPE_TEXT = 28; - public static final int TYPE_UINT32 = 29; - public static final int TYPE_ENUM = 30; - public static final int TYPE_SFIXED32 = 31; - public static final int TYPE_SFIXED64 = 32; - - // new protobuf 2 types - public static final int TYPE_SINT32 = 33; - public static final int TYPE_SINT64 = 34; - public static final int TYPE_BYTES = 35; - public static final int TYPE_STRING = 36; - - public static final int MASK_TYPE = 0x0ff; - public static final int MASK_MODIFIER = 0x0ff00; - - public static final int REQUIRED = 0x100; - public static final int OPTIONAL = 0x200; - public static final int REPEATED = 0x400; - - private final StringBuffer types = new StringBuffer(); - private final Vector data = new Vector(); - private final String typeName; - - /** - * Empty constructor. - */ - public ProtoBufType() { - typeName = null; - } - - /** - * Constructor including a type name for debugging purposes. - */ - public ProtoBufType(String typeName) { - this.typeName = typeName; - } - - /** - * Adds a tag description. The data parameter contains the group definition - * for group elements and the default value for regular elements. - * - * @param optionsAndType any legal combination (bitwise or) of REQUIRED - * or OPTIONAL and REPEATED and one of the TYPE_ - * constants - * @param tag the tag id - * @param data the type for group elements (or the default value for - * regular elements in future versions) - * @return this is returned to permit cascading - */ - public ProtoBufType addElement(int optionsAndType, int tag, Object data) { - while (types.length() <= tag) { - types.append((char) TYPE_UNDEFINED); - this.data.addElement(null); - } - types.setCharAt(tag, (char) optionsAndType); - this.data.setElementAt(data, tag); - - return this; - } - - /** - * Returns the type for the given tag id (without modifiers such as OPTIONAL, - * REPEATED). For undefined tags, TYPE_UNDEFINED is returned. - */ - public int getType(int tag) { - return (tag < 0 || tag >= types.length()) - ? TYPE_UNDEFINED - : (types.charAt(tag) & MASK_TYPE); - } - - /** - * Returns a bit combination of the modifiers for the given tag id - * (OPTIONAL, REPEATED, REQUIRED). For undefined tags, OPTIONAL|REPEATED - * is returned. - */ - public int getModifiers(int tag) { - return (tag < 0 || tag >= types.length()) - ? (OPTIONAL | REPEATED) - : (types.charAt(tag) & MASK_MODIFIER); - } - - /** - * Returns the data associated to a given tag (either the default value for - * regular elements or a ProtoBufType for groups and messages). For undefined - * tags, null is returned. - */ - public Object getData(int tag) { - return (tag < 0 || tag >= data.size()) ? null : data.elementAt(tag); - } - - /** - * Returns the type name set in the constructor for debugging purposes. - */ - public String toString() { - return typeName; - } - - /** - * {@inheritDoc} - * <p>Two ProtoBufTypes are equals if the fields types are the same. - */ - public boolean equals(Object object) { - if (null == object) { - // trivial check - return false; - } else if (this == object) { - // trivial check - return true; - } else if (this.getClass() != object.getClass()) { - // different class - return false; - } - ProtoBufType other = (ProtoBufType) object; - - return stringEquals(types, other.types); - } - - /** - * {@inheritDoc} - */ - public int hashCode() { - if (types != null) { - return types.hashCode(); - } else { - return super.hashCode(); - } - } - - public static boolean stringEquals(CharSequence a, CharSequence b) { - if (a == b) return true; - int length; - if (a != null && b != null && (length = a.length()) == b.length()) { - if (a instanceof String && b instanceof String) { - return a.equals(b); - } else { - for (int i = 0; i < length; i++) { - if (a.charAt(i) != b.charAt(i)) return false; - } - return true; - } - } - return false; - } -} diff --git a/src/com/google/common/io/protocol/ProtoBufUtil.java b/src/com/google/common/io/protocol/ProtoBufUtil.java deleted file mode 100644 index a14bef6e..00000000 --- a/src/com/google/common/io/protocol/ProtoBufUtil.java +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. - -package com.google.common.io.protocol; - -import java.io.*; - -/** - * Utility functions for dealing with ProtoBuf objects consolidated from - * previous spot implementations across the codebase. - * - */ -public final class ProtoBufUtil { - private ProtoBufUtil() { - } - - /** Convenience method to return a string value from of a proto or "". */ - public static String getProtoValueOrEmpty(ProtoBuf proto, int tag) { - try { - return (proto != null && proto.has(tag)) ? proto.getString(tag) : ""; - } catch (ClassCastException e) { - return ""; - } - } - - /** Convenience method to return a string value from of a sub-proto or "". */ - public static String getSubProtoValueOrEmpty( - ProtoBuf proto, int sub, int tag) { - try { - return getProtoValueOrEmpty(getSubProtoOrNull(proto, sub), tag); - } catch (ClassCastException e) { - return ""; - } - } - - /** Convenience method to get a subproto if the proto has it. */ - public static ProtoBuf getSubProtoOrNull(ProtoBuf proto, int sub) { - return (proto != null && proto.has(sub)) ? proto.getProtoBuf(sub) : null; - } - - /** - * Get an int with "tag" from the proto buffer. If the given field can't be - * retrieved, return the provided default value. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @param defaultValue The value to return if the field can't be retrieved. - * @return The result which should be an integer. - */ - public static int getProtoValueOrDefault(ProtoBuf proto, int tag, - int defaultValue) { - try { - return (proto != null && proto.has(tag)) - ? proto.getInt(tag) : defaultValue; - } catch (IllegalArgumentException e) { - return defaultValue; - } catch (ClassCastException e) { - return defaultValue; - } - } - - /** - * Get an Int with "tag" from the proto buffer. - * If the given field can't be retrieved, return 0. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @return The result which should be an integer. - */ - public static int getProtoValueOrZero(ProtoBuf proto, int tag) { - return getProtoValueOrDefault(proto, tag, 0); - } - - /** - * Get an Long with "tag" from the proto buffer. - * If the given field can't be retrieved, return 0. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @return The result which should be an integer. - */ - public static long getProtoLongValueOrZero(ProtoBuf proto, int tag) { - try { - return (proto != null && proto.has(tag)) ? proto.getLong(tag) : 0L; - } catch (IllegalArgumentException e) { - return 0L; - } catch (ClassCastException e) { - return 0L; - } - } - - /** - * Get an Int with "tag" from the proto buffer. - * If the given field can't be retrieved, return -1. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @return The result which should be a long. - */ - public static long getProtoValueOrNegativeOne(ProtoBuf proto, int tag) { - try { - return (proto != null && proto.has(tag)) ? proto.getLong(tag) : -1; - } catch (IllegalArgumentException e) { - return -1; - } catch (ClassCastException e) { - return -1; - } - } - - /** - * Returns an input stream for reading protocol buffer - * responses. This method reads a 32-bit signed integer from the - * stream, which determines the data size and compression. If the - * integer is negative, indicating a GZipped input stream which we - * do not support, an exception is thrown. Otherwise, just a - * BoundInputStream is returned. The input stream returned is always - * limited to the data available. - * - * @param dataInput the data input to read from - * @return an input stream, limited to the data size read from the stream - * @throws IOException if the incoming stream is gzipped. - */ - public static InputStream getInputStreamForProtoBufResponse( - DataInput dataInput) throws IOException { - - int size = dataInput.readInt(); - InputStream is = new BoundInputStream((InputStream) dataInput, - Math.abs(size)); - - if (size < 0) { - throw new IOException("Cannot read gzipped streams"); - } - return is; - } - - /** - * Reads a single protocol buffer from the given input stream. This method is - * provided where the client needs incremental access to the contents of a - * protocol buffer which contains a sequence of protocol buffers. - * <p /> - * Please use {@link #getInputStreamForProtoBufResponse} to obtain an input - * stream suitable for this method. - * - * @param umbrellaType the type of the "outer" protocol buffer containing - * the message to read - * @param is the stream to read the protocol buffer from - * @param result the result protocol buffer (must be empty, will be filled - * with the data read and the type will be set) - * @return the tag id of the message, -1 at the end of the stream - */ - public static int readNextProtoBuf(ProtoBufType umbrellaType, - InputStream is, ProtoBuf result) throws IOException { - long tagAndType = ProtoBuf.readVarInt(is, true /* permits EOF */); - if (tagAndType == -1) { - return -1; - } - - if ((tagAndType & 7) != ProtoBuf.WIRETYPE_LENGTH_DELIMITED) { - throw new IOException("Message expected"); - } - int tag = (int) (tagAndType >>> 3); - - result.setType((ProtoBufType) umbrellaType.getData(tag)); - int length = (int) ProtoBuf.readVarInt(is, false); - result.parse(is, length); - return tag; - } - - /** - * Reads a size int and a protocol buffer from a DataInput. If the size - * is negative, this is interpreted as an indicator that the protocol buffer - * is packed with GZIP. In this case, -size bytes are read, and the data is - * unpacked with GZIP before constructing the protocol buffer. - * - * @param protoBufType the protocol buffer type to read - * @param dataInput the data input to read from - * @return a protocol buffer of the given type - * @throws IOException - */ - public static ProtoBuf readProtoBufResponse(ProtoBufType protoBufType, - DataInput dataInput) throws IOException { - ProtoBuf response = new ProtoBuf(protoBufType); - InputStream is = getInputStreamForProtoBufResponse(dataInput); - response.parse(is); - if (is.read() != -1) { - throw new IOException(); - } - return response; - } - - /** - * A wrapper for <code> getProtoValueOrNegativeOne </code> that drills into - * a sub message returning the long value if it exists, returning -1 if it - * does not. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @param sub The sub tag value that identifies which protocol buffer - * sub-field to retrieve.n - * @return The result which should be a long. - */ - public static long getSubProtoValueOrNegativeOne( - ProtoBuf proto, int sub, int tag) { - try { - return getProtoValueOrNegativeOne(getSubProtoOrNull(proto, sub), tag); - } catch (IllegalArgumentException e) { - return -1; - } catch (ClassCastException e) { - return -1; - } - } - - /** - * A wrapper for {@link #getProtoValueOrDefault(ProtoBuf, int, int)} that - * drills into a sub message returning the int value if it exists, returning - * the given default if it does not. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * retrieve. - * @param sub The sub tag value that identifies which protocol buffer - * sub-field to retrieve. - * @param defaultValue The value to return if the field is not present. - * @return The result which should be a long. - */ - public static int getSubProtoValueOrDefault(ProtoBuf proto, int sub, int tag, - int defaultValue) { - try { - return getProtoValueOrDefault(getSubProtoOrNull(proto, sub), tag, - defaultValue); - } catch (IllegalArgumentException e) { - return defaultValue; - } catch (ClassCastException e) { - return defaultValue; - } - } - - /** - * Creates a sub ProtoBuf of the given Protobuf and sets it. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * create. - * @return the sub ProtoBuf generated. - */ - public static ProtoBuf createProtoBuf(ProtoBuf proto, int tag) { - ProtoBuf child = proto.createGroup(tag); - proto.setProtoBuf(tag, child); - return child; - } - - /** - * Creates a sub ProtoBuf of the given Protobuf and adds it. - * - * @param proto The proto buffer. - * @param tag The tag value that identifies which protocol buffer field to - * add. - * @return the sub ProtoBuf generated. - */ - public static ProtoBuf addProtoBuf(ProtoBuf proto, int tag) { - ProtoBuf child = proto.createGroup(tag); - proto.addProtoBuf(tag, child); - return child; - } - - /** - * Writes the ProtoBuf to the given DataOutput. This is useful for unit - * tests. - * - * @param output The data output to write to. - * @param protoBuf The proto buffer. - */ - public static void writeProtoBufToOutput(DataOutput output, ProtoBuf protoBuf) - throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - protoBuf.outputTo(baos); - byte[] bytes = baos.toByteArray(); - output.writeInt(bytes.length); - output.write(bytes); - } -} diff --git a/src/com/google/common/io/protocol/package.html b/src/com/google/common/io/protocol/package.html deleted file mode 100644 index 1c9bf9da..00000000 --- a/src/com/google/common/io/protocol/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body> - {@hide} -</body> -</html> |