public static void WriteString(this Stream stream, string value) { if (value == null) { stream.Write7BitEncodedInt(0); return; } var bytes = Encoding.UTF8.GetBytes(value); stream.Write7BitEncodedInt(value.Length + 1); stream.Write(bytes, 0, bytes.Length); }
/// <summary> /// Writes byte count prefixed encoded text into the file. Byte count is written as 7-bit encoded 32-bit int. /// If no encoding is specified, UTF-8 will be used. Byte count prefix specifies number of bytes taken up by /// the string, not length of the string itself. /// Note that this method may allocate if the size of encoded string exceeds size of prepared buffer. /// </summary> public static void WriteNoAlloc(this Stream stream, string text, Encoding encoding = null) { encoding = encoding ?? Encoding.UTF8; int byteCount = encoding.GetByteCount(text); stream.Write7BitEncodedInt(byteCount); var buffer = Buffer; if (byteCount > buffer.Length) { // mk:TODO: Make this work even when encoded string has to be written in parts (prepared buffer is not large enough). buffer = new byte[byteCount]; } int bytesWritten = encoding.GetBytes(text, 0, text.Length, buffer, 0); Debug.Assert(bytesWritten == byteCount); stream.Write(buffer, 0, bytesWritten); }
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); } }
// +--------+--------+--+----------+-----------+-------------+-----------+------------+-------+ // | 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; } }
public void WriteTo(Stream stream) { stream.Write7BitEncodedInt((ushort)ChunkType); stream.Write7BitEncodedInt(Version); stream.Write7BitEncodedInt(Size); }
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); } }
// +--------+--------+--+----------+-----------+-------------+-----------+------------+-------+ // | 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; } }
public void WriteTo(Stream stream) { stream.Write7BitEncodedInt((ushort)ChunkType); stream.Write7BitEncodedInt(Version); stream.Write7BitEncodedInt(Size); }