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