using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Globalization;
using System.ComponentModel;
public class SeekableStreamByteList : IList<byte>
public SeekableStreamByteList(Stream stream)
throw new ArgumentNullException();
throw new ArgumentException("!stream.CanSeek");
#region IList<byte> Members
public int IndexOf(byte item) { throw new NotImplementedException(); }
public void Insert(int index, byte item) { throw new NotImplementedException(); }
public void RemoveAt(int index) { throw new NotImplementedException(); }
public byte this[int index]
if (index < 0 || index >= stream.Length)
throw new ArgumentOutOfRangeException();
return checked((byte)stream.ReadByte());
throw new NotImplementedException();
#region ICollection<byte> Members
public void Add(byte item) { throw new NotImplementedException(); }
public void Clear() { throw new NotImplementedException(); }
public bool Contains(byte item) { throw new NotImplementedException(); }
public void CopyTo(byte[] array, int arrayIndex)
foreach (var item in this)
array[arrayIndex++] = item;
public int Count { get { return checked((int)stream.Length); } }
public bool IsReadOnly { get { return true; } }
public bool Remove(byte item) { throw new NotImplementedException(); }
#region IEnumerable<byte> Members
const int ChunkSize = 4096;
internal static event EventHandler OnDataReadBegin;
internal static event EventHandler OnDataReadEnd;
public IEnumerator<byte> GetEnumerator()
var oldPosition = stream.Position;
if (OnDataReadBegin != null)
OnDataReadBegin(this, new EventArgs());
byte[] buffer = new byte[ChunkSize];
read = stream.Read(buffer, 0, buffer.Length);
for (int i = 0; i < read; i++)
while (read == buffer.Length);
if (OnDataReadEnd != null)
OnDataReadEnd(this, new EventArgs());
stream.Position = oldPosition;
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
public StreamObject(Stream stream)
throw new ArgumentNullException();
this.StreamProperty = stream;
public Stream StreamProperty { get; set; }
[ProtoMember(1, IsPacked = true)]
SeekableStreamByteList StreamBytes
return new SeekableStreamByteList(StreamProperty);
[ProtoMember(1, IsPacked = true)]
public List<byte> StreamBytes { get; set; }
Console.WriteLine(string.Format("Contract for {0}: ", typeof(StreamObject)));
Console.WriteLine(RuntimeTypeModel.Default.GetSchema(typeof(StreamObject)));
Console.WriteLine(string.Format("Contract for {0}: ", typeof(ByteListObject)));
Console.WriteLine(RuntimeTypeModel.Default.GetSchema(typeof(ByteListObject)));
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)); };
SeekableStreamByteList.OnDataReadBegin += begin;
SeekableStreamByteList.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();
ByteListObject newStreamObject;
using (var s = new MemoryStream(data))
newStreamObject = Serializer.Deserialize<ByteListObject>(s);
if (!inputStream.ToArray().SequenceEqual(newStreamObject.StreamBytes))
throw new InvalidOperationException("!inputStream.AsEnumerable().SequenceEqual(newStreamObject.StreamProperty.AsEnumerable())");
Console.WriteLine("Streams round-tripped successfully.");
if (beginLength >= endLength)
throw new InvalidOperationException("inputStream was completely loaded into memory before writing to writeStream!");
Console.WriteLine("inputStream was successfully streamed to writeStream.");
SeekableStreamByteList.OnDataReadBegin -= begin;
SeekableStreamByteList.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;