2

I have a java backend that sends messages using protobuf, it sends delimited message objects in one big byte array blob over tib. I can deserialize them fine using the function parseDelimitedFrom(yourStreamHere) in java but on the C# side we are having some issues and I couldn't find any examples but I may just be missing something obvious here.

We are doing something in C# like this

using (MemoryStream mem = new MemoryStream()) 
{ 
    mem.Write(byteArray, 0, byteArray.Length); 
    mem.Position = 0;     
    return Serializer.Deserialize<List<OrderState>>(mem); 
}

Note: I saw an older post on this but it looked pretty dated and I think changes have occurred to protobuf-net since then but correct if I'm wrong there

Community
  • 1
  • 1
jtruelove
  • 3,306
  • 3
  • 25
  • 29
  • BTW your use of MemoryStream is inefficient. You can simply wrap your byte array in a MemoryStream using `new MemoryStream(byteArray)` instead of creating a MemoryStream with a new, internal byte array and copying your byte array into it. – dtb Sep 16 '10 at 14:00
  • I don't think the difference is that big of a deal because the MemoryStream is going to do something like this internally anyways, it is just some sample code, do you have any insight into the question? – jtruelove Sep 16 '10 at 14:42
  • I don't know off the top of my head which form parsedelimited uses. I'm not at a computer right now, but should be able to look later. – Marc Gravell Sep 16 '10 at 14:59
  • Out of interest, what happens when you try the code as written? – Marc Gravell Sep 16 '10 at 15:00
  • we get this exception: ProtoBuf.ProtoException: Invalid tag: 0 at ProtoBuf.Serializer.ParseFieldToken(UInt32 token, WireType& wireType, Int32& tag) at ProtoBuf.Serializer`1.Deserialize[TCreation](T& instance, SerializationContext context) at ProtoBuf.Serializer`1.DeserializeChecked[TCreation](T& instance, SerializationContext source) at ProtoBuf.SerializerSimpleProxy`1.Deserialize(TValue& value, SerializationContext source) at ProtoBuf.Serializer.Deserialize[T](SerializationContext source) at ProtoBuf.Serializer.Deserialize[T](Stream source) – jtruelove Sep 16 '10 at 15:32
  • Just a hunch, but try deserializeitems, passing tag 0 and prefix style base 128 – Marc Gravell Sep 16 '10 at 16:00

1 Answers1

1

The developer was using tag 0 and prefix style 128 at one point yesterday like so

IEnumerable<SomeObject> list =  (Serializer.DeserializeItems<SomeObject>(memoryStream, PrefixStyle.Base128, 0));

but we were still getting an error. When we called getProto on the C# side today it appears it was converting our properties that were set to the double type to the fixed64 type, on the java side we had specified double so I think this mismatch was causing the errors we were seeing. We temporarily changed those fields to the string type and now the above snippet works. Of course ideally we don't want to send strings when we don't have to.

jtruelove
  • 3,306
  • 3
  • 25
  • 29
  • > converting our properties that were set to the double type to the fixed64 type - do you mean when generating a .proto? or on the wire? There is a recent fix to .proto generation for this, but this doesn't change the actual serialization. – Marc Gravell Sep 16 '10 at 19:17
  • I believe when generating the .proto on the C# side, but when the requests from the java services were coming in it was giving us an exception probably because the incoming request was using a double but the C# definition had a fixed64, or are you saying this wouldn't ever occur? – jtruelove Sep 17 '10 at 13:33
  • what is confusing (to me) is that on the wire both use an identical format. It was only GetProto that was affected, so I'm confused... – Marc Gravell Sep 22 '10 at 05:39
  • Yeah me too then, when we circle back in a bit to optimize the field types from string to something more specific if I see errors again I'll revisit this thread with details – jtruelove Sep 23 '10 at 14:26