1 /** 2 * A collection of helper functions that augment the basic `read` and `write` 3 * functions of input and output streams. 4 */ 5 module streams.functions; 6 7 import streams.primitives; 8 9 import std.traits; 10 11 /** 12 * Continously reads an input stream into an in-memory buffer, until 0 elements 13 * could be read, or an error occurs. 14 * Params: 15 * stream = The stream to read from. 16 * bufferSize = The size of the internal buffer to use for reading. 17 * Returns: The full contents of the stream. 18 */ 19 DataType[] readAll(StreamType, DataType)( 20 ref StreamType stream, 21 uint bufferSize = 8192 22 ) if (isInputStream!(StreamType, DataType)) { 23 import std.array : Appender, appender; 24 Appender!(DataType[]) app = appender!(DataType[])(); 25 DataType[] buffer = new DataType[bufferSize]; 26 int itemsRead; 27 while ((itemsRead = stream.read(buffer)) > 0) { 28 app ~= buffer[0 .. itemsRead]; 29 } 30 return app[]; 31 } 32 33 unittest { 34 import streams; 35 import std.file; 36 37 auto s1 = FileInputStream("LICENSE"); 38 ulong expectedSize = getSize("LICENSE"); 39 ubyte[] data = readAll!(FileInputStream, ubyte)(s1); 40 assert(data.length == expectedSize); 41 } 42 43 /** 44 * Transfers elements from an input stream to an output stream, doing so 45 * continuously until the input stream reads 0 elements or an error occurs. 46 * The streams are not closed after transfer completes. 47 * Params: 48 * input = The input stream to read from. 49 * output = The output stream to write to. 50 * bufferSize = The size of the internal buffer to use for reading. 51 */ 52 void transferTo(InputStreamType, OutputStreamType, DataType)( 53 ref InputStreamType input, 54 ref OutputStreamType output, 55 uint bufferSize = 8192 56 ) if (isInputStream!(InputStreamType, DataType) && isOutputStream!(OutputStreamType, DataType)) { 57 DataType[] buffer = new DataType[bufferSize]; 58 int itemsRead; 59 while ((itemsRead = input.read(buffer)) > 0) { 60 int written = output.write(buffer[0 .. itemsRead]); 61 if (written != itemsRead) { 62 throw new StreamException("Failed to transfer bytes."); 63 } 64 } 65 } 66 67 unittest { 68 import streams; 69 import std.file; 70 71 auto sIn = FileInputStream("LICENSE"); 72 auto sOut = FileOutputStream("LICENSE-COPY"); 73 scope(exit) { 74 std.file.remove("LICENSE-COPY"); 75 } 76 transferTo!(FileInputStream, FileOutputStream, ubyte)(sIn, sOut); 77 sIn.close(); 78 sOut.close(); 79 assert(getSize("LICENSE") == getSize("LICENSE-COPY")); 80 }