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  }