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 }