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