1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: March 2004$(BR) 8 Outback release: December 2006 9 10 author: Kris 11 12 *******************************************************************************/ 13 14 module tango.io.model.IConduit; 15 16 /******************************************************************************* 17 18 Conduits provide virtualized access to external content, and 19 represent things like files or Internet connections. Conduits 20 expose a pair of streams, are modelled by tango.io.model.IConduit, 21 and are implemented via classes such as File & SocketConduit. 22 23 Additional kinds of conduit are easy to construct: one either 24 subclasses tango.io.device.Conduit, or implements tango.io.model.IConduit. 25 A conduit typically reads and writes from/to an IBuffer in large 26 chunks, typically the entire buffer. Alternatively, one can invoke 27 input.read(dst[]) and/or output.write(src[]) directly. 28 29 *******************************************************************************/ 30 31 interface IConduit : InputStream, OutputStream 32 { 33 /*********************************************************************** 34 35 Return a preferred size for buffering conduit I/O. 36 37 ***********************************************************************/ 38 39 @property abstract size_t bufferSize (); 40 41 /*********************************************************************** 42 43 Return the name of this conduit. 44 45 ***********************************************************************/ 46 47 abstract immutable(char)[] toString (); 48 49 /*********************************************************************** 50 51 Is the conduit alive? 52 53 ***********************************************************************/ 54 55 @property abstract const bool isAlive (); 56 57 /*********************************************************************** 58 59 Release external resources. 60 61 ***********************************************************************/ 62 63 abstract void detach (); 64 65 /*********************************************************************** 66 67 Throw a generic IO exception with the provided msg. 68 69 ***********************************************************************/ 70 71 abstract void error (const(char[]) msg); 72 73 /*********************************************************************** 74 75 All streams now support seek(), so this is used to signal 76 a seekable conduit instead. 77 78 ***********************************************************************/ 79 80 interface Seek {} 81 82 /*********************************************************************** 83 84 Indicates the conduit supports resize/truncation. 85 86 ***********************************************************************/ 87 88 interface Truncate 89 { 90 void truncate (long size); 91 } 92 } 93 94 95 /******************************************************************************* 96 97 Describes how to make an IO entity usable with selectors. 98 99 *******************************************************************************/ 100 101 interface ISelectable 102 { 103 version (Windows) 104 alias void* Handle; /// Opaque OS file-handle. 105 else 106 alias int Handle;/* = -1;*/ /// Opaque OS file-handle. 107 108 /*********************************************************************** 109 110 Models a handle-oriented device. 111 112 TODO: Figure out how to avoid exposing this in the general 113 case. 114 115 ***********************************************************************/ 116 117 @property Handle fileHandle (); 118 } 119 120 121 /******************************************************************************* 122 123 The common attributes of streams. 124 125 *******************************************************************************/ 126 127 interface IOStream 128 { 129 enum Eof = -1; /// the End-of-Flow identifer 130 131 /*********************************************************************** 132 133 The anchor positions supported by seek(). 134 135 ***********************************************************************/ 136 137 enum Anchor { 138 Begin = 0, 139 Current = 1, 140 End = 2, 141 }; 142 143 /*********************************************************************** 144 145 Move the stream position to the given offset from the 146 provided anchor point, and return adjusted position. 147 148 Those conduits which don't support seeking will throw 149 an IOException (and don't implement IConduit.Seek). 150 151 ***********************************************************************/ 152 153 long seek (long offset, Anchor anchor = Anchor.Begin); 154 155 /*********************************************************************** 156 157 Return the host conduit. 158 159 ***********************************************************************/ 160 161 @property IConduit conduit (); 162 163 /*********************************************************************** 164 165 Flush buffered content. For InputStream this is equivalent 166 to clearing buffered content. 167 168 ***********************************************************************/ 169 170 IOStream flush (); 171 172 /*********************************************************************** 173 174 Close the input. 175 176 ***********************************************************************/ 177 178 void close (); 179 180 181 /*********************************************************************** 182 183 Marks a stream that performs read/write mutation, rather than 184 generic decoration. This is used to identify those stream that 185 should explicitly not share an upstream buffer with downstream 186 siblings. 187 188 Many streams add simple decoration (such as DataStream) while 189 others are merely template aliases. However, streams such as 190 EndianStream mutate content as it passes through the read and 191 write methods, which must be respected. On one hand we wish 192 to share a single buffer instance, while on the other we must 193 ensure correct data flow through an arbitrary combinations of 194 streams. 195 196 There are two stream variations: one which operate directly 197 upon memory (and thus must have access to a buffer) and another 198 that prefer to have buffered input (for performance reasons) but 199 can operate without. EndianStream is an example of the former, 200 while DataStream represents the latter. 201 202 In order to sort out who gets what, each stream makes a request 203 for an upstream buffer at construction time. The request has an 204 indication of the intended purpose (array-based access, or not). 205 206 ***********************************************************************/ 207 208 interface Mutator {} 209 } 210 211 212 /******************************************************************************* 213 214 The Tango input stream. 215 216 *******************************************************************************/ 217 218 interface InputStream : IOStream 219 { 220 /*********************************************************************** 221 222 Read from stream into a target array. The provided dst 223 will be populated with content from the stream. 224 225 Returns the number of bytes read, which may be less than 226 requested in dst. Eof is returned whenever an end-of-flow 227 condition arises. 228 229 ***********************************************************************/ 230 231 size_t read (void[] dst); 232 233 /*********************************************************************** 234 235 Load the bits from a stream, and return them all in an 236 array. The optional max value indicates the maximum 237 number of bytes to be read. 238 239 Returns an array representing the content, and throws 240 IOException on error. 241 242 ***********************************************************************/ 243 244 void[] load (size_t max = -1); 245 246 /*********************************************************************** 247 248 Return the upstream source. 249 250 ***********************************************************************/ 251 252 @property InputStream input (); 253 } 254 255 256 /******************************************************************************* 257 258 The Tango output stream. 259 260 *******************************************************************************/ 261 262 interface OutputStream : IOStream 263 { 264 /*********************************************************************** 265 266 Write to stream from a source array. The provided src 267 content will be written to the stream. 268 269 Returns the number of bytes written from src, which may 270 be less than the quantity provided. Eof is returned when 271 an end-of-flow condition arises. 272 273 ***********************************************************************/ 274 275 size_t write (const(void)[] src); 276 277 278 /*********************************************************************** 279 280 Transfer the content of another stream to this one. Returns 281 a reference to this class, and throws IOException on failure. 282 283 ***********************************************************************/ 284 285 OutputStream copy (InputStream src, size_t max = -1); 286 287 /*********************************************************************** 288 289 Return the upstream sink. 290 291 ***********************************************************************/ 292 293 @property OutputStream output (); 294 } 295 296 297 /******************************************************************************* 298 299 A buffered input stream. 300 301 *******************************************************************************/ 302 303 interface InputBuffer : InputStream 304 { 305 void[] slice (); 306 307 bool next (scope size_t delegate(const(void)[]) scan); 308 309 size_t reader (scope size_t delegate(const(void)[]) consumer); 310 } 311 312 /******************************************************************************* 313 314 A buffered output stream. 315 316 *******************************************************************************/ 317 318 interface OutputBuffer : OutputStream 319 { 320 alias append opCall; 321 322 void[] slice (); 323 324 OutputBuffer append (const(void)[]); 325 326 size_t writer (size_t delegate(void[]) producer); 327 } 328 329