I don't *think* the generic type is going to be enough due to erasure,
but I'm not a generics expert. I know something like the following
works (I may be messing up the generics syntax since I'm not super
familiar with it):
<T extends MessageLite> public T fromByteBuffer(ByteBuffer byteBuffer,
T defaultInstance) {
Builder b = defaultInstance.newBuilderForType();
b.mergeFrom(ByteString.copyFrom(byteBuffer));
return b.build();
}
You can get defaultInstance from
ConcreteMessageType.getDefaultInstance();
You may want to create a tiny InputStream wrapper around ByteBuffer to
avoid an extra copy, or if you know it is a heap byte buffer, use the
array mergeFrom().
Hope that helps,
Evan
--
Evan Jones
http://evanjones.ca/
--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.
Because the serialized representation does not include anything to
describe the type. Thus, based on just the raw bytes, you can't tell
what type of message it is. If you need this functionality, you need
to build it yourself, either using union types:
http://code.google.com/apis/protocolbuffers/docs/techniques.html#union
Or by doing some custom thing (including some unique identifier, or
the fully qualified message name, or something in some header first).
Oh, sorry, I misunderstood your question, so my answer is somewhat
invalid.
> One could then:
> 1) pick the right subclass of Message based upon some information
> outside the raw bytes (in my case something stored in a protobuf
> wrapper around the raw bytes)
> 2) call subclass.parseFrom(bytes)
>
> now we have to jump through more hoops for step 2 (create instance
> of Message subclass, newBuilderForType, mergeFrom, isInitialized,
> build)
The MessageLite.Builder interface has a mergeFrom method that does
what you want. What you should do is something like:
* Get a MessageLite instance for the message type you want to parse
(eg. something like MyMessageType.getDefaultInstance(), or
MessageLite.getDefaultInstanceForType())
* Hold on to that MessageLite instance in some sort of registry.
(HashMap<Integer, MessageLite>?)
* When you get a message, look at the protobuf wrapper to determine
the type.
* Look up the "prototype" MessageLite instance in your registry.
* Call prototypeInstance.newBuilderForType().mergeFrom(bytes).build()
This only creates a single instance of the message each time.
The .build() method will automatically check that the message is
initialized, so you don't need to call isInitialized (although you may
want to catch the exception it could throw?).
This Builder pattern is used so that the Message objects are
immutable. This means they can be passed between threads without
requiring any synchronization. See:
http://code.google.com/apis/protocolbuffers/docs/javatutorial.html#builders
Hope this helps,