using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using ZeroLevel.Services.Extensions; namespace ZeroLevel.Services.Serialization { /// /// Обертка над MemoryStream для записи /// public sealed class MemoryStreamWriter : IBinaryWriter { public Stream Stream { get { return _stream; } } private readonly MemoryStream _stream; public MemoryStreamWriter() { _stream = new MemoryStream(); } /// /// Запись булевого значения (1 байт) /// public void WriteBoolean(bool val) { _stream.WriteByte(BitConverter.GetBytes(val)[0]); } /// /// Запись байта (1 байт) /// public void WriteByte(byte val) { _stream.WriteByte(val); } /// /// Запись байт массива /// /// public void WriteBytes(byte[] val) { if (val == null) { WriteInt32(0); } else { WriteInt32(val.Length); _stream.Write(val, 0, val.Length); } } /// /// Запись целого 32-хбитного числа (4 байта) /// public void WriteInt32(Int32 number) { _stream.Write(BitConverter.GetBytes(number), 0, 4); } /// /// Запись целого 64-хбитного числа (8 байт) /// public void WriteLong(Int64 number) { _stream.Write(BitConverter.GetBytes(number), 0, 8); } public void WriteTimeSpan(TimeSpan period) { WriteLong(period.Ticks); } public void WriteDecimal(Decimal number) { _stream.Write(BitConverterExt.GetBytes(number), 0, 16); } public void WriteDouble(double val) { _stream.Write(BitConverter.GetBytes(val), 0, 8); } /// /// Запись строки (4 байта на длину + Length байт) /// public void WriteString(string line) { if (line == null) { WriteInt32(0); } else { var buffer = Encoding.UTF8.GetBytes(line); WriteInt32(buffer.Length); _stream.Write(buffer, 0, buffer.Length); } } /// /// Запись GUID (16 байт) /// public void WriteGuid(Guid guid) { _stream.Write(guid.ToByteArray(), 0, 16); } /// /// Запись даты времени /// /// public void WriteDateTime(DateTime? datetime) { if (datetime == null) { WriteByte(0); } else { WriteByte(1); long serialized = datetime.Value.ToBinary(); byte[] data = BitConverter.GetBytes(serialized); _stream.Write(data, 0, 8); } } public void WriteIP(IPAddress ip) { WriteLong(ip.Address); } public void WriteIPEndpoint(IPEndPoint endpoint) { WriteLong(endpoint.Address.Address); WriteInt32(endpoint.Port); } public byte[] Complete() { return _stream.ToArray(); } public void Dispose() { _stream.Dispose(); } #region Extension public void Write(T item) where T : IBinarySerializable { if (item != null) { WriteByte(1); item.Serialize(this); } else { WriteByte(0); } } public void WriteCollection(IEnumerable collection) where T : IBinarySerializable { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { item.Serialize(this); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteString(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteIP(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteIPEndpoint(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteGuid(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteDateTime(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteLong(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteInt32(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteDouble(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteBoolean(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteByte(item); } } } public void WriteCollection(IEnumerable collection) { WriteInt32(collection?.Count() ?? 0); if (collection != null) { foreach (var item in collection) { WriteBytes(item); } } } public void WriteCompatible(T item) { WriteBytes(MessageSerializer.SerializeCompatible(item)); } #endregion } }