diff options
Diffstat (limited to 'java/src/main')
5 files changed, 88 insertions, 7 deletions
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java index 51c6e783..2f61859d 100644 --- a/java/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java @@ -77,6 +77,7 @@ public abstract class AbstractMessage implements Message { return true; } + @Override public final String toString() { return TextFormat.printToString(this); } @@ -199,6 +200,7 @@ public abstract class AbstractMessage implements Message { public static abstract class Builder<BuilderType extends Builder> implements Message.Builder { // The compiler produces an error if this is not declared explicitly. + @Override public abstract BuilderType clone(); public BuilderType clear() { @@ -307,8 +309,13 @@ public abstract class AbstractMessage implements Message { public BuilderType mergeFrom(byte[] data) throws InvalidProtocolBufferException { + return mergeFrom(data, 0, data.length); + } + + public BuilderType mergeFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException { try { - CodedInputStream input = CodedInputStream.newInstance(data); + CodedInputStream input = CodedInputStream.newInstance(data, off, len); mergeFrom(input); input.checkLastTagWas(0); return (BuilderType) this; @@ -322,10 +329,18 @@ public abstract class AbstractMessage implements Message { } public BuilderType mergeFrom( - byte[] data, ExtensionRegistry extensionRegistry) + byte[] data, + ExtensionRegistry extensionRegistry) + throws InvalidProtocolBufferException { + return mergeFrom(data, 0, data.length, extensionRegistry); + } + + public BuilderType mergeFrom( + byte[] data, int off, int len, + ExtensionRegistry extensionRegistry) throws InvalidProtocolBufferException { try { - CodedInputStream input = CodedInputStream.newInstance(data); + CodedInputStream input = CodedInputStream.newInstance(data, off, len); mergeFrom(input, extensionRegistry); input.checkLastTagWas(0); return (BuilderType) this; diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java index 9814dfc1..f376e7a1 100644 --- a/java/src/main/java/com/google/protobuf/ByteString.java +++ b/java/src/main/java/com/google/protobuf/ByteString.java @@ -35,6 +35,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FilterOutputStream; import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; /** * Immutable array of bytes. @@ -154,6 +155,15 @@ public final class ByteString { } /** + * Constructs a new read-only {@code java.nio.ByteBuffer} with the + * same backing byte array. + */ + public ByteBuffer asReadOnlyByteBuffer() { + ByteBuffer byteBuffer = ByteBuffer.wrap(this.bytes); + return byteBuffer.asReadOnlyBuffer(); + } + + /** * Constructs a new {@code String} by decoding the bytes using the * specified charset. */ diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java index c956ed2b..caef068b 100644 --- a/java/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java @@ -59,7 +59,14 @@ public final class CodedInputStream { * Create a new CodedInputStream wrapping the given byte array. */ public static CodedInputStream newInstance(byte[] buf) { - return new CodedInputStream(buf); + return newInstance(buf, 0, buf.length); + } + + /** + * Create a new CodedInputStream wrapping the given byte array slice. + */ + public static CodedInputStream newInstance(byte[] buf, int off, int len) { + return new CodedInputStream(buf, off, len); } // ----------------------------------------------------------------- @@ -454,7 +461,7 @@ public final class CodedInputStream { private byte[] buffer; private int bufferSize; private int bufferSizeAfterLimit = 0; - private int bufferPos = 0; + private int bufferPos; private InputStream input; private int lastTag = 0; @@ -479,15 +486,17 @@ public final class CodedInputStream { private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB private static final int BUFFER_SIZE = 4096; - private CodedInputStream(byte[] buffer) { + private CodedInputStream(byte[] buffer, int off, int len) { this.buffer = buffer; - this.bufferSize = buffer.length; + this.bufferSize = off + len; + this.bufferPos = off; this.input = null; } private CodedInputStream(InputStream input) { this.buffer = new byte[BUFFER_SIZE]; this.bufferSize = 0; + this.bufferPos = 0; this.input = input; } diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java index bc231a15..b1be8b14 100644 --- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -87,6 +87,33 @@ public abstract class GeneratedMessage extends AbstractMessage { } return result; } + + public boolean isInitialized() { + for (FieldDescriptor field : getDescriptorForType().getFields()) { + // Check that all required fields are present. + if (field.isRequired()) { + if (!hasField(field)) { + return false; + } + } + // Check that embedded messages are initialized. + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.isRepeated()) { + for (Message element : (List<Message>) getField(field)) { + if (!element.isInitialized()) { + return false; + } + } + } else { + if (hasField(field) && !((Message) getField(field)).isInitialized()) { + return false; + } + } + } + } + + return true; + } public Map<FieldDescriptor, Object> getAllFields() { return Collections.unmodifiableMap(getAllFieldsMutable()); @@ -370,6 +397,10 @@ public abstract class GeneratedMessage extends AbstractMessage { protected boolean extensionsAreInitialized() { return extensions.isInitialized(); } + + public boolean isInitialized() { + return super.isInitialized() && extensionsAreInitialized(); + } /** * Used by subclasses to serialize extensions. Extension ranges may be diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java index add5dab6..9635387a 100644 --- a/java/src/main/java/com/google/protobuf/Message.java +++ b/java/src/main/java/com/google/protobuf/Message.java @@ -400,6 +400,13 @@ public interface Message { /** * Parse {@code data} as a message of this type and merge it with the * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + */ + public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}. */ Builder mergeFrom(byte[] data, @@ -407,6 +414,15 @@ public interface Message { throws InvalidProtocolBufferException; /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}. + */ + Builder mergeFrom(byte[] data, int off, int len, + ExtensionRegistry extensionRegistry) + throws InvalidProtocolBufferException; + + /** * Parse a message of this type from {@code input} and merge it with the * message being built. This is just a small wrapper around * {@link #mergeFrom(CodedInputStream)}. Note that this method always |