org.fusesource.hawtbuf.proto.MessageBufferSupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hawtbuf-proto Show documentation
Show all versions of hawtbuf-proto Show documentation
HawtBuf Proto: A protobuf library
The newest version!
package org.fusesource.hawtbuf.proto;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.BufferOutputStream;
final public class MessageBufferSupport {
public static final String FORZEN_ERROR_MESSAGE = "Modification not allowed after object has been fozen. Try modifying a copy of this object.";
static public Buffer toUnframedBuffer(MessageBuffer message) {
try {
int size = message.serializedSizeUnframed();
BufferOutputStream baos = new BufferOutputStream(size);
CodedOutputStream output = new CodedOutputStream(baos);
message.writeUnframed(output);
Buffer rc = baos.toBuffer();
assert rc.length == size : "Did not write as much data as expected.";
return rc;
} catch (IOException e) {
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
}
}
static public Buffer toFramedBuffer(MessageBuffer message) {
try {
int size = message.serializedSizeFramed();
BufferOutputStream baos = new BufferOutputStream(size);
CodedOutputStream output = new CodedOutputStream(baos);
message.writeFramed(output);
Buffer rc = baos.toBuffer();
assert rc.length==size : "Did not write as much data as expected.";
return rc;
} catch (IOException e) {
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
}
}
public static void writeMessage(CodedOutputStream output, int tag, MessageBuffer message) throws IOException {
output.writeTag(tag, WireFormat.WIRETYPE_LENGTH_DELIMITED);
message.writeFramed(output);
}
public static int computeMessageSize(int tag, MessageBuffer message) {
return CodedOutputStream.computeTagSize(tag) + message.serializedSizeFramed();
}
public static Buffer readFrame(java.io.InputStream input) throws IOException {
int length = 0;
try {
length = readRawVarint32(input);
} catch (InvalidProtocolBufferException e) {
if( e.isEOF() ) {
throw new EOFException();
} else {
throw e;
}
}
byte[] data = new byte[length];
int pos = 0;
while (pos < length) {
int r = input.read(data, pos, length - pos);
if (r < 0) {
throw new InvalidProtocolBufferException("Input stream ended before a full message frame could be read.");
}
pos += r;
}
return new Buffer(data);
}
/**
* Read a raw Varint from the stream. If larger than 32 bits, discard the
* upper bits.
*/
static public int readRawVarint32(InputStream is) throws IOException {
byte tmp = readRawByte(is);
if (tmp >= 0) {
return tmp;
}
int result = tmp & 0x7f;
if ((tmp = readRawByte(is)) >= 0) {
result |= tmp << 7;
} else {
result |= (tmp & 0x7f) << 7;
if ((tmp = readRawByte(is)) >= 0) {
result |= tmp << 14;
} else {
result |= (tmp & 0x7f) << 14;
if ((tmp = readRawByte(is)) >= 0) {
result |= tmp << 21;
} else {
result |= (tmp & 0x7f) << 21;
result |= (tmp = readRawByte(is)) << 28;
if (tmp < 0) {
// Discard upper 32 bits.
for (int i = 0; i < 5; i++) {
if (readRawByte(is) >= 0)
return result;
}
throw new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
}
}
}
}
return result;
}
static public byte readRawByte(InputStream is) throws IOException {
int rc = is.read();
if (rc == -1) {
throw new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
+ "misreported its own length.", true);
}
return (byte) rc;
}
static public void addAll(Iterable values, Collection super T> list) {
if (values instanceof Collection) {
@SuppressWarnings("unsafe")
Collection collection = (Collection) values;
list.addAll(collection);
} else {
for (T value : values) {
list.add(value);
}
}
}
}