internal static uint?ReadUInt32Wrapper(ref ReadOnlySpan <byte> buffer, ref ParserInternalState state) { // field=1, type=varint = tag of 8 const int expectedTag = 8; // length:1 + tag:1 + value:10(varint64-max) = 12 bytes // Value can be 64 bits for negative integers if (state.bufferPos + 12 <= state.bufferSize) { // The entire wrapper message is already contained in `buffer`. int pos0 = state.bufferPos; int length = buffer[state.bufferPos++]; if (length == 0) { return(0); } // Length will always fit in a single byte. if (length >= 128) { state.bufferPos = pos0; return(ReadUInt32WrapperSlow(ref buffer, ref state)); } int finalBufferPos = state.bufferPos + length; if (buffer[state.bufferPos++] != expectedTag) { state.bufferPos = pos0; return(ReadUInt32WrapperSlow(ref buffer, ref state)); } var result = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); // Verify this message only contained a single field. if (state.bufferPos != finalBufferPos) { state.bufferPos = pos0; return(ReadUInt32WrapperSlow(ref buffer, ref state)); } return(result); } else { return(ReadUInt32WrapperSlow(ref buffer, ref state)); } }
public static void ReadMessage(ref ParseContext ctx, IMessage message) { int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); ++ctx.state.recursionDepth; ReadRawMessage(ref ctx, message); CheckReadEndOfStreamTag(ref ctx.state); // Check that we've read exactly as much data as expected. if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) { throw InvalidProtocolBufferException.TruncatedMessage(); } --ctx.state.recursionDepth; SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); }
/// <summary> /// Skip a group. /// </summary> public static void SkipGroup(ref ReadOnlySpan <byte> buffer, ref ParserInternalState state, uint startGroupTag) { // Note: Currently we expect this to be the way that groups are read. We could put the recursion // depth changes into the ReadTag method instead, potentially... state.recursionDepth++; if (state.recursionDepth >= state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } uint tag; while (true) { tag = ParsingPrimitives.ParseTag(ref buffer, ref state); if (tag == 0) { throw InvalidProtocolBufferException.TruncatedMessage(); } // Can't call SkipLastField for this case- that would throw. if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup) { break; } // This recursion will allow us to handle nested groups. SkipLastField(ref buffer, ref state); } int startField = WireFormat.GetTagFieldNumber(startGroupTag); int endField = WireFormat.GetTagFieldNumber(tag); if (startField != endField) { throw new InvalidProtocolBufferException( $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}"); } state.recursionDepth--; }
public int ReadEnum() { // Currently just a pass-through, but it's nice to separate it logically from WriteInt32. return((int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state)); }
public static string ReadString(ref ReadOnlySpan <byte> buffer, ref ParserInternalState state) { int length = ParsingPrimitives.ParseLength(ref buffer, ref state); return(ParsingPrimitives.ReadRawString(ref buffer, ref state, length)); }
public static ByteString ReadBytes(ref ReadOnlySpan <byte> buffer, ref ParserInternalState state) { int length = ParsingPrimitives.ParseLength(ref buffer, ref state); return(ByteString.AttachBytes(ParsingPrimitives.ReadRawBytes(ref buffer, ref state, length))); }
public long ReadSInt64() { return(ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state))); }
public int ReadLength() { return((int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state)); }
public long ReadSFixed64() { return((long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state)); }
public int ReadSInt32() { return(ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state))); }
public float ReadFloat() { return(ParsingPrimitives.ParseFloat(ref buffer, ref state)); }
public double ReadDouble() { return(ParsingPrimitives.ParseDouble(ref buffer, ref state)); }
public uint ReadUInt32() { return(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state)); }
public ByteString ReadBytes() { return(ParsingPrimitives.ReadBytes(ref buffer, ref state)); }
public string ReadString() { return(ParsingPrimitives.ReadString(ref buffer, ref state)); }
public bool ReadBool() { return(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0); }
public long ReadInt64() { return((long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state)); }
public int ReadSFixed32() { return((int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state)); }
public uint ReadTag() { return(ParsingPrimitives.ParseTag(ref buffer, ref state)); }