private static bool TryReadPrefixLength(Stream source, PrefixStyle style, int tag, out uint length, Getter <int, bool> processField) { MethodStart: switch (style) { case PrefixStyle.None: length = uint.MaxValue; return(true); case PrefixStyle.Base128: if (tag <= 0) { return(SerializationContext.TryDecodeUInt32(source, out length)); } uint expected = GetFieldToken(tag, WireType.String), actual; if (!SerializationContext.TryDecodeUInt32(source, out actual)) { length = 0; return(false); } WireType wireType; int actualTag; ParseFieldToken(actual, out wireType, out actualTag); if (processField != null) { if (processField(actualTag)) { length = SerializationContext.DecodeUInt32(source); return(true); } } else if (expected == actual) { length = SerializationContext.DecodeUInt32(source); return(true); } switch (wireType) { case WireType.String: SerializationContext.SkipStringData(source); goto MethodStart; default: throw new ProtoException("A record with a different tag could not be jumped because of the wire-type: " + wireType); } case PrefixStyle.Fixed32: return(SerializationContext.TryDecodeUInt32Fixed(source, out length)); default: throw new NotSupportedException("Invalid prefix style: " + style); } }
/// <summary> /// Jump a block of data using a base-128 length prefix. /// </summary> /// <param name="source">The input stream.</param> public static void SkipStringData(Stream source) { int bytesRead, bytesRemaining = (int)SerializationContext.DecodeUInt32(source); while (bytesRemaining > trashBuffer.Length && (bytesRead = source.Read(trashBuffer, 0, trashBuffer.Length)) > 0) { bytesRemaining -= bytesRead; } while (bytesRemaining > 0 && (bytesRead = source.Read(trashBuffer, 0, bytesRemaining)) > 0) { bytesRemaining -= bytesRead; } if (bytesRemaining != 0) { throw new EndOfStreamException(); } }
private static bool TryReadPrefixLength(SerializationContext context, PrefixStyle style, int tag, out uint length) { MethodStart: switch (style) { case PrefixStyle.None: length = uint.MaxValue; return(true); case PrefixStyle.Base128: if (tag <= 0) { return(context.TryDecodeUInt32(out length)); } uint expected = GetFieldToken(tag, WireType.String), actual; if (!context.TryDecodeUInt32(out actual)) { length = 0; return(false); } if (expected == actual) { length = context.DecodeUInt32(); return(true); } WireType wireType; int actualTag; ParseFieldToken(actual, out wireType, out actualTag); SkipData(context, actualTag, wireType); goto MethodStart; case PrefixStyle.Fixed32: return(context.TryDecodeUInt32Fixed(out length)); default: throw new NotSupportedException("Invalid prefix style: " + style); } }