10 public class IteratorStream : Stream
11 {
12 private readonly IEnumerator<byte[]> m_Chunks;
13 private ArraySegment<byte> m_CurrentChunk;
14
15 public IteratorStream(IEnumerable<byte[]> _Chunks)
16 {
17 if (_Chunks == null) throw new ArgumentNullException();
18 m_Chunks = _Chunks.GetEnumerator();
19 }
20
21 public override bool CanRead {
22 get { return true; }
23 }
24
25 public override bool CanSeek
26 {
27 get { return false; }
28 }
29
30 public override bool CanWrite {
31 get { return false; }
32 }
33 public override long Length { get { return -1; } }
34
35 public override long Position
36 {
37 get { throw new NotImplementedException(); }
38 set{ throw new NotImplementedException();}
39 }
40
41 private bool ReadNextChunk()
42 {
43 bool HasMore = m_Chunks.MoveNext();
44 if (HasMore)
45 {
46 m_CurrentChunk = new ArraySegment<byte>(m_Chunks.Current);
47 }
48 return HasMore;
49 }
50
51 public override int Read(byte[] buffer, int offset, int count) {
52 if (buffer == null) throw new ArgumentNullException("buffer");
53 if (offset < 0 || offset >= buffer.Length) throw new ArgumentException("offset must be greater than or equal to 0 and less than the size of the buffer");
54 if (count < 0) throw new ArgumentException("count must be greater than or equal to 0");
55 if (offset + count > buffer.Length) throw new ArgumentException("offset + count must be less than the buffer size");
56
57 int LeftToRead = count;
58 int CurrentLocation = offset;
59 if (m_CurrentChunk.Count == 0)
60 {
61 if (!ReadNextChunk())
62 {
63 return 0;
64 }
65 }
66 while (LeftToRead > 0 && m_CurrentChunk.Count != 0)
67 {
68 int toRead = (LeftToRead > m_CurrentChunk.Count) ? m_CurrentChunk.Count : LeftToRead;
69 Buffer.BlockCopy(m_CurrentChunk.Array, m_CurrentChunk.Offset, buffer, CurrentLocation, toRead);
70 LeftToRead -= toRead;
71 CurrentLocation += toRead;
72 m_CurrentChunk = new ArraySegment<byte>(m_CurrentChunk.Array, m_CurrentChunk.Offset + toRead, m_CurrentChunk.Count - toRead);
73 if (m_CurrentChunk.Count == 0)
74 {
75 ReadNextChunk();
76 }
77 }
78 return count - LeftToRead;
79 }
80
81 protected override void Dispose(bool disposing)
82 {
83 base.Dispose(disposing);
84 if (disposing && m_Chunks != null)
85 {
86 m_Chunks.Dispose();
87 }
88
89 }
90
91 public override long Seek(long offset, SeekOrigin loc) { throw new NotImplementedException(); }
92 public override void SetLength(long value) { throw new NotImplementedException(); }
93 public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); }
94 public override void Flush() { throw new NotImplementedException(); }
95 public override void WriteByte(byte value) { throw new NotImplementedException(); }
96 }
97
98
99 class Program
100 {
101 static IEnumerable<byte[]> GetBytes()
102 {
103 byte [] OneToTen = new byte[10];
104 for(byte i=0;i<10;i++)
105 OneToTen
= i;
106 for(int j = 0;j <10;j++) {
107 yield return OneToTen;
108 }
109 }
110
111 static void Main(string[] args)
112 {
113 IteratorStream stream;
114 using (stream = new IteratorStream(GetBytes()))
115 {
116 int read = stream.ReadByte();
117
118 //read 1 byte at a time
119 while (read != -1)
120 {
121 Console.WriteLine(read.ToString());
122 read = stream.ReadByte();
123 }
124 }
125
126 //read 100 bytes
127 using (stream = new IteratorStream(GetBytes()))
128 {
129 byte[] buffer = new byte[100];
130 int read = stream.Read(buffer, 0, 100);
131 Console.WriteLine(read);
132 }
133
134 }
135 }