1 package frost.io
2
3 uses frost.unsafe.Pointer
4
5 ====================================================================================================
6 A stream of binary or character data which can be written to. The various `write` methods output
7 binary data, whereas `print` outputs text. This means that `out.write(65)` will write an `"A"`
8 (which has numeric value 65) to the stream, while `out.print(65)` will print the two characters
9 `"6"` and `"5"`.
10 ====================================================================================================
11 @abstract
12 class OutputStream {
13 ================================================================================================
14 Determines the endianness of the data in this stream when writing multi-byte values. Defaults to
15 `LITTLE_ENDIAN`, but may be freely changed.
16 ================================================================================================
17 var byteOrder := ByteOrder.LITTLE_ENDIAN
18
19 ================================================================================================
20 The string used to terminate lines written by the various `printLine` methods. Defaults to the
21 correct line ending sequence for the current platform.
22 ================================================================================================
23 var lineEnding := "\n" -- FIXME this will need to be changed on Windows
24
25 ================================================================================================
26 Writes a single byte.
27
28 @param value the value to write
29 ================================================================================================
30 @abstract
31 method write(value:UInt8):Error?
32
33 ================================================================================================
34 Writes the two bytes comprising a `UInt16`. The byte order is controlled by the [byteOrder]
35 field.
36
37 @param value the value to write
38 ================================================================================================
39 @extendable
40 method write(value:UInt16):Error? {
41 try {
42 if byteOrder = ByteOrder.LITTLE_ENDIAN {
43 write(value.asUInt8)
44 write((value >> 8).asUInt8)
45 }
46 else {
47 write((value >> 8).asUInt8)
48 write(value.asUInt8)
49 }
50 return null
51 }
52 fail(error) {
53 return error
54 }
55 }
56
57 ================================================================================================
58 Writes the four bytes comprising a `UInt32`. The byte order is controlled by the [byteOrder]
59 field.
60
61 @param value the value to write
62 ================================================================================================
63 @extendable
64 method write(value:UInt32):Error? {
65 try {
66 if byteOrder = ByteOrder.LITTLE_ENDIAN {
67 write(value.asUInt16)
68 write((value >> 16).asUInt16)
69 }
70 else {
71 write((value >> 16).asUInt16)
72 write(value.asUInt16)
73 }
74 return null
75 }
76 fail(error) {
77 return error
78 }
79 }
80
81 ================================================================================================
82 Writes the eight bytes comprising a `UInt64`. The byte order is controlled by the [byteOrder]
83 field.
84
85 @param value the value to write
86 ================================================================================================
87 @extendable
88 method write(value:UInt64):Error? {
89 try {
90 if byteOrder = ByteOrder.LITTLE_ENDIAN {
91 write(value.asUInt32)
92 write((value >> 32).asUInt32)
93 }
94 else {
95 write((value >> 32).asUInt32)
96 write(value.asUInt32)
97 }
98 return null
99 }
100 fail(error) {
101 return error
102 }
103 }
104
105 ================================================================================================
106 Writes a single byte.
107
108 @param value the value to write
109 ================================================================================================
110 method write(value:Int8):Error? {
111 return write(value.asUInt8)
112 }
113
114 ================================================================================================
115 Writes the two bytes comprising an `Int16`. The byte order is controlled by the [byteOrder]
116 field.
117
118 @param value the value to write
119 ================================================================================================
120 method write(value:Int16):Error? {
121 return write(value.asUInt16)
122 }
123
124 ================================================================================================
125 Writes the four bytes comprising an `Int32`. The byte order is controlled by the [byteOrder]
126 field.
127
128 @param value the value to write
129 ================================================================================================
130 method write(value:Int32):Error? {
131 return write(value.asUInt32)
132 }
133
134 ================================================================================================
135 Writes the eight bytes comprising an `Int64`. The byte order is controlled by the [byteOrder]
136 field.
137
138 @param value the value to write
139 ================================================================================================
140 method write(value:Int64):Error? {
141 return write(value.asUInt64)
142 }
143
144 ================================================================================================
145 Writes a block of data to this stream.
146
147 @param ptr Pointer to the data to write
148 @param count number of bytes to write
149 ================================================================================================
150 @extendable
151 method write(ptr:Pointer<UInt8>, count:Int):Error? {
152 try {
153 for i in 0 .. count {
154 write(ptr[i])
155 }
156 return null
157 }
158 fail(error) {
159 return error
160 }
161 }
162
163 ================================================================================================
164 Writes a block of data to this stream.
165
166 @param ptr Pointer to the data to write
167 @param count number of bytes to write
168 ================================================================================================
169 method write(ptr:Pointer<Int8>, count:Int):Error? {
170 return write(ptr->Pointer<UInt8>, count)
171 }
172
173 ================================================================================================
174 Writes a block of data to this stream.
175
176 @param ptr Pointer to the data to write
177 @param count number of bytes to write
178 ================================================================================================
179 method write(ptr:Pointer<Char8>, count:Int):Error? {
180 return write(ptr->Pointer<UInt8>, count)
181 }
182
183 ================================================================================================
184 Writes a portion of an array of bytes to this stream. The write begins at index `0` and the last
185 byte written is at index `count - 1`.
186
187 @param a the array to write
188 @param count number of bytes to write
189 ================================================================================================
190 method write(a:Array<UInt8>, count:Int):Error? {
191 try {
192 for i in 0 .. count {
193 write(a[i])
194 }
195 return null
196 }
197 fail(error) {
198 return error
199 }
200 }
201
202 ================================================================================================
203 Writes a portion of an array of bytes to this stream. The write begins at index `0` and the last
204 byte written is at index `count - 1`.
205
206 @param a the array to write
207 @param count number of bytes to write
208 ================================================================================================
209 method write(a:Array<Int8>, count:Int):Error? {
210 try {
211 for i in 0 .. count {
212 write(a[i])
213 }
214 return null
215 }
216 fail(error) {
217 return error
218 }
219 }
220
221 ================================================================================================
222 Writes a portion of an array of bytes to this stream. The write begins at index `0` and the last
223 byte written is at index `count - 1`.
224
225 @param a the array to write
226 @param count number of bytes to write
227 ================================================================================================
228 method write(a:Array<Char8>, count:Int):Error? {
229 try {
230 for i in 0 .. count {
231 write(a[i])
232 }
233 return null
234 }
235 fail(error) {
236 return error
237 }
238 }
239
240 ================================================================================================
241 Writes a single byte.
242
243 @param value the value to write
244 ================================================================================================
245 method write(value:Char8):Error? {
246 return write(value.asUInt8)
247 }
248
249 ================================================================================================
250 Prints a string to the stream.
251
252 @param s the string to write
253 ================================================================================================
254 @unsafeAccess
255 method print(s:String):Error? {
256 return write(s.data, s._length)
257 }
258
259 ================================================================================================
260 Prints the string represention of an object (as given by [toString](Object.toString)) to the
261 stream.
262
263 @param o the object to write
264 ================================================================================================
265 method print(o:Object):Error? {
266 return print(o.toString)
267 }
268
269 ================================================================================================
270 Prints a string to the stream., followed by a [line ending](lineEnding).
271
272 @param s the string to write
273 ================================================================================================
274 method printLine(s:String):Error? {
275 try {
276 print(s)
277 printLine()
278 return null
279 }
280 fail(error) {
281 return error
282 }
283 }
284
285 ================================================================================================
286 Prints the string represention of an object (as given by [toString](Object.toString)) to the
287 stream, followed by a [line ending](lineEnding).
288
289 @param o the object to write
290 ================================================================================================
291 method printLine(o:Object):Error? {
292 return printLine(o.toString)
293 }
294
295 ================================================================================================
296 Prints a [line ending](lineEnding).
297 ================================================================================================
298 method printLine():Error? {
299 return print(lineEnding)
300 }
301
302 ================================================================================================
303 Flushes any buffers associated with this stream. `OutputStream` does not itself perform any
304 buffering, so the base implementation of this method does nothing, but subclasses which buffer
305 their output should override this.
306 ================================================================================================
307 @extendable
308 method flush():Error? {
309 return null
310 }
311
312 ================================================================================================
313 Closes this `OutputStream`. The default implementation does nothing.
314 ================================================================================================
315 @extendable
316 method close():Error? {
317 return null
318 }
319 }