1 module libd.io.memory;
2
3 import libd.io.stream;
4
5 struct MemoryReaderStream
6 {
7 static assert(isStream!MemoryReaderStream);
8
9 private const(ubyte)[] _data;
10 private size_t _cursor;
11
12 nothrow @nogc:
13
14 this(const ubyte[] data)
15 {
16 this._data = data;
17 }
18
19 SimpleResult!size_t write(const void[] data)
20 {
21 return typeof(return)(raise("This stream cannot read under any circumstance."));
22 }
23
24 SimpleResult!size_t read(scope void[] data)
25 {
26 if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
27 auto end = this._cursor + data.length;
28 if(end > this._data.length)
29 end = this._data.length;
30
31 const amount = end - this._cursor;
32 (cast(ubyte[])data)[0..amount] = this._data[this._cursor..end];
33 this._cursor = end;
34 return typeof(return)(cast(size_t)amount);
35 }
36
37 bool hasData()
38 {
39 return this._cursor < this._data.length;
40 }
41
42 bool isOpen()
43 {
44 return this._data !is null;
45 }
46
47 SimpleResult!size_t getPosition()
48 {
49 if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
50 return typeof(return)(this._cursor);
51 }
52
53 SimpleResult!void setPosition(size_t position)
54 {
55 import libd.data.format;
56 if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
57 if(position > this._data.length)
58 return typeof(return)(raise("Cannot set position to {0} as data length is {1}".format(position, this._data.length).value));
59
60 this._cursor = position;
61 return typeof(return)();
62 }
63
64 SimpleResult!size_t getSize()
65 {
66 if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
67 return typeof(return)(this._data.length);
68 }
69
70 enum canPosition = true;
71 enum canWrite = false;
72 enum canRead = true;
73 }