/// <summary> /// Decode a value of the given type. /// Should not be called directly. This interface is used by service client stubs. /// </summary> public static object Decode(ByteString value, Type type, Connection client) { var stream = new CodedInputStream (value.ToByteArray ()); if (type == typeof(double)) return stream.ReadDouble (); else if (type == typeof(float)) return stream.ReadFloat (); else if (type == typeof(int)) return stream.ReadInt32 (); else if (type == typeof(long)) return stream.ReadInt64 (); else if (type == typeof(uint)) return stream.ReadUInt32 (); else if (type == typeof(ulong)) return stream.ReadUInt64 (); else if (type == typeof(bool)) return stream.ReadBool (); else if (type == typeof(string)) return stream.ReadString (); else if (type == typeof(byte[])) return stream.ReadBytes ().ToByteArray (); else if (type.IsEnum) return stream.ReadInt32 (); else if (typeof(RemoteObject).IsAssignableFrom (type)) { if (client == null) throw new ArgumentException ("Client not passed when decoding remote object"); var id = stream.ReadUInt64 (); if (id == 0) return null; return (RemoteObject)Activator.CreateInstance (type, client, id); } else if (typeof(IMessage).IsAssignableFrom (type)) { IMessage message = (IMessage)Activator.CreateInstance (type); message.MergeFrom (stream); return message; } else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof(IList<>)) return DecodeList (value, type, client); else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof(IDictionary<,>)) return DecodeDictionary (value, type, client); else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof(ISet<>)) return DecodeSet (value, type, client); else if (type.IsGenericType && (type.GetGenericTypeDefinition () == typeof(Tuple<>) || type.GetGenericTypeDefinition () == typeof(Tuple<,>) || type.GetGenericTypeDefinition () == typeof(Tuple<,,>) || type.GetGenericTypeDefinition () == typeof(Tuple<,,,>) || type.GetGenericTypeDefinition () == typeof(Tuple<,,,,>) || type.GetGenericTypeDefinition () == typeof(Tuple<,,,,,>))) return DecodeTuple (value, type, client); // TODO: ugly handing of tuple types throw new ArgumentException (type + " is not a serializable type"); }
public IMessage Decode(byte[] msg) { IMessage message = null; CodedInputStream stream = new CodedInputStream(msg); //data length,Protobuf 变长头, 也就是消息长度 int varint32 = (int)stream.ReadInt32(); if (varint32 <= (msg.Length - (int)stream.Position)) { try { byte[] body = stream.ReadRawBytes(varint32); message = Message.Parser.ParseFrom(body); } catch (Exception exception) { //"[ProtobufEncoding] Decode exception :{0}", exception.Message); } } else { //"网络数据读取不完整,丢包了?"); } return(message); }
/// <summary> /// 将数据解码 /// </summary> public void DecodeAsync(byte[] msg) { if (msg.Length <= 0) { return; } if (buffer.Data == null) { buffer.Data = new byte[8192]; } //把收取上来的自己全部缓存到本地 buffer 中 Array.Copy(msg, 0, buffer.Data, buffer.Length, msg.Length); buffer.Length += msg.Length; //string.Format("cache buff length: {0}, offset: {1}", buffer.Length, buffer.Offset)); CodedInputStream stream = new CodedInputStream(buffer.Data); while (!stream.IsAtEnd) { //标记读取的Position, 在长度不够时进行数组拷贝,到下一次在进行解析 int markReadIndex = (int)stream.Position; //data length,Protobuf 变长头, 也就是消息长度 int varint32 = (int)stream.ReadInt32(); if (varint32 <= (buffer.Length - (int)stream.Position)) { try { byte[] body = stream.ReadRawBytes(varint32); Message message = Message.Parser.ParseFrom(body); SocketManager.Instance.DispatchProto(message); //TODO: dispatcher message, 这里就可以用多线程进行协议分发 } catch (Exception exception) { //exception.Message); } } else { //本次数据不够长度,缓存进行下一次解析 byte[] dest = new byte[8192]; int remainSize = buffer.Length - markReadIndex; Array.Copy(buffer.Data, markReadIndex, dest, 0, remainSize); /** * 缓存未处理完的字节 */ buffer.Data = dest; buffer.Offset = 0; buffer.Length = remainSize; break; } } }
public void MergeFrom(CodedInputStream input) { while (true) { IL_D9: uint num; uint arg_9E_0 = ((num = input.ReadTag()) != 0u) ? 123760098u : 340881777u; while (true) { uint num2; switch ((num2 = (arg_9E_0 ^ 2069247364u)) % 8u) { case 0u: input.SkipLastField(); arg_9E_0 = (num2 * 3109966835u ^ 1634015013u); continue; case 1u: goto IL_D9; case 2u: this.End = input.ReadInt32(); arg_9E_0 = 651504541u; continue; case 3u: this.Start = input.ReadInt32(); arg_9E_0 = 651504541u; continue; case 4u: arg_9E_0 = (((num == 16u) ? 3653100894u : 3502071340u) ^ num2 * 176730384u); continue; case 6u: arg_9E_0 = ((num != 8u) ? 730284952u : 1349205327u); continue; case 7u: arg_9E_0 = 123760098u; continue; } return; } } }
public void TestCodedInputOutputPosition() { byte[] content = new byte[110]; for (int i = 0; i < content.Length; i++) { content[i] = (byte)i; } byte[] child = new byte[120]; { MemoryStream ms = new MemoryStream(child); CodedOutputStream cout = new CodedOutputStream(ms, 20); // Field 11: numeric value: 500 cout.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 12: length delimited 120 bytes cout.WriteTag(12, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(content)); Assert.AreEqual(115, cout.Position); // Field 13: fixed numeric value: 501 cout.WriteTag(13, WireFormat.WireType.Fixed32); Assert.AreEqual(116, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(120, cout.Position); cout.Flush(); } byte[] bytes = new byte[130]; { CodedOutputStream cout = new CodedOutputStream(bytes); // Field 1: numeric value: 500 cout.WriteTag(1, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 2: length delimited 120 bytes cout.WriteTag(2, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(child)); Assert.AreEqual(125, cout.Position); // Field 3: fixed numeric value: 500 cout.WriteTag(3, WireFormat.WireType.Fixed32); Assert.AreEqual(126, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(130, cout.Position); cout.Flush(); } // Now test Input stream: { CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0); Assert.AreEqual(0, cin.Position); // Field 1: uint tag = cin.ReadTag(); Assert.AreEqual(1, tag >> 3); Assert.AreEqual(1, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(3, cin.Position); //Field 2: tag = cin.ReadTag(); Assert.AreEqual(2, tag >> 3); Assert.AreEqual(4, cin.Position); int childlen = cin.ReadLength(); Assert.AreEqual(120, childlen); Assert.AreEqual(5, cin.Position); int oldlimit = cin.PushLimit((int)childlen); Assert.AreEqual(5, cin.Position); // Now we are reading child message { // Field 11: numeric value: 500 tag = cin.ReadTag(); Assert.AreEqual(11, tag >> 3); Assert.AreEqual(6, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(8, cin.Position); //Field 12: length delimited 120 bytes tag = cin.ReadTag(); Assert.AreEqual(12, tag >> 3); Assert.AreEqual(9, cin.Position); ByteString bstr = cin.ReadBytes(); Assert.AreEqual(110, bstr.Length); Assert.AreEqual((byte)109, bstr[109]); Assert.AreEqual(120, cin.Position); // Field 13: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(13, tag >> 3); // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit Assert.AreEqual(121, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(125, cin.Position); Assert.IsTrue(cin.IsAtEnd); } cin.PopLimit(oldlimit); Assert.AreEqual(125, cin.Position); // Field 3: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(3, tag >> 3); Assert.AreEqual(126, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(130, cin.Position); Assert.IsTrue(cin.IsAtEnd); } }
public void TestCodedInputOutputPosition() { byte[] content = new byte[110]; for (int i = 0; i < content.Length; i++) content[i] = (byte)i; byte[] child = new byte[120]; { MemoryStream ms = new MemoryStream(child); CodedOutputStream cout = new CodedOutputStream(ms, 20); // Field 11: numeric value: 500 cout.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 12: length delimited 120 bytes cout.WriteTag(12, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(content)); Assert.AreEqual(115, cout.Position); // Field 13: fixed numeric value: 501 cout.WriteTag(13, WireFormat.WireType.Fixed32); Assert.AreEqual(116, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(120, cout.Position); cout.Flush(); } byte[] bytes = new byte[130]; { CodedOutputStream cout = new CodedOutputStream(bytes); // Field 1: numeric value: 500 cout.WriteTag(1, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 2: length delimited 120 bytes cout.WriteTag(2, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(child)); Assert.AreEqual(125, cout.Position); // Field 3: fixed numeric value: 500 cout.WriteTag(3, WireFormat.WireType.Fixed32); Assert.AreEqual(126, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(130, cout.Position); cout.Flush(); } // Now test Input stream: { CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0); Assert.AreEqual(0, cin.Position); // Field 1: uint tag = cin.ReadTag(); Assert.AreEqual(1, tag >> 3); Assert.AreEqual(1, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(3, cin.Position); //Field 2: tag = cin.ReadTag(); Assert.AreEqual(2, tag >> 3); Assert.AreEqual(4, cin.Position); int childlen = cin.ReadLength(); Assert.AreEqual(120, childlen); Assert.AreEqual(5, cin.Position); int oldlimit = cin.PushLimit((int)childlen); Assert.AreEqual(5, cin.Position); // Now we are reading child message { // Field 11: numeric value: 500 tag = cin.ReadTag(); Assert.AreEqual(11, tag >> 3); Assert.AreEqual(6, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(8, cin.Position); //Field 12: length delimited 120 bytes tag = cin.ReadTag(); Assert.AreEqual(12, tag >> 3); Assert.AreEqual(9, cin.Position); ByteString bstr = cin.ReadBytes(); Assert.AreEqual(110, bstr.Length); Assert.AreEqual((byte) 109, bstr[109]); Assert.AreEqual(120, cin.Position); // Field 13: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(13, tag >> 3); // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit Assert.AreEqual(121, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(125, cin.Position); Assert.IsTrue(cin.IsAtEnd); } cin.PopLimit(oldlimit); Assert.AreEqual(125, cin.Position); // Field 3: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(3, tag >> 3); Assert.AreEqual(126, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(130, cin.Position); Assert.IsTrue(cin.IsAtEnd); } }
internal int <ForInt32> b__3_0(CodedInputStream input) { return(input.ReadInt32()); }
/// <summary> /// Convert a Protocol Buffer value type, encoded as a byte string, to a C# value. /// </summary> public static object ReadValue(ByteString value, Type type) { if (value.Length == 0) throw new ArgumentException ("Value is empty"); var stream = new CodedInputStream (value.ToByteArray ()); if (type == typeof(double)) { return stream.ReadDouble (); } else if (type == typeof(float)) { return stream.ReadFloat (); } else if (type == typeof(int)) { return stream.ReadInt32 (); } else if (type == typeof(long)) { return stream.ReadInt64 (); } else if (type == typeof(uint)) { return stream.ReadUInt32 (); } else if (type == typeof(ulong)) { return stream.ReadUInt64 (); } else if (type == typeof(bool)) { return stream.ReadBool (); } else if (type == typeof(string)) { return stream.ReadString (); } else if (type == typeof(byte[])) { return stream.ReadBytes ().ToByteArray(); } throw new ArgumentException (type + " is not a Protocol Buffer value type"); }