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);
            }
        }
Exemple #4
0
        // +--------+--------+--+----------+-----------+-------------+-----------+------------+-------+
        // | 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;
            }
        }
Exemple #8
0
 public void WriteTo(Stream stream)
 {
     stream.Write7BitEncodedInt((ushort)ChunkType);
     stream.Write7BitEncodedInt(Version);
     stream.Write7BitEncodedInt(Size);
 }