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); } }
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); } }
/// <summary>Indicates the number of bytes expected for the next message.</summary> /// <param name="buffer">The buffer containing the data to investigate for a length.</param> /// <param name="index">The offset of the first byte to read from the buffer.</param> /// <param name="count">The number of bytes to read from the buffer.</param> /// <param name="style">The algorithm used to encode the length.</param> /// <param name="length">The length of the message, if it could be identified.</param> /// <returns>True if a length could be obtained, false otherwise.</returns> public static bool TryReadLengthPrefix(byte[] buffer, int index, int count, PrefixStyle style, out int length) { using (Stream source = new MemoryStream(buffer, index, count)) { uint len; bool result; switch (style) { case PrefixStyle.Fixed32: result = SerializationContext.TryDecodeUInt32Fixed(source, out len); break; case PrefixStyle.Base128: result = SerializationContext.TryDecodeUInt32Fixed(source, out len); break; default: throw new ArgumentOutOfRangeException("style", "Invalid prefix style: " + style); } length = (int)len; return(result); } }