/// <summary> /// 解析一个数据包 /// 不足一个封包时返回null /// </summary> /// <param name="stream">接收到的历史数据</param> /// <param name="packet">数据包</param> /// <returns></returns> public static bool Parse(IStreamReader stream, out FastPacket packet) { if (stream.Length < 1 || stream[0] != FastPacket.Mark) { packet = null; return(false); } if (stream.Length < 5) { packet = null; return(true); } stream.Position = 1; const int packetMinSize = 16; var totalBytes = stream.ReadInt32(); if (totalBytes < packetMinSize) { packet = null; return(false); } // 数据包未接收完整 if (stream.Length < totalBytes) { packet = null; return(true); } // api名称数据长度 var apiNameLength = stream.ReadByte(); if (totalBytes < apiNameLength + packetMinSize) { packet = null; return(false); } // api名称数据 var apiNameBytes = stream.ReadArray(apiNameLength); // 标识符 var id = stream.ReadInt64(); // 是否为客户端封包 var isFromClient = stream.ReadBoolean(); // 是否异常 var isException = stream.ReadBoolean(); // 实体数据 var body = stream.ReadArray(totalBytes - stream.Position); // 清空本条数据 stream.Clear(totalBytes); var apiName = Encoding.UTF8.GetString(apiNameBytes); packet = new FastPacket(apiName, id, isFromClient) { TotalBytes = totalBytes, ApiNameLength = apiNameLength, IsException = isException, Body = body }; return(true); }
private void ReadData(int dataTypeCd, WireMessage message, IStreamReader reader) { switch ((TypeCode)dataTypeCd) { case TypeCode.Boolean: message.Data = reader.ReadBoolean(); break; case TypeCode.Byte: message.Data = reader.ReadByte(); break; case TypeCode.Char: message.Data = reader.ReadChar(); break; case TypeCode.DateTime: message.Data = new DateTime(reader.ReadInt64()); break; case TypeCode.DBNull: reader.ReadByte(); message.Data = DBNull.Value; break; case TypeCode.Decimal: message.Data = reader.ReadDecimal(); break; case TypeCode.Double: message.Data = reader.ReadDouble(); break; case TypeCode.Empty: reader.ReadByte(); break; case TypeCode.Int16: message.Data = reader.ReadInt16(); break; case TypeCode.Int32: message.Data = reader.ReadInt32(); break; case TypeCode.Int64: message.Data = reader.ReadInt64(); break; case TypeCode.SByte: message.Data = reader.ReadSByte(); break; case TypeCode.Single: message.Data = reader.ReadSingle(); break; case TypeCode.String: message.Data = ReadString(reader); break; case TypeCode.UInt16: message.Data = reader.ReadUInt16(); break; case TypeCode.UInt32: message.Data = reader.ReadUInt32(); break; case TypeCode.UInt64: message.Data = reader.ReadUInt64(); break; default: { var len = reader.ReadInt32(); if (len > 0) { using (var tempStream = new ChunkedStream()) { var chunkSize = tempStream.ChunkSize; while (len > 0) { var bytes = reader.ReadBytes(chunkSize); var readLen = bytes?.Length ?? 0; if (readLen == 0) { throw new Exception(SerializationErrors.StreamNotContainingValidWireMessage); } len -= readLen; tempStream.Write(bytes, 0, readLen); } tempStream.Position = 0; message.Data = GetSerializer().Deserialize(tempStream); } } } break; } }