1 /******************************************************************************* 2 3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: June 2007 8 9 author: Kris 10 11 *******************************************************************************/ 12 13 module tango.io.stream.Greedy; 14 15 private import tango.io.device.Conduit; 16 17 18 /******************************************************************************* 19 20 A conduit filter that ensures its input is read in full. There's 21 also an optional readExact() for more explicit requests. 22 23 *******************************************************************************/ 24 25 class GreedyInput : InputFilter 26 { 27 /*********************************************************************** 28 29 Propagate ctor to superclass. 30 31 ***********************************************************************/ 32 33 this (InputStream stream) 34 { 35 super (stream); 36 } 37 38 /*********************************************************************** 39 40 Fill the provided array. Returns the number of bytes 41 actually read, which will be less that dst.length when 42 Eof has been reached, and then Eof thereafter. 43 44 ***********************************************************************/ 45 46 final override size_t read (void[] dst) 47 { 48 size_t len = 0; 49 50 while (len < dst.length) 51 { 52 auto i = source.read (dst [len .. $]); 53 if (i is Eof) 54 return (len ? len : i); 55 len += i; 56 } 57 return len; 58 } 59 60 /*********************************************************************** 61 62 Read from a stream into a target array. The provided dst 63 will be fully populated with content from the input. 64 65 This differs from read in that it will throw an exception 66 where an Eof condition is reached before input has completed. 67 68 ***********************************************************************/ 69 70 final GreedyInput readExact (void[] dst) 71 { 72 while (dst.length) 73 { 74 auto i = read (dst); 75 if (i is Eof) 76 conduit.error ("unexpected Eof while reading: "~conduit.toString()); 77 dst = dst [i .. $]; 78 } 79 return this; 80 } 81 } 82 83 84 85 /******************************************************************************* 86 87 A conduit filter that ensures its output is written in full. There's 88 also an optional writeExact() for more explicit requests. 89 90 *******************************************************************************/ 91 92 class GreedyOutput : OutputFilter 93 { 94 /*********************************************************************** 95 96 Propagate ctor to superclass. 97 98 ***********************************************************************/ 99 100 this (OutputStream stream) 101 { 102 super (stream); 103 } 104 105 /*********************************************************************** 106 107 Consume everything we were given. Returns the number of 108 bytes written which will be less than src.length only 109 when an Eof condition is reached, and Eof from that point 110 forward. 111 112 ***********************************************************************/ 113 114 final override size_t write (const(void)[] src) 115 { 116 size_t len = 0; 117 118 while (len < src.length) 119 { 120 auto i = sink.write (src [len .. $]); 121 if (i is Eof) 122 return (len ? len : i); 123 len += i; 124 } 125 return len; 126 } 127 128 /*********************************************************************** 129 130 Write to stream from a source array. The provided src content 131 will be written in full to the output. 132 133 This differs from write in that it will throw an exception 134 where an Eof condition is reached before output has completed. 135 136 ***********************************************************************/ 137 138 final GreedyOutput writeExact (void[] src) 139 { 140 while (src.length) 141 { 142 auto i = write (src); 143 if (i is Eof) 144 conduit.error ("unexpected Eof while writing: "~conduit.toString()); 145 src = src [i .. $]; 146 } 147 return this; 148 } 149 } 150 151 152 /******************************************************************************* 153 154 *******************************************************************************/ 155 156 debug (Greedy) 157 { 158 void main() 159 { 160 auto s = new GreedyInput (null); 161 } 162 }