/// <summary>Indicates the number of bytes expected for the next message.</summary> /// <param name="source">The stream containing the data to investigate for a length.</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(Stream source, PrefixStyle style, out int length) { int fieldNumber, bytesRead; length = ProtoReader.ReadLengthPrefix(source, false, style, out fieldNumber, out bytesRead); return(bytesRead > 0); }
public void Process() { try { if (client == null || !client.Connected) { return; } if (LengthPrefix == 0) { if (this.client.Available >= 4) { int fieldNumber; LengthPrefix = ProtoReader.ReadLengthPrefix(stream, false, PrefixStyle.Fixed32, out fieldNumber); } } else { if (this.client.Available >= LengthPrefix) { ProcessMessage(LengthPrefix); LengthPrefix = 0; } } } catch (ProtoException e) { Debug.Log("Recv ERROR >>> " + e); Close(); } }
public static bool TryReadLengthPrefix(Stream source, PrefixStyle style, out int length) { int num; int num2; length = ProtoReader.ReadLengthPrefix(source, false, style, out num, out num2); return(num2 > 0); }
protected void Handle() { readBuffer_.Seek(0, SeekOrigin.Begin); if (readBuffer_.Length < controller_proto_length_) { lack_length_ = controller_proto_length_ - (int)readBuffer_.Length; return; } int fieldNumber; int len = ProtoReader.ReadLengthPrefix(readBuffer_, false, PrefixStyle.Fixed32BigEndian, out fieldNumber); if (len > readBuffer_.Length - controller_proto_length_) { lack_length_ = len + controller_proto_length_ - (int)readBuffer_.Length; readBuffer_.Seek(0, SeekOrigin.Begin); return; } else { lack_length_ = controller_proto_length_; } Controller controller = new Controller(); controller.channel = this; controller.proto = serializer_.Deserialize(readBuffer_, null, typeof(ControllerProto), len) as ControllerProto; proto_ = controller.proto; // swap buffer readBufferBack_.Seek(0, SeekOrigin.Begin); readBufferBack_.SetLength(0); readBufferBack_.Write(readBuffer_.ToArray(), (int)readBuffer_.Position, (int)(readBuffer_.Length - readBuffer_.Position)); //WARN: may cause something bad MemoryStream ms = readBuffer_; readBuffer_ = readBufferBack_; readBufferBack_ = ms; string fullMethodName = controller.proto.full_service_name + "." + controller.proto.method_name; if (controller.proto.stub) { if (handleRequestFunc_.ContainsKey(fullMethodName)) { handleRequestFunc_[fullMethodName](controller); } } else { if (handleResponseFunc_.ContainsKey(fullMethodName)) { handleResponseFunc_[fullMethodName](controller); } } }
public void Execute() { using var ms = new MemoryStream(); // write data with a length-prefix but no field number Serializer.SerializeWithLengthPrefix(ms, new Foo { Bar = 1 }, PrefixStyle.Base128, 0); Serializer.SerializeWithLengthPrefix(ms, new Foo { Bar = 2 }, PrefixStyle.Base128, 0); Serializer.SerializeWithLengthPrefix(ms, new Foo { Bar = 3 }, PrefixStyle.Base128, 0); ms.Position = 0; Assert.Equal(9, ms.Length); //, "3 lengths, 3 headers, 3 values"); // read the length prefix and use that to limit each call TypeModel model = RuntimeTypeModel.Default; int bytesRead; List <Foo> foos = new List <Foo>(); do { var len = ProtoReader.ReadLengthPrefix(ms, false, PrefixStyle.Base128, out var fieldNumber, out bytesRead); if (bytesRead <= 0) { continue; } #pragma warning disable CS0618 foos.Add((Foo)model.Deserialize(ms, null, typeof(Foo), len)); #pragma warning restore CS0618 Assert.True(foos.Count <= 3, "too much data! (manual)"); } while (bytesRead > 0); Assert.Equal(3, foos.Count); Assert.Equal(1, foos[0].Bar); Assert.Equal(2, foos[1].Bar); Assert.Equal(3, foos[2].Bar); // do it using DeserializeItems ms.Position = 0; foos.Clear(); foreach (var obj in model.DeserializeItems <Foo>(ms, PrefixStyle.Base128, 0)) { foos.Add(obj); Assert.True(foos.Count <= 3, "too much data! (foreach)"); } Assert.Equal(3, foos.Count); Assert.Equal(1, foos[0].Bar); Assert.Equal(2, foos[1].Bar); Assert.Equal(3, foos[2].Bar); }
public void Execute() { using (var ms = new MemoryStream()) { // write data with a length-prefix but no field number var tm = TypeModel.Create(false, ProtoCompatibilitySettingsValue.FullCompatibility); tm.SerializeWithLengthPrefix(ms, new Foo { Bar = 1 }, typeof(Foo), PrefixStyle.Base128, 0); tm.SerializeWithLengthPrefix(ms, new Foo { Bar = 2 }, typeof(Foo), PrefixStyle.Base128, 0); tm.SerializeWithLengthPrefix(ms, new Foo { Bar = 3 }, typeof(Foo), PrefixStyle.Base128, 0); ms.Position = 0; Assert.AreEqual(9, ms.Length, "3 lengths, 3 headers, 3 values"); // read the length prefix and use that to limit each call int len, fieldNumber, bytesRead; List <Foo> foos = new List <Foo>(); do { len = ProtoReader.ReadLengthPrefix(ms, false, PrefixStyle.Base128, out fieldNumber, out bytesRead); if (bytesRead <= 0) { continue; } foos.Add((Foo)tm.Deserialize(ms, null, typeof(Foo), len)); Assert.IsTrue(foos.Count <= 3, "too much data! (manual)"); } while (bytesRead > 0); Assert.AreEqual(3, foos.Count); Assert.AreEqual(1, foos[0].Bar); Assert.AreEqual(2, foos[1].Bar); Assert.AreEqual(3, foos[2].Bar); // do it using DeserializeItems ms.Position = 0; foos.Clear(); foreach (var obj in tm.DeserializeItems <Foo>(ms, PrefixStyle.Base128, 0)) { foos.Add(obj); Assert.IsTrue(foos.Count <= 3, "too much data! (foreach)"); } Assert.AreEqual(3, foos.Count); Assert.AreEqual(1, foos[0].Bar); Assert.AreEqual(2, foos[1].Bar); Assert.AreEqual(3, foos[2].Bar); } }
/// <summary> /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed /// data - useful with network IO. /// </summary> /// <param name="type">The type being merged.</param> /// <param name="value">The existing instance to be modified (can be null).</param> /// <param name="source">The binary stream to apply to the instance (cannot be null).</param> /// <param name="style">How to encode the length prefix.</param> /// <param name="expectedField">The tag used as a prefix to each record (only used with base-128 style prefixes).</param> /// <param name="resolver">Used to resolve types on a per-field basis.</param> /// <param name="bytesRead">Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data).</param> /// <returns>The updated instance; this may be different to the instance argument if /// either the original instance was null, or the stream defines a known sub-type of the /// original instance.</returns> public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, int expectedField, Serializer.TypeResolver resolver, out int bytesRead) { bool skip; int len; int tmpBytesRead; bytesRead = 0; do { int actualField; bool expectPrefix = expectedField > 0 || resolver != null; len = ProtoReader.ReadLengthPrefix(source, expectPrefix, style, out actualField, out tmpBytesRead); bytesRead += tmpBytesRead; if (len < 0) { return(value); } if (expectedField == 0 && type == null && resolver != null) { type = resolver(actualField); skip = type == null; } else { skip = expectedField != actualField; } if (skip) { if (len == int.MaxValue) { throw new InvalidOperationException(); } ProtoReader.Seek(source, len, null); bytesRead += len; } } while (skip); int key = GetKey(ref type); if (key < 0) { throw new InvalidOperationException(); } using (ProtoReader reader = new ProtoReader(source, this, len)) { object result = Deserialize(key, value, reader); bytesRead += reader.Position; return(result); } }
private bool TryReadHeader(Stream s, out int length) { length = ProtoReader.ReadLengthPrefix(s, true, PrefixStyle.Base128, out int fieldNumber, out int bytesRead); if (bytesRead == 0) { length = 0; return(false); } if (fieldNumber != TypeModel.ListItemTag) { throw new StreamSerializationException($"invalid proto item tag found: {fieldNumber}, expected {TypeModel.ListItemTag}"); } return(true); }
public void ReadLengthPrefixProducesCorrectLengthComparedToStreamPosition() { byte[] bytes = null; const int arraySize = 7000 * 100; using (MemoryStream stream = new MemoryStream(arraySize)) { Serializer.SerializeWithLengthPrefix(stream, new Issue374TestModel(new byte[arraySize]), PrefixStyle.Base128); bytes = stream.ToArray(); } using (MemoryStream stream = new MemoryStream(bytes)) { ProtoReader.ReadLengthPrefix(stream, false, PrefixStyle.Base128, out int fieldNumber, out int bytesRead); //These should be the same. They don't appear to be with the fault raised in issue 374 Assert.Equal(stream.Position, bytesRead); } }
void Process() { long currentTicks = DateTime.Now.Ticks; int LengthPrefix = 0; while (true && !cerrado) { Thread.Sleep(0); try { if (LengthPrefix == 0) { if (this.client.Available >= 4) { int fieldNumber; LengthPrefix = ProtoReader.ReadLengthPrefix(stream, false, PrefixStyle.Fixed32, out fieldNumber); } } else { if (this.client.Available >= LengthPrefix) { ProcessMessage(LengthPrefix); LengthPrefix = 0; } } currentTicks = currentTicks = DateTime.Now.Ticks; if (currentTicks - lastKA > 100000000L) { MessageTest1 msgKA = new MessageTest1 { secuencia = secuencia++ }; Send(msgKA); lastKA = currentTicks; } } catch (ProtoException e) { Console.WriteLine("Process >>> " + e); Close(); } } }
private void DecodeMsg(byte[] receiveBytes, int size) { _recMsgBuf.SetPosition(_recMsgBuf.Length()); _recMsgBuf.Put(receiveBytes, size); _recMsgBuf.Flip(); int minCheckLength = MessageConfig.BODY_SIZE_LENGTH; while (_recMsgBuf.Remaining() >= minCheckLength) { _recMsgBuf.SetPosition(minCheckLength - MessageConfig.BODY_SIZE_LENGTH); int fieldNumber, headLen; int bodyLen = ProtoReader.ReadLengthPrefix(_recMsgBuf.getStream(), false, PrefixStyle.Base128, out fieldNumber, out headLen); if (bodyLen <= 0) { break; } if (_recMsgBuf.Remaining() >= bodyLen) { _recMsgBuf.Flip(); long position = _recMsgBuf.Position(); int dataLen = headLen + bodyLen; object data = _decoder.Decode(_recMsgBuf.GetBuffer(), (int)position, dataLen); // byte[] data = new byte[minCheckLength + bodyLen]; // _recMsgBuf.Get(data); _recMsgs.Enqueue(data); _recMsgBuf.SetPosition(position + dataLen); _recMsgBuf.Compact(); _recMsgBuf.Flip(); } else { break; } } }
private object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, int expectedField, Serializer.TypeResolver resolver, out int bytesRead, out bool haveObject, SerializationContext context) { haveObject = false; bytesRead = 0; if (type == null && (style != PrefixStyle.Base128 || resolver == null)) { throw new InvalidOperationException("A type must be provided unless base-128 prefixing is being used in combination with a resolver"); } int num; bool flag2; do { bool flag = expectedField > 0 || resolver != null; num = ProtoReader.ReadLengthPrefix(source, flag, style, out int fieldNumber, out int bytesRead2); if (bytesRead2 == 0) { return(value); } bytesRead += bytesRead2; if (num < 0) { return(value); } if (style == PrefixStyle.Base128) { if (flag && expectedField == 0 && type == null && resolver != null) { type = resolver(fieldNumber); flag2 = (type == null); } else { flag2 = (expectedField != fieldNumber); } } else { flag2 = false; } if (flag2) { if (num == int.MaxValue) { throw new InvalidOperationException(); } ProtoReader.Seek(source, num, null); bytesRead += num; } }while (flag2); ProtoReader protoReader = null; try { protoReader = ProtoReader.Create(source, this, context, num); int key = GetKey(ref type); if (key >= 0 && !Helpers.IsEnum(type)) { value = Deserialize(key, value, protoReader); } else if (!TryDeserializeAuxiliaryType(protoReader, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: true, insideList: false) && num != 0) { ThrowUnexpectedType(type); } bytesRead += protoReader.Position; haveObject = true; return(value); } finally { ProtoReader.Recycle(protoReader); } }
private object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, int expectedField, Serializer.TypeResolver resolver, out int bytesRead, out bool haveObject, SerializationContext context) { haveObject = false; bytesRead = 0; if (type == null && (style != PrefixStyle.Base128 || resolver == null)) { throw new InvalidOperationException("A type must be provided unless base-128 prefixing is being used in combination with a resolver"); } while (true) { bool expectPrefix = expectedField > 0 || resolver != null; int actualField; int tmpBytesRead; int len = ProtoReader.ReadLengthPrefix(source, expectPrefix, style, out actualField, out tmpBytesRead); if (tmpBytesRead == 0) { break; } bytesRead += tmpBytesRead; if (len < 0) { return(value); } bool skip; if (style == PrefixStyle.Base128) { if (expectPrefix && expectedField == 0 && type == null && resolver != null) { type = resolver(actualField); skip = (type == null); } else { skip = (expectedField != actualField); } } else { skip = false; } if (skip) { if (len == 2147483647) { goto Block_12; } ProtoReader.Seek(source, len, null); bytesRead += len; } if (!skip) { goto Block_13; } } return(value); Block_12: throw new InvalidOperationException(); Block_13: ProtoReader reader = null; object result; try { int len; reader = ProtoReader.Create(source, this, context, len); int key = this.GetKey(ref type); if (key >= 0 && !Helpers.IsEnum(type)) { value = this.Deserialize(key, value, reader); } else { if (!this.TryDeserializeAuxiliaryType(reader, DataFormat.Default, 1, type, ref value, true, false, true, false) && len != 0) { TypeModel.ThrowUnexpectedType(type); } } bytesRead += reader.Position; haveObject = true; result = value; } finally { ProtoReader.Recycle(reader); } return(result); }
private object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, int expectedField, ProtobufSerializer.TypeResolver resolver, out int bytesRead, out bool haveObject, SerializationContext context) { bool flag; int num; haveObject = false; bytesRead = 0; if ((type == null) && ((style != PrefixStyle.Base128) || (resolver == null))) { throw new InvalidOperationException("A type must be provided unless base-128 prefixing is being used in combination with a resolver"); } do { int num2; int num3; bool expectHeader = (expectedField > 0) || (resolver != null); num = ProtoReader.ReadLengthPrefix(source, expectHeader, style, out num3, out num2); if (num2 == 0) { return(value); } bytesRead += num2; if (num < 0) { return(value); } if (style == PrefixStyle.Base128) { if ((expectHeader && (expectedField == 0)) && ((type == null) && (resolver != null))) { type = resolver(num3); flag = type == null; } else { flag = expectedField != num3; } } else { flag = false; } if (flag) { if (num == 0x7fffffff) { throw new InvalidOperationException(); } ProtoReader.Seek(source, num, null); bytesRead += num; } }while (flag); using (ProtoReader reader = new ProtoReader(source, this, context, num)) { int key = this.GetKey(ref type); if ((key >= 0) && !Helpers.IsEnum(type)) { value = this.Deserialize(key, value, reader); } else if (!this.TryDeserializeAuxiliaryType(reader, DataFormat.Default, 1, type, ref value, true, false, true, false) && (num != 0)) { ThrowUnexpectedType(type); } bytesRead += reader.Position; haveObject = true; return(value); } }