132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Oct 2004: Initial release
|
|
8 Dec 2006: Outback release
|
|
9
|
|
10 author: Kris
|
|
11 Ivan Senji (the "alias get" idea)
|
|
12
|
|
13 *******************************************************************************/
|
|
14
|
|
15 module tango.io.protocol.model.IReader;
|
|
16
|
|
17 public import tango.io.model.IBuffer;
|
|
18
|
|
19 private import tango.io.protocol.model.IProtocol;
|
|
20
|
|
21 /*******************************************************************************
|
|
22
|
|
23 IReader interface. Each reader operates upon an IBuffer, which is
|
|
24 provided at construction time. Readers are simple converters of data,
|
|
25 and have reasonably rigid rules regarding data format. For example,
|
|
26 each request for data expects the content to be available; an exception
|
|
27 is thrown where this is not the case. If the data is arranged in a more
|
|
28 relaxed fashion, consider using IBuffer directly instead.
|
|
29
|
|
30 All readers support the full set of native data types, plus a full
|
|
31 selection of array types. The latter can be configured to produce
|
|
32 either a copy (.dup) of the buffer content, or a slice. See classes
|
|
33 HeapCopy, BufferSlice and HeapSlice for more on this topic. Applications
|
|
34 can disable memory management by configuring a Reader with one of the
|
|
35 binary oriented protocols, and ensuring the optional protocol 'prefix'
|
|
36 is disabled.
|
|
37
|
|
38 Readers support Java-esque get() notation. However, the Tango
|
|
39 style is to place IO elements within their own parenthesis, like
|
|
40 so:
|
|
41
|
|
42 ---
|
|
43 int count;
|
|
44 char[] verse;
|
|
45
|
|
46 read (verse) (count);
|
|
47 ---
|
|
48
|
|
49 Note that each element read is distict; this style is affectionately
|
|
50 known as "whisper". The code below illustrates basic operation upon a
|
|
51 memory buffer:
|
|
52
|
|
53 ---
|
|
54 auto buf = new Buffer (256);
|
|
55
|
|
56 // map same buffer into both reader and writer
|
|
57 auto read = new Reader (buf);
|
|
58 auto write = new Writer (buf);
|
|
59
|
|
60 int i = 10;
|
|
61 long j = 20;
|
|
62 double d = 3.14159;
|
|
63 char[] c = "fred";
|
|
64
|
|
65 // write data using whisper syntax
|
|
66 write (c) (i) (j) (d);
|
|
67
|
|
68 // read them back again
|
|
69 read (c) (i) (j) (d);
|
|
70
|
|
71
|
|
72 // same thing again, but using put() syntax instead
|
|
73 write.put(c).put(i).put(j).put(d);
|
|
74 read.get(c).get(i).get(j).get(d);
|
|
75 ---
|
|
76
|
|
77 Note that certain protocols, such as the basic binary implementation,
|
|
78 expect to retrieve the number of array elements from the source. For
|
|
79 example: when reading an array from a file, the number of elements
|
|
80 is read from the file also, and the configurable memory-manager is
|
|
81 invoked to provide the array space. If content is not arranged in
|
|
82 such a manner you may read array content directly either by creating
|
|
83 a Reader with a protocol configured to sidestep array-prefixing, or
|
|
84 by accessing buffer content directly (via the methods exposed there)
|
|
85 e.g.
|
|
86
|
|
87 ---
|
|
88 void[10] data;
|
|
89
|
|
90 reader.buffer.fill (data);
|
|
91 ---
|
|
92
|
|
93 Readers may also be used with any class implementing the IReadable
|
|
94 interface, along with any struct implementing an equivalent method
|
|
95
|
|
96 *******************************************************************************/
|
|
97
|
|
98 abstract class IReader // could be an interface, but that causes poor codegen
|
|
99 {
|
|
100 alias get opCall;
|
|
101
|
|
102 /***********************************************************************
|
|
103
|
|
104 These are the basic reader methods
|
|
105
|
|
106 ***********************************************************************/
|
|
107
|
|
108 abstract IReader get (inout bool x);
|
|
109 abstract IReader get (inout byte x); /// ditto
|
|
110 abstract IReader get (inout ubyte x); /// ditto
|
|
111 abstract IReader get (inout short x); /// ditto
|
|
112 abstract IReader get (inout ushort x); /// ditto
|
|
113 abstract IReader get (inout int x); /// ditto
|
|
114 abstract IReader get (inout uint x); /// ditto
|
|
115 abstract IReader get (inout long x); /// ditto
|
|
116 abstract IReader get (inout ulong x); /// ditto
|
|
117 abstract IReader get (inout float x); /// ditto
|
|
118 abstract IReader get (inout double x); /// ditto
|
|
119 abstract IReader get (inout real x); /// ditto
|
|
120 abstract IReader get (inout char x); /// ditto
|
|
121 abstract IReader get (inout wchar x); /// ditto
|
|
122 abstract IReader get (inout dchar x); /// ditto
|
|
123
|
|
124 abstract IReader get (inout bool[] x); /// ditto
|
|
125 abstract IReader get (inout byte[] x); /// ditto
|
|
126 abstract IReader get (inout short[] x); /// ditto
|
|
127 abstract IReader get (inout int[] x); /// ditto
|
|
128 abstract IReader get (inout long[] x); /// ditto
|
|
129 abstract IReader get (inout ubyte[] x); /// ditto
|
|
130 abstract IReader get (inout ushort[] x); /// ditto
|
|
131 abstract IReader get (inout uint[] x); /// ditto
|
|
132 abstract IReader get (inout ulong[] x); /// ditto
|
|
133 abstract IReader get (inout float[] x); /// ditto
|
|
134 abstract IReader get (inout double[] x); /// ditto
|
|
135 abstract IReader get (inout real[] x); /// ditto
|
|
136 abstract IReader get (inout char[] x); /// ditto
|
|
137 abstract IReader get (inout wchar[] x); /// ditto
|
|
138 abstract IReader get (inout dchar[] x); /// ditto
|
|
139
|
|
140 /***********************************************************************
|
|
141
|
|
142 This is the mechanism used for binding arbitrary classes
|
|
143 to the IO system. If a class implements IReadable, it can
|
|
144 be used as a target for IReader get() operations. That is,
|
|
145 implementing IReadable is intended to transform any class
|
|
146 into an IReader adaptor for the content held therein.
|
|
147
|
|
148 ***********************************************************************/
|
|
149
|
|
150 abstract IReader get (IReadable);
|
|
151
|
|
152 alias void delegate (IReader) Closure;
|
|
153
|
|
154 abstract IReader get (Closure);
|
|
155
|
|
156 /***********************************************************************
|
|
157
|
|
158 Return the buffer associated with this reader
|
|
159
|
|
160 ***********************************************************************/
|
|
161
|
|
162 abstract IBuffer buffer ();
|
|
163
|
|
164 /***********************************************************************
|
|
165
|
|
166 Get the allocator to use for array management. Arrays are
|
|
167 generally allocated by the IReader, via configured managers.
|
|
168 A number of Allocator classes are available to manage memory
|
|
169 when reading array content. Alternatively, the application
|
|
170 may obtain responsibility for allocation by selecting one of
|
|
171 the NativeProtocol deriviatives and setting 'prefix' to be
|
|
172 false. The latter disables internal array management.
|
|
173
|
|
174 Gaining access to the allocator can expose some additional
|
|
175 controls. For example, some allocators benefit from a reset
|
|
176 operation after each data 'record' has been processed.
|
|
177
|
|
178 By default, an IReader will allocate each array from the
|
|
179 heap. You can change that by constructing the Reader
|
|
180 with an Allocator of choice. For instance, there is a
|
|
181 BufferSlice which will slice an array directly from
|
|
182 the buffer where possible. Also available is the record-
|
|
183 oriented HeaoSlice, which slices memory from within
|
|
184 a pre-allocated heap area, and should be reset by the client
|
|
185 code after each record has been read (to avoid unnecessary
|
|
186 growth).
|
|
187
|
|
188 See module tango.io.protocol.Allocator for more information
|
|
189
|
|
190 ***********************************************************************/
|
|
191
|
|
192 abstract IAllocator allocator ();
|
|
193 }
|
|
194
|
|
195 /*******************************************************************************
|
|
196
|
|
197 Any class implementing IReadable becomes part of the Reader framework
|
|
198
|
|
199 *******************************************************************************/
|
|
200
|
|
201 interface IReadable
|
|
202 {
|
|
203 void read (IReader input);
|
|
204 }
|
|
205
|