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