\ Preprocessor Stream Class - Copyright 2022 J.L. Bezemer
\ You can redistribute this file and/or modify it under
\ the terms of the GNU General Public License

[UNDEFINED] Stream [IF]
\ Typical use:
\   s" myfile" input instance Stream myFile
\   myFile -> ferror     abort" Cannot open file"
\   myFile -> freadln 0= abort" Cannot read line"
\   myFile delete

\ ftell                                ( -- n)
\ fseek                                ( n -- f)
\ fread                                ( a1 n1 -- n2)
\ freadln                              ( -- f)
\ fwrite                               ( a n --)
\ fwriteln                             ( a n --)
\ fmode                                ( -- n)
\ ferror                               ( -- f)

:class Stream                          \ wrapper for files
  extends Object
     field: (handle)                   \ contains the handle
     field: (mode)                     \ contains the file mode
     field: (status)                   \ contains an error flag
    method: ftell                      \ like TELL
    method: fseek                      \ like SEEK
    method: fread                      \ like ACCEPT
    method: freadln                    \ like REFILL
    method: fwrite                     \ like TYPE
    method: fwriteln                   \ like TYPE CR
    method: fmode                      \ getter for (mode)
    method: ferror                     \ getter for (status)
    method: fuse                       \ like USE (private method)
  end-extends
                                       \ constructor like OPEN
  :new                                 ( a1 n1 n2 --)
    dup                                \ duplicate the mode
    this -> (mode)   ! open error?     \ save its mode, open file
    this -> (status) !                 \ save its status,
    this -> (handle) !                 \ and the handle
  ;method

  :method ftell this -> (handle) @ tell ;method
  :method fseek this -> (handle) @ seek ;method
  :method fuse  this -> (handle) @ use  ;method
  :method fread this -> fuse accept     ;method
  :method freadln this -> fuse refill   ;method
  :method fwrite this -> fuse type      ;method
  :method fwriteln this -> fwrite cr    ;method
  :method fmode this -> (mode) @        ;method
  :method ferror this -> (status) @     ;method
                                       \ close file if no errors
  :delete this -> ferror unless this -> (handle) @ close then ;method

  private{ (handle) (mode) (status) fuse }
;class
[THEN]

