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 }