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