Technically, the protobuf fields may not be in order, but in most cases (including the one you are showing) we can reasonably assume that the fields are in order (the only way to get them out of order here is to separately serialize the two semi-classes and combine the results, which is technically true in the protobuf specification).
So what we will have:
- varint notation: field 1, string - always decimal
10
- varint denoting "a", the length of the header
- "a" encoded UTF-8 header
- varint notation: field 2, string - always decimal
18
- varint denoting "b", body length
- "b" bytes, body
We can assume that "a" is >= 0
and < int.MaxValue
- this means that encoding will require no more than 5 bytes; therefore, if you buffer at least 6 bytes, you will have enough information to know how big the header is. Of course, it can technically also contain part of the body, so you will need to hold it in your hands! But if you had sync-over-async Stream
, you can only read this part of the stream, for example:
int protoHeader = ProtoReader.DirectReadVarintInt32(stream);
Or, if "sync over async" is complex, an explicit read:
static byte[] ReadAtLeast6() { return new byte[] { 0x0A, 0x0B, 0x68, 0x65, 0x6C, 0x6C, 0x6F }; } static byte[] ReadMore(int bytes) { return new byte[] { 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64 }; } static void Main() {
source share