logo

class

sys::InStream

sys::Obj
  sys::InStream
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   16 Mar 06  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** InStream is used to read binary and text stream based input.
  11  **
  12  class InStream
  13  {
  14  
  15  //////////////////////////////////////////////////////////////////////////
  16  // Construction
  17  //////////////////////////////////////////////////////////////////////////
  18  
  19    **
  20    ** Make an input stream designed to read characters from the specified
  21    ** string.  If binary reads are made from the string, then each character
  22    ** is read as a one byte ASCII char.
  23    **
  24    static InStream makeForStr(Str str)
  25  
  26    **
  27    ** Constructor for an InStream which wraps another stream.
  28    ** All reads from this stream will be routed to the specified
  29    ** inner stream.
  30    **
  31    ** If in is null, then it is the subclass responsibility to
  32    ** handle reads by overriding the following methods: `read`,
  33    ** `readBuf`, and `unread`.
  34    **
  35    protected new make(InStream out)
  36  
  37  //////////////////////////////////////////////////////////////////////////
  38  // Virtuals
  39  //////////////////////////////////////////////////////////////////////////
  40  
  41    **
  42    ** Read the next unsigned byte from the input stream.
  43    ** Return null if at end of stream.  Throw IOErr on error.
  44    **
  45    virtual Int read()
  46  
  47    **
  48    ** Attempt to read the next n bytes into the Buf at it's current
  49    ** position.  The buffer will be grown as needed.  Return the number
  50    ** of bytes read and increment buf's size and position accordingly.
  51    ** Return null and leave buf's state untouched if end of stream.
  52    ** Note this method may not read the full number of n bytes, use
  53    ** readBufFully() if you must block until all n bytes read.
  54    ** Throw IOErr on error.
  55    **
  56    virtual Int readBuf(Buf buf, Int n)
  57  
  58    **
  59    ** Pushback a byte so that it is the next byte to be read.  There
  60    ** is a finite limit to the number of bytes which may be pushed
  61    ** back.  Return this.
  62    **
  63    virtual InStream unread(Int b)
  64  
  65    **
  66    ** Close the input stream.  This method is guaranteed to never
  67    ** throw an IOErr.  Return true if the stream was closed successfully
  68    ** or false if the stream was closed abnormally.  Default implementation
  69    ** does nothing and returns true.
  70    **
  71    virtual Bool close()
  72  
  73    **
  74    ** Attempt to skip 'n' number of bytes.  Return the number of bytes
  75    ** actually skipped which may be equal to or lesser than n.
  76    **
  77    virtual Int skip(Int n)
  78  
  79  //////////////////////////////////////////////////////////////////////////
  80  // Buf Support
  81  //////////////////////////////////////////////////////////////////////////
  82  
  83    **
  84    ** Read the entire contents of the stream into a memory Buf.
  85    ** The resulting buffer is automatically positioned at the beginning.
  86    ** This InStream is guaranteed to be closed.
  87    **
  88    Buf readAllBuf()
  89  
  90    **
  91    ** Read the next n bytes from the stream into the Buf at it's
  92    ** current position.  The buffer will be grown as needed.  If the
  93    ** buf parameter is null, then a buffer is automatically created
  94    ** with a capacity of n.  Block until exactly n bytes have been
  95    ** read or throw IOErr if end of stream is reached first.  Return
  96    ** the Buf passed in or the one created automatically if buf is null.
  97    ** The buffer is automatically positioned at the beginning.
  98    **
  99    Buf readBufFully(Buf buf, Int n)
 100  
 101  //////////////////////////////////////////////////////////////////////////
 102  // Binary Data
 103  //////////////////////////////////////////////////////////////////////////
 104  
 105    **
 106    ** Peek at the next byte to be read without actually consuming
 107    ** it.  Peek has the same semantics as a read/unread.  Return
 108    ** null if at end of stream.
 109    **
 110    Int peek()
 111  
 112    **
 113    ** Read the next byte as an unsigned 8-bit number in network
 114    ** byte order.  This method may be paired with OutStream.write.
 115    ** Throw IOErr on error or if the end of stream is reached before
 116    ** one byte can be read.  This method differs from read() in that
 117    ** it will throw IOErr on end of stream rather than return null.
 118    **
 119    Int readU1()
 120  
 121    **
 122    ** Read the next byte as a signed 8-bit number.  This method may be
 123    ** paired with `OutStream.write`.  Throw IOErr on error or if the end
 124    ** of stream is reached before one byte can be read.
 125    **
 126    Int readS1()
 127  
 128    **
 129    ** Read the next two bytes as an unsigned 16-bit number in network
 130    ** byte order.  This method may be paired with `OutStream.writeI2`.
 131    ** Throw IOErr on error or if the end of stream is reached before
 132    ** two bytes can be read.
 133    **
 134    Int readU2()
 135  
 136    **
 137    ** Read the next two bytes as a signed 16-bit number in network
 138    ** byte order.  This method may be paired with `OutStream.writeI2`.
 139    ** Throw IOErr on error or if the end of stream is reached before
 140    ** two bytes can be read.
 141    **
 142    Int readS2()
 143  
 144    **
 145    ** Read the next four bytes as an unsigned 32-bit number in network
 146    ** byte order.  This method may be paired with `OutStream.writeI4`.
 147    ** Throw IOErr on error or if the end of stream is reached before
 148    ** four bytes can be read.
 149    **
 150    Int readU4()
 151  
 152    **
 153    ** Read the next four bytes as a signed 32-bit number in network
 154    ** byte order.  This method may be paired with `OutStream.writeI4`.
 155    ** Throw IOErr on error or if the end of stream is reached before
 156    ** four bytes can be read.
 157    **
 158    Int readS4()
 159  
 160    **
 161    ** Read the next eight bytes as a signed 64-bit number in network
 162    ** byte order.  This method may be paired with `OutStream.writeI8`.
 163    ** Throw IOErr on error or if the end of stream is reached before
 164    ** eight bytes can be read.  Note there is no readU8 (because Java
 165    ** doesn't support unsigned longs).
 166    **
 167    Int readS8()
 168  
 169    **
 170    ** Read the next four bytes as a 32-bit floating point number in
 171    ** network byte order according to `Float.bits32`.  This method may be
 172    ** paired with `OutStream.writeF4`.  Throw IOErr on error or if the
 173    ** end of stream is reached before four bytes can be read.
 174    **
 175    Float readF4()
 176  
 177    **
 178    ** Read the next eight bytes as a 64-bit floating point number in
 179    ** network byte order according to `Float.bits`.  This method may be
 180    ** paired with `OutStream.writeF8`.  Throw IOErr on error or if the
 181    ** end of stream is reached before four bytes can be read.
 182    **
 183    Float readF8()
 184  
 185    **
 186    ** Read the next byte and return true if nonzero.  This method may
 187    ** be paired with `OutStream.writeBool`.  Throw IOErr on error or if
 188    ** the end of stream is reached before one byte can be read.
 189    **
 190    Bool readBool()
 191  
 192    **
 193    ** Read a Str in modified UTF-8 format according the java.io.DataInput
 194    ** specification. This method may be paired with `OutStream.writeUtf`.
 195    ** Throw IOErr on error, invalid UTF encoding, or if the end of stream
 196    ** is reached before the string is fully read.
 197    **
 198    Str readUtf()
 199  
 200  //////////////////////////////////////////////////////////////////////////
 201  // Text Data
 202  //////////////////////////////////////////////////////////////////////////
 203  
 204    **
 205    ** The current charset used to decode bytes into Unicode
 206    ** characters.  The default charset should always be UTF-8.
 207    **
 208    virtual Charset charset
 209  
 210    **
 211    ** Read a single Unicode character from the stream using the
 212    ** current charset encoding.  Return null if at end of stream.
 213    ** Throw IOErr if there is a problem reading the stream, or
 214    ** an invalid character encoding is encountered.
 215    **
 216    Int readChar()
 217  
 218    **
 219    ** Pushback a char so that it is the next char to be read.  This
 220    ** method pushes back one or more bytes depending on the current
 221    ** character encoding.  Return this.
 222    **
 223    InStream unreadChar(Int b)
 224  
 225    **
 226    ** Peek at the next char to be read without actually consuming
 227    ** it.  Peek has the same semantics as a readChar/unreadChar.
 228    ** Return null if at end of stream.
 229    **
 230    Int peekChar()
 231  
 232    **
 233    ** Read the next line from the input stream as a Str based on the
 234    ** configured charset.  A line is terminated by \n, \r\n, \r, or
 235    ** EOF.  The Str returned never contains the trailing newline.
 236    **
 237    ** The max parameter specifies the maximum number of Unicode
 238    ** chacters (not bytes) to read before truncating the line and
 239    ** returning.  If max is null, then no boundary is enforced except
 240    ** of course the end of the stream.  Max defaults to 4kb.
 241    **
 242    ** Return null if the end of stream has been reached.  Throw IOErr
 243    ** if there is a problem reading the stream or an invalid character
 244    ** encoding is encountered.
 245    **
 246    Str readLine(Int max := 4096)
 247  
 248    **
 249    ** Read a Str token from the input stream which is terminated
 250    ** when the specified function 'c' returns false.  The terminating
 251    ** char is unread and will be the next char read once this
 252    ** method returns.  Characters are read based on the currently
 253    ** configured charset.
 254    **
 255    ** If 'c' is null then the default implementation tokenizes up
 256    ** until the next character which returns true for `Int.isSpace`.
 257    **
 258    ** The max parameter specifies the maximum number of Unicode
 259    ** chacters (not bytes) to read before truncating the line and
 260    ** returning.  If max is null, then no boundary is enforced except
 261    ** of course the end of the stream.  Max defaults to 4kb.
 262    **
 263    ** Return null if the end of stream has been reached.  Throw IOErr
 264    ** if there is a problem reading the stream or an invalid character
 265    ** encoding is encountered.
 266    **
 267    Str readStrToken(Int max := 4096, |Int ch->Bool| c := null)
 268  
 269    **
 270    ** Read the entire stream into a list of Str lines based on the
 271    ** configured charset encoding.  Each Str in the list maps
 272    ** to a line terminated by \n, \r\n, \r, or EOF.  The Str lines
 273    ** themselves do not contain a trailing newline.  Empty lines
 274    ** are returned as the empty Str "".  Return an empty list if
 275    ** currently at end of stream (not null).  Throw IOErr if there
 276    ** is a problem reading the stream or an invalid character encoding
 277    ** is encountered.  This InStream is guaranteed to be closed upon
 278    ** return.
 279    **
 280    Str[] readAllLines()
 281  
 282    **
 283    ** Read the entire stream into Str lines based on the current
 284    ** encoding.  Call the specified function for each line read.
 285    ** Each line is terminated by \n, \r\n, \r, or EOF.  The Str
 286    ** lines themselves do not contain a trailing newline.  Empty
 287    ** lines are returned as the empty Str "".  This InStream is
 288    ** guaranteed to be closed upon return.
 289    **
 290    Void eachLine(|Str line| f)
 291  
 292    **
 293    ** Read the entire stream into a Str based on the configured
 294    ** charset encoding.  If the normalizeNewlines flag is true,
 295    ** then all occurances of \r\n or \r newlines are normalized
 296    ** into \n.  Return "" if the stream is empty.  Throw IOErr if
 297    ** there is a problem reading the stream or an invalid character
 298    ** encoding is encountered.  This InStream is guaranteed to
 299    ** be closed.
 300    **
 301    Str readAllStr(Bool normalizeNewlines := true)
 302  
 303    **
 304    ** Read a serialized object from the stream according to
 305    ** the Fan [serialization format]`docLang::Serialization`.
 306    ** Throw IOErr or ParseErr on error.  This method may consume
 307    ** bytes/chars past the end of the serialized object (we may
 308    ** want to add a "full stop" token at some point to support
 309    ** compound object streams).
 310    **
 311    ** The options may be used to specify additional decoding
 312    ** logic:
 313    **   - "makeArgs": Obj[] arguments to pass to the root
 314    **     object's make constructor via 'Type.make'
 315    **
 316    Obj readObj(Str:Obj options := null)
 317  
 318  //////////////////////////////////////////////////////////////////////////
 319  // Utils
 320  //////////////////////////////////////////////////////////////////////////
 321  
 322    **
 323    ** Read the entire stream into a Str:Str of name value pairs using the
 324    ** Fan props file format.  This format is similiar but different than
 325    ** the Java properties file format:
 326    **   - Input must be UTF-8 encoded (current charset is ignored)
 327    **   - Name/value pairs formatted as logical line: <name>"="<value>
 328    **   - Any Unicode character allowed in name or value
 329    **   - Leading and trailing whitespace trimmed from both name and value
 330    **   - Duplicate name keys within one file is an error condition
 331    **   - Comment to end of line is '//' if start of line or preceeded
 332    **     by whitespace
 333    **   - Block comment is '/* */' (may be nested)
 334    **   - Use trailing \ to continue logical line to another actual line,
 335    **     any leading whitespace (space or tab char) is trimmed from beginning
 336    **     of continued line
 337    **   - Fan Str literal escape sequences supported: \n \r \t or \uxxxx
 338    **   - The $ character is treated as a normal character and should not be
 339    **     escaped, but convention is to indicate a variable in a format string
 340    **   - Convention is that name is lower camel case with dot separators
 341    **
 342    ** Throw IOErr if there is a problem reading the stream or an invalid
 343    ** props format is encountered.  This InStream is guaranteed to be closed.
 344    **
 345    Str:Str readProps()
 346  
 347    **
 348    ** Pipe bytes from this input stream to the specified output stream.
 349    ** If n is specified, then block until exactly n bytes have been
 350    ** read or throw IOErr if end of stream is reached first.  If n is
 351    ** null then the entire contents of this input stream are piped.  If
 352    ** close is true, then this input stream is guaranteed to be closed
 353    ** upon return (the OutStream is never closed).  Return the number
 354    ** of bytes piped to the output stream.
 355    **
 356    Int pipe(OutStream out, Int n := null, Bool close := true)
 357  
 358  }
 359  
 360  **************************************************************************
 361  ** SysInStream
 362  **************************************************************************
 363  
 364  internal class SysInStream : InStream
 365  {
 366    override Int read()
 367    override Int readBuf(Buf buf, Int n)
 368    override InStream unread(Int n)
 369    override Bool close()
 370  }