private void WriteType(Stream stream, Type type) { var messageTypeAlias = _typeTable.GetAlias(type); if (messageTypeAlias != 0) { // Write big endian var bytes = BitConverter.GetBytes(messageTypeAlias); stream.WriteByte(bytes[3]); stream.WriteByte(bytes[2]); stream.WriteByte(bytes[1]); stream.WriteByte(bytes[0]); } else { // Write string with length 0x80 for making msb of first byte set var name = type.AssemblyQualifiedName; var bytes = Encoding.UTF8.GetBytes(name); stream.Write7BitEncodedInt(0x80 + bytes.Length); stream.Write(bytes, 0, bytes.Length); } }
public void WriteTo(Stream stream) { stream.Write7BitEncodedInt((ushort)ChunkType); stream.Write7BitEncodedInt(Version); stream.Write7BitEncodedInt(Size); }
// +--------+--------+--+----------+-----------+-------------+-----------+------------+-------+ // | LEN(4) | CRC(4) |H1| ID (1~6) | AID (1~6) | M_SIG (1~6) | M_LEN (4) | M_DATA (~) | E (~) | // +--------+--------+--+----------+-----------+-------------+-----------+------------+-------+ // H=[ME....TT] T=Type, M=Message?, E=Exception? // ID=RequestId, AID=ActorId, M=Message, E=Exception public void Serialize(Stream stream, object packet) { var p = (Packet)packet; // Jump 8 Bytes for writing Length | Checksum var packetLengthMarker = new StreamLengthMarker(stream, false); stream.Seek(8, SeekOrigin.Current); // Write Packet Header var header = (byte)((byte)(p.Type) | (byte)(p.Message != null ? 0x80 : 0) | (byte)(p.Exception != null ? 0x40 : 0)); stream.WriteByte(header); stream.Write7BitEncodedInt(p.ActorId); stream.Write7BitEncodedInt(p.RequestId); // Write Message if (p.Message != null) { if (p.Type == PacketType.System) { // System message: Always string. stream.WriteString((string)p.Message); } else { // User message: Length, Signature, and Data var messageTypeAlias = _data.TypeTable.GetAlias(p.Message.GetType()); stream.Write7BitEncodedInt(messageTypeAlias); var messageLengthMarker = new StreamLengthMarker(stream, true); _data.MessageSerializer.Serialize(stream, p.Message); messageLengthMarker.WriteLength(true); } } // Write Exception if (p.Exception != null) { _exceptionSerializer.Serialize(stream, p.Exception); } // Write Length packetLengthMarker.WriteLength(false); // Encrypt and Calc Checksum ArraySegment<byte> s0, s1; GetBuffers(stream, (int)packetLengthMarker.StartPosition + 8, packetLengthMarker.Length - 4, out s0, out s1); var ctx = new EncryptContext { Key = _serializeWrapKey }; Encrypt(s0.Array, s0.Offset, s0.Array, s0.Offset, s0.Count, ref ctx); Encrypt(s1.Array, s1.Offset, s1.Array, s1.Offset, s1.Count, ref ctx); if (_serializeWrapKey != 0) { _serializeWrapKey += 1; if (_serializeWrapKey == 0) _serializeWrapKey = 1; } // Write Checksum var hashBytes = BitConverter.GetBytes(ctx.Hash); stream.Write(hashBytes, 0, hashBytes.Length); // End of stream, again. stream.Seek(packetLengthMarker.EndPosition, SeekOrigin.Begin); // Pending WrapKey if (_serializeWrapPendingKey != 0) { _serializeWrapKey = _serializeWrapPendingKey; _serializeWrapPendingKey = 0; } }