Reputation: 709
I want to have a simple piece of code that will iterate through a random stream of protocol buffers, and print out the contents without having an explicit understanding of the structural contents. Something that is equivalent to XmlReader.Read() inside a while loop
using (ProtoBuf.ProtoReader protoReader =
new ProtoBuf.ProtoReader(stream1, null,
new ProtoBuf.SerializationContext { }))
{
protoReader.ReadFieldHeader();
while (protoReader.WireType != ProtoBuf.WireType.None)
{
switch (protoReader.WireType)
{
case ProtoBuf.WireType.Fixed64:
Console.WriteLine(protoReader.ReadInt64());
break;
case ProtoBuf.WireType.Fixed32:
Console.WriteLine(protoReader.ReadInt32());
break;
case ProtoBuf.WireType.StartGroup:
Console.WriteLine(protoReader.ReadInt32());
break;
default:
Console.WriteLine(protoReader.WireType);
break;
}
}
}
However I don't know how to advance the protocol buffer to the next element. In my test, it keeps returning "StartGroup" and never advancing. How can I advance to the next element in the stream?
Upvotes: 1
Views: 745
Reputation: 1064204
The ReadFieldHeader()
should be inside the loop:
while(protoReader.ReadFieldHeader() > 0)
{
//...
}
Note: if you don't know how to process a given field, there is a .SkipField()
method that will correctly read the data - for example:
default:
Console.WriteLine(protoReader.WireType);
protoReader.SkipField();
break;
you must read or skip the data exactly once per field-header.
In the case of groups and sub-items, you need to use StartSubItem
etc:
var tok = ProtoReader.StartSubItem(protoReader);
// an inner while-loop, etc
ProtoReader.EndSubItem(tok);
alternatively: use SkipField()
.
Upvotes: 1