using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Globalization;
using System.ComponentModel;
public StreamObject() : this(new MemoryStream()) { }
public StreamObject(Stream stream)
throw new ArgumentNullException();
this.StreamProperty = stream;
public Stream StreamProperty { get; set; }
internal static event EventHandler OnDataReadBegin;
internal static event EventHandler OnDataReadEnd;
const int ChunkSize = 4096;
[ProtoMember(1, IsPacked = false, OverwriteList = true)]
IEnumerable<ByteBuffer> Data
if (OnDataReadBegin != null)
OnDataReadBegin(this, new EventArgs());
byte[] buffer = new byte[ChunkSize];
int read = StreamProperty.Read(buffer, 0, buffer.Length);
else if (read == buffer.Length)
yield return new ByteBuffer { Data = buffer };
Array.Resize(ref buffer, read);
yield return new ByteBuffer { Data = buffer };
if (OnDataReadEnd != null)
OnDataReadEnd(this, new EventArgs());
foreach (var buffer in value)
StreamProperty.Write(buffer.Data, 0, buffer.Data.Length);
[ProtoMember(1, IsPacked = true)]
public byte[] Data { get; set; }
var writeStream = new MemoryStream();
EventHandler begin = (o, e) => { beginLength = writeStream.Length; Console.WriteLine(string.Format("Begin serialization of Data, writeStream.Length = {0}", writeStream.Length)); };
EventHandler end = (o, e) => { endLength = writeStream.Length; Console.WriteLine(string.Format("End serialization of Data, writeStream.Length = {0}", writeStream.Length)); };
StreamObject.OnDataReadBegin += begin;
StreamObject.OnDataReadEnd += end;
var inputStream = new MemoryStream();
for (int i = 0; i < length; i++)
inputStream.WriteByte(unchecked((byte)i));
inputStream.Position = 0;
var streamObject = new StreamObject(inputStream);
Serializer.Serialize(writeStream, streamObject);
var data = writeStream.ToArray();
StreamObject newStreamObject;
using (var s = new MemoryStream(data))
newStreamObject = Serializer.Deserialize<StreamObject>(s);
if (beginLength >= endLength)
throw new InvalidOperationException("inputStream was completely buffered before writing to writeStream");
inputStream.Position = 0;
newStreamObject.StreamProperty.Position = 0;
if (!inputStream.AsEnumerable().SequenceEqual(newStreamObject.StreamProperty.AsEnumerable()))
throw new InvalidOperationException("!inputStream.AsEnumerable().SequenceEqual(newStreamObject.StreamProperty.AsEnumerable())");
Console.WriteLine("Streams identical.");
StreamObject.OnDataReadBegin -= begin;
StreamObject.OnDataReadEnd -= end;
public static class StreamExtensions
public static IEnumerable<byte> AsEnumerable(this Stream stream)
throw new ArgumentNullException();
while ((b = stream.ReadByte()) != -1)
yield return checked((byte)b);
public static void Main()
Console.WriteLine("protobuf-net version: " + typeof(ProtoBuf.Serializer).Assembly.FullName);
ProtoBuf.Meta.RuntimeTypeModel.Default.AutoCompile = false;