org.fusesource.hawtbuf.proto.BaseMessage 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!
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fusesource.hawtbuf.proto;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.BufferOutputStream;
abstract public class BaseMessage implements Message {
protected int memoizedSerializedSize = -1;
abstract public T clone() throws CloneNotSupportedException;
public void clear() {
memoizedSerializedSize = -1;
}
public boolean isInitialized() {
return missingFields().isEmpty();
}
@SuppressWarnings("unchecked")
public T assertInitialized() throws UninitializedMessageException {
java.util.ArrayList missingFields = missingFields();
if (!missingFields.isEmpty()) {
throw new UninitializedMessageException(missingFields);
}
return getThis();
}
@SuppressWarnings("unchecked")
protected T checktInitialized() throws InvalidProtocolBufferException {
java.util.ArrayList missingFields = missingFields();
if (!missingFields.isEmpty()) {
throw new UninitializedMessageException(missingFields).asInvalidProtocolBufferException();
}
return getThis();
}
public ArrayList missingFields() {
load();
return new ArrayList();
}
protected void loadAndClear() {
memoizedSerializedSize = -1;
}
protected void load() {
}
@SuppressWarnings("unchecked")
public T mergeFrom(T other) {
return getThis();
}
public void writeUnframed(CodedOutputStream output) throws java.io.IOException {
// if (encodedForm == null) {
// encodedForm = new byte[serializedSizeUnframed()];
// com.google.protobuf.CodedOutputStream original = output;
// output =
// com.google.protobuf.CodedOutputStream.newInstance(encodedForm);
// if (hasField1()) {
// output.writeInt32(1, getField1());
// }
// if (hasField2()) {
// output.writeInt64(2, getField2());
// }
// if (hasField3()) {
// writeMessage(output, 3, getField3());
// }
// output.checkNoSpaceLeft();
// output = original;
// }
// output.writeRawBytes(encodedForm);
}
// /////////////////////////////////////////////////////////////////
// Write related helpers.
// /////////////////////////////////////////////////////////////////
public void writeFramed(CodedOutputStream output) throws IOException {
output.writeRawVarint32(serializedSizeUnframed());
writeUnframed(output);
}
public Buffer toUnframedBuffer() {
try {
int size = serializedSizeUnframed();
BufferOutputStream baos = new BufferOutputStream(size);
CodedOutputStream output = new CodedOutputStream(baos);
writeUnframed(output);
Buffer rc = baos.toBuffer();
if( rc.length != size ) {
throw new IllegalStateException("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 Buffer toFramedBuffer() {
try {
int size = serializedSizeFramed();
BufferOutputStream baos = new BufferOutputStream(size);
CodedOutputStream output = new CodedOutputStream(baos);
writeFramed(output);
Buffer rc = baos.toBuffer();
if( rc.length != size ) {
throw new IllegalStateException("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 byte[] toUnframedByteArray() {
return toUnframedBuffer().toByteArray();
}
public byte[] toFramedByteArray() {
return toFramedBuffer().toByteArray();
}
public void writeFramed(OutputStream output) throws IOException {
CodedOutputStream codedOutput = new CodedOutputStream(output);
writeFramed(codedOutput);
codedOutput.flush();
}
public void writeUnframed(OutputStream output) throws IOException {
CodedOutputStream codedOutput = new CodedOutputStream(output);
writeUnframed(codedOutput);
codedOutput.flush();
}
public int serializedSizeFramed() {
int t = serializedSizeUnframed();
return CodedOutputStream.computeRawVarint32Size(t) + t;
}
// /////////////////////////////////////////////////////////////////
// Read related helpers.
// /////////////////////////////////////////////////////////////////
public T mergeFramed(CodedInputStream input) throws IOException {
int length = input.readRawVarint32();
int oldLimit = input.pushLimit(length);
T rc = mergeUnframed(input);
input.checkLastTagWas(0);
input.popLimit(oldLimit);
return rc;
}
public T mergeUnframed(Buffer data) throws InvalidProtocolBufferException {
try {
CodedInputStream input = new CodedInputStream(data);
mergeUnframed(input);
input.checkLastTagWas(0);
return getThis();
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
throw new RuntimeException("An IOException was thrown (should never happen in this method).", e);
}
}
@SuppressWarnings("unchecked")
private T getThis() {
return (T) this;
}
public T mergeFramed(Buffer data) throws InvalidProtocolBufferException {
try {
CodedInputStream input = new CodedInputStream(data);
mergeFramed(input);
input.checkLastTagWas(0);
return getThis();
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
throw new RuntimeException("An IOException was thrown (should never happen in this method).", e);
}
}
public T mergeUnframed(byte[] data) throws InvalidProtocolBufferException {
return mergeUnframed(new Buffer(data));
}
public T mergeFramed(byte[] data) throws InvalidProtocolBufferException {
return mergeFramed(new Buffer(data));
}
public T mergeUnframed(InputStream input) throws IOException {
CodedInputStream codedInput = new CodedInputStream(input);
mergeUnframed(codedInput);
return getThis();
}
public T mergeFramed(InputStream input) throws IOException {
int length = readRawVarint32(input);
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 mergeUnframed(data);
}
// /////////////////////////////////////////////////////////////////
// Internal implementation methods.
// /////////////////////////////////////////////////////////////////
static protected 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);
}
}
}
static protected void writeGroup(CodedOutputStream output, int tag, BaseMessage message) throws IOException {
output.writeTag(tag, WireFormat.WIRETYPE_START_GROUP);
message.writeUnframed(output);
output.writeTag(tag, WireFormat.WIRETYPE_END_GROUP);
}
static protected T readGroup(CodedInputStream input, int tag, T group) throws IOException {
group.mergeUnframed(input);
input.checkLastTagWas(WireFormat.makeTag(tag, WireFormat.WIRETYPE_END_GROUP));
return group;
}
static protected int computeGroupSize(int tag, BaseMessage message) {
return CodedOutputStream.computeTagSize(tag) * 2 + message.serializedSizeUnframed();
}
static protected void writeMessage(CodedOutputStream output, int tag, BaseMessage message) throws IOException {
output.writeTag(tag, WireFormat.WIRETYPE_LENGTH_DELIMITED);
message.writeFramed(output);
}
static protected int computeMessageSize(int tag, BaseMessage message) {
return CodedOutputStream.computeTagSize(tag) + message.serializedSizeFramed();
}
protected List prefix(List missingFields, String prefix) {
ArrayList rc = new ArrayList(missingFields.size());
for (String v : missingFields) {
rc.add(prefix + v);
}
return rc;
}
/**
* 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 protected 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.");
}
return (byte) rc;
}
}