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 { /// /// Wrapper over memorystream for writing /// public sealed class MemoryStreamWriter : IBinaryWriter { public Stream Stream { get { return _stream; } } private readonly MemoryStream _stream; public MemoryStreamWriter() { _stream = new MemoryStream(); } /// /// Record a boolean value (1 byte) /// public void WriteBoolean(bool val) { _stream.WriteByte(BitConverter.GetBytes(val)[0]); } /// /// Write byte (1 byte) /// public void WriteByte(byte val) { _stream.WriteByte(val); } /// /// Write array bytes /// /// public void WriteBytes(byte[] val) { if (val == null) { WriteInt32(0); } else { WriteInt32(val.Length); _stream.Write(val, 0, val.Length); } } /// /// Record a 32-bit integer (4 bytes) /// public void WriteInt32(Int32 number) { _stream.Write(BitConverter.GetBytes(number), 0, 4); } /// /// Record an integer 64-bit number (8 bytes) /// 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); } /// /// Write string (4 bytes long + Length bytes) /// 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 record (16 bytes) /// public void WriteGuid(Guid guid) { _stream.Write(guid.ToByteArray(), 0, 16); } /// /// Record the datetime /// /// 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 Extension } }