(DEFINE-FILE-INFO READTABLE "INTERLISP" PACKAGE "INTERLISP")
(FILECREATED "13-Sep-90 16:39:58" |{PELE:MV:ENVOS}<LISPCORE>SOURCES>AOFD.;4| 34722  

      changes to%:  (FNS \BASEBYTES.IO.INIT \BASEBYTES.SETFILEPTR)

      previous date%: "16-May-90 12:01:06" |{PELE:MV:ENVOS}<LISPCORE>SOURCES>AOFD.;3|)


(* ; "
Copyright (c) 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1990 by Venue & Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT AOFDCOMS)

(RPAQQ AOFDCOMS
       [

(* ;;; "streams (= OpenFileDescriptors)")

        (COMS (FNS \ADD-OPEN-STREAM \GENERIC-UNREGISTER-STREAM)
              (INITVARS (*ISSUE-CLOSE-WARNINGS* NIL))
              (FNS CLOSEALL CLOSEF EOFCLOSEF INPUT OPENP OUTPUT POSITION RANDACCESSP \IOMODEP 
                   WHENCLOSE)
              (FNS STREAMADDPROP)
              (INITVARS (DEFAULTEOFCLOSE 'NILL)
                     (\OPENFILES))
              (GLOBALVARS DEFAULTEOFCLOSE \OPENFILES))
        (COMS 
              (* ;; "STREAM interface to Read and Write to random memory")

              (DECLARE%: DONTCOPY (EXPORT (RECORDS BASEBYTESTREAM)))
              (FNS \BASEBYTES.IO.INIT \MAKEBASEBYTESTREAM \MBS.OUTCHARFN \BASEBYTES.NAME.FROM.STREAM
                   \BASEBYTES.BOUT \BASEBYTES.SETFILEPTR \BASEBYTES.READP \BASEBYTES.BIN 
                   \BASEBYTES.PEEKBIN \BASEBYTES.TRUNCATEFN \BASEBYTES.OPENFN \BASEBYTES.BLOCKIO)
              (GLOBALVARS \BASEBYTESDEVICE)
              (DECLARE%: DONTEVAL@LOAD (P (\BASEBYTES.IO.INIT)))
              (FNS OPENSTRINGSTREAM))
        [COMS 
              (* ;; "STREAM interface for old-style strings")

              (FNS \STRINGSTREAM.INIT)
              (DECLARE%: DONTEVAL@LOAD DOCOPY (P (\STRINGSTREAM.INIT]
        (COMS (FNS GETSTREAM \ADDOFD \CLEAROFD \DELETEOFD \GETSTREAM \SEARCHOPENFILES)
              (DECLARE%: DONTCOPY (EXPORT (MACROS \INSTREAMARG \OUTSTREAMARG \STREAMARG)))
              (MACROS GETOFD \GETOFD))
        (LOCALVARS . T)
        (DECLARE%: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA)
                                                                             (NLAML)
                                                                             (LAMA WHENCLOSE])



(* ;;; "streams (= OpenFileDescriptors)")

(DEFINEQ

(\ADD-OPEN-STREAM
  [LAMBDA (DEVICE STREAM)                                    (* hdj "28-May-86 11:22")
    (if (NOT (STREAMP STREAM))
        then (\ILLEGAL.ARG STREAM))
    (pushnew (fetch (FDEV OPENFILELST) of DEVICE)
           STREAM)
    STREAM])

(\GENERIC-UNREGISTER-STREAM
  [LAMBDA (DEVICE STREAM)                                    (* hdj "22-Sep-86 18:30")

(* ;;; "Remove an open stream from the list of streams kept by DEVICE.  Assumes the use of the FDEV's OPENFILELSTto store the streams.  Errors if passed a stream the device doesn't know about if *ISSUE-CLOSE-WARNINGS* is non-NIL.")

    (DECLARE (GLOBALVARS *ISSUE-CLOSE-WARNINGS*))
    (if (NOT (STREAMP STREAM))
        then (\ILLEGAL.ARG STREAM))
    (LET ((OPENFILELST (fetch (FDEV OPENFILELST) of DEVICE)))
         (if (AND *ISSUE-CLOSE-WARNINGS* (NOT (FMEMB STREAM OPENFILELST)))
             then (ERROR "Closing a stream that's not open!" STREAM))
         (replace (FDEV OPENFILELST) of DEVICE with (DREMOVE STREAM OPENFILELST))
         STREAM])
)

(RPAQ? *ISSUE-CLOSE-WARNINGS* NIL)
(DEFINEQ

(CLOSEALL
  [LAMBDA (ALLFLG)
    (DECLARE (LOCALVARS . T))                                (* hdj "11-Jul-86 10:33")
    (if MULTIPLE.STREAMS.PER.FILE.ALLOWED
        then (ERROR "CLOSEALL no longer supported")
      else (for STREAM in (PROG1 (APPEND \OPENFILES)         (* ; 
                                   "Need to APPEND because CLOSEF will remove things from \OPENFILES")
                                 ) when [AND (fetch USERVISIBLE of STREAM)
                                             (\IOMODEP STREAM NIL T)
                                             (OR ALLFLG (NOT (STREAMPROP STREAM 'CLOSEALL]
              collect (CLOSEF STREAM])

(CLOSEF
  [LAMBDA (FILE)                                             (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG ((STREAM (\GETSTREAM FILE)))
          (COND
             ((OR (\OUTTERMP STREAM)
                  (NOT (fetch USERCLOSEABLE of STREAM)))
              (RETURN NIL)))
          [MAPC (STREAMPROP STREAM 'BEFORECLOSE)
                (FUNCTION (LAMBDA (FN)
                            (APPLY* FN STREAM]
          (\CLEAROFD)
          (COND
             ((EQ STREAM *STANDARD-INPUT*)
              (SETQ *STANDARD-INPUT* \LINEBUF.OFD)))
          (COND
             ((EQ STREAM *STANDARD-OUTPUT*)
              (SETQ *STANDARD-OUTPUT* \TERM.OFD)))
          (AND (NOT MULTIPLE.STREAMS.PER.FILE.ALLOWED)
               (\DELETEOFD STREAM))
          
          (* ;; "Logical close before physical close;  otherwise, we might have a logically open file with no physically open file behind it.  (Device LPT depends on this)")

          (\CLOSEFILE STREAM)
          [MAPC (STREAMPROP STREAM 'AFTERCLOSE)
                (FUNCTION (LAMBDA (FN)
                            (APPLY* FN STREAM]
          (RETURN (fetch FULLNAME of STREAM])

(EOFCLOSEF
  [LAMBDA (FILE)                                             (* bvm%: "15-Jan-85 17:58")
    (DECLARE (LOCALVARS . T))
    (PROG ((STREAM (GETSTREAM FILE)))
          (APPLY* (OR (STREAMPROP STREAM 'EOFCLOSE)
                      DEFAULTEOFCLOSE)
                 STREAM])

(INPUT
  [LAMBDA (FILE)                                             (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG1 (if (EQ *STANDARD-INPUT* \LINEBUF.OFD)
               then T
             else (if MULTIPLE.STREAMS.PER.FILE.ALLOWED
                      then *STANDARD-INPUT*
                    else (fetch FULLNAME of *STANDARD-INPUT*)))
           (COND
              (FILE (SETQ *STANDARD-INPUT* (COND
                                              ((EQ FILE T)   (* ; 
                                                 "Check explicitly for T to avoid needless creations")
                                               \LINEBUF.OFD)
                                              (T (\GETSTREAM FILE 'INPUT])

(OPENP
  [LAMBDA (FILE ACCESS)                                      (* hdj "29-Sep-86 17:41")
    (DECLARE (GLOBALVARS MULTIPLE.STREAMS.PER.FILE.ALLOWED \FILEDEVICES))
    (if (AND FILE (type? STREAM FILE))
        then (\GETSTREAM FILE ACCESS T)
      elseif FILE
        then NIL
      else (\MAP-OPEN-STREAMS (FUNCTION EVQ)
                  \FILEDEVICES NIL])

(OUTPUT
  [LAMBDA (FILE)                                             (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG1 (if (EQ *STANDARD-OUTPUT* \TERM.OFD)
               then T
             else (if MULTIPLE.STREAMS.PER.FILE.ALLOWED
                      then *STANDARD-OUTPUT*
                    else (fetch FULLNAME of *STANDARD-OUTPUT*)))
           (COND
              (FILE (SETQ *STANDARD-OUTPUT* (COND
                                               ((EQ FILE T)  (* ; 
                                  "Check for this special so we don't create a tty window needlessly")
                                                \TERM.OFD)
                                               (T (\GETSTREAM FILE 'OUTPUT])

(POSITION
  [LAMBDA (FILE N)                                           (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG [(STRM (COND
                    (FILE (\GETSTREAM FILE))
                    (T *STANDARD-OUTPUT*]
          (RETURN (PROG1 (fetch CHARPOSITION of STRM)
                         (COND
                            (N (replace CHARPOSITION of STRM with (COND
                                                                     ((IGREATERP N 0)
                                                                      N)
                                                                     (T 
                                                             (* ; "compatible with PDP-10 version")
                                                                        0])

(RANDACCESSP
  [LAMBDA (FILE)                                             (* rmk%: "14-OCT-83 15:32")
    (PROG ((STREAM (\GETSTREAM FILE)))
          (RETURN (AND (fetch RANDOMACCESSP of (fetch DEVICE of STREAM))
                       (NEQ STREAM \LINEBUF.OFD)
                       (fetch FULLNAME of STREAM])

(\IOMODEP
  [LAMBDA (STREAM ACCESS NOERROR)                            (* rmk%: "21-OCT-83 11:10")
          
          (* ;; "Returns STREAM if it represents a File open with access mode ACCESS")

    (COND
       ([COND
           ((NOT ACCESS)
            (fetch ACCESS of STREAM))
           ((EQ ACCESS (fetch ACCESS of STREAM)))
           [(EQ (fetch ACCESS of STREAM)
                'BOTH)
            (FMEMB ACCESS '(INPUT OUTPUT]
           ((EQ (fetch ACCESS of STREAM)
                'APPEND)
            (EQ ACCESS 'OUTPUT]
        STREAM)
       (T (\FILE.NOT.OPEN STREAM NOERROR])

(WHENCLOSE
  [LAMBDA NARGS                                              (* lmm " 2-Sep-84 16:07")
    (DECLARE (LOCALVARS . T))
    (PROG [(STREAM (AND (IGREATERP NARGS 0)
                        (GETSTREAM (ARG NARGS 1]
          [for I FN from 2 to NARGS by 2
             do [SETQ FN (AND (IGREATERP NARGS I)
                              (ARG NARGS (ADD1 I]
                (SELECTQ (ARG NARGS I)
                    (CLOSEALL [STREAMPROP STREAM 'CLOSEALL (SELECTQ FN
                                                               (NO T)
                                                               (YES NIL)
                                                               (ERRORX (LIST 27 FN])
                    (BEFORE (COND
                               (FN (STREAMADDPROP STREAM 'BEFORECLOSE FN T))))
                    (AFTER (COND
                              (FN (STREAMADDPROP STREAM 'AFTERCLOSE FN T))))
                    (STATUS (STREAMPROP STREAM 'STATUSFN FN))
                    (EOF (STREAMPROP STREAM 'EOFCLOSE FN))
                    (ERRORX (LIST 27 (ARG NARGS I]
          (RETURN STREAM])
)
(DEFINEQ

(STREAMADDPROP
  [LAMBDA (STREAM PROP VAL)
    (STREAMPROP STREAM PROP (CONS VAL (STREAMPROP STREAM PROP])
)

(RPAQ? DEFAULTEOFCLOSE 'NILL)

(RPAQ? \OPENFILES )
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS DEFAULTEOFCLOSE \OPENFILES)
)



(* ;; "STREAM interface to Read and Write to random memory")

(DECLARE%: DONTCOPY 
(* "FOLLOWING DEFINITIONS EXPORTED")

(DECLARE%: EVAL@COMPILE

(RECORD BASEBYTESTREAM STREAM (SUBRECORD STREAM)
                                 [ACCESSFNS ((BIASOFFST (fetch (STREAM FW6) of DATUM)
                                                    (replace (STREAM FW6) of DATUM
                                                       with NEWVALUE))
                                             (BBSNCHARS (fetch (STREAM FW7) of DATUM)
                                                    (replace (STREAM FW7) of DATUM
                                                       with NEWVALUE))
                                             (WRITEXTENSIONFN (fetch (STREAM F1) of DATUM)
                                                    (replace (STREAM F1) of DATUM
                                                       with NEWVALUE])
)

(* "END EXPORTED DEFINITIONS")

)
(DEFINEQ

(\BASEBYTES.IO.INIT
  [LAMBDA NIL
    (DECLARE (GLOBALVARS \BASECHARDEVICE))           (* ; "Edited 13-Sep-90 16:27 by jds")

    (* ;; "Initialize the FDEV for base-bytes type devices (e.g. string streams).")

    (SETQ \BASEBYTESDEVICE
     (create FDEV
            DEVICENAME _ 'BASEBYTES
            RESETABLE _ T
            RANDOMACCESSP _ T
            PAGEMAPPED _ NIL
            FDBINABLE _ T
            FDBOUTABLE _ T
            FDEXTENDABLE _ NIL
            CLOSEFILE _ (FUNCTION NILL)
            DELETEFILE _ (FUNCTION NILL)
            DIRECTORYNAMEP _ (FUNCTION NILL)
            EVENTFN _ (FUNCTION NILL)
            GENERATEFILES _ (FUNCTION \GENERATENOFILES)
            GETFILEINFO _ (FUNCTION NILL)
            GETFILENAME _ (FUNCTION \BASEBYTES.NAME.FROM.STREAM)
            HOSTNAMEP _ (FUNCTION NILL)
            OPENFILE _ (FUNCTION \BASEBYTES.OPENFN)
            READPAGES _ (FUNCTION NILL)
            REOPENFILE _ [FUNCTION (LAMBDA (FILE ACCESS RECOG OTHERINFO FDEV STREAM)
                                     STREAM]
            SETFILEINFO _ (FUNCTION NILL)
            TRUNCATEFILE _ [FUNCTION (LAMBDA (STREAM I]
            WRITEPAGES _ (FUNCTION \ILLEGAL.DEVICEOP)
            BIN _ (FUNCTION \BASEBYTES.BIN)
            BOUT _ (FUNCTION \BASEBYTES.BOUT)
            PEEKBIN _ (FUNCTION \BASEBYTES.PEEKBIN)
            READP _ (FUNCTION \BASEBYTES.READP)
            BACKFILEPTR _ [FUNCTION (LAMBDA (STREAM)

                                      (* ;; "Back up the file pointer")

                                      (AND (NEQ (fetch COFFSET of STREAM)
                                                (fetch BIASOFFST of STREAM))
                                           (\PAGEDBACKFILEPTR STREAM))

                                      (* ;; "And fix charposition.")

                                      (replace BBSNCHARS of STREAM
                                         with (IDIFFERENCE (fetch COFFSET of STREAM)
                                                         (fetch BIASOFFST of STREAM]
            SETFILEPTR _ (FUNCTION \BASEBYTES.SETFILEPTR)
            GETFILEPTR _ [FUNCTION (LAMBDA (STREAM)
                                     (IDIFFERENCE (fetch COFFSET of STREAM)
                                            (fetch BIASOFFST of STREAM]
            GETEOFPTR _ [FUNCTION (LAMBDA (STREAM)
                                    (IDIFFERENCE (fetch EOFFSET of STREAM)
                                           (fetch BIASOFFST of STREAM]
            EOFP _ [FUNCTION (LAMBDA (STREAM)
                               (IGEQ (fetch COFFSET of STREAM)
                                     (fetch EOFFSET of STREAM]
            BLOCKIN _ [FUNCTION (LAMBDA (STREAM BASE OFFST N)
                                  (\BASEBYTES.BLOCKIO STREAM BASE OFFST N 'INPUT]
            BLOCKOUT _ [FUNCTION (LAMBDA (STREAM BASE OFFST N)
                                   (\BASEBYTES.BLOCKIO STREAM BASE OFFST N 'OUTPUT]
            RENAMEFILE _ (FUNCTION \ILLEGAL.DEVICEOP)))
    (\DEFINEDEVICE NIL \BASEBYTESDEVICE])

(\MAKEBASEBYTESTREAM
  [LAMBDA (BASE OFFST LEN ACCESS WRITEXTENSIONFN OSTREAM)    (* ; "Edited 17-Jan-87 16:08 by bvm:")
          
          (* ;; "If an error is to occur due to non-numeric arg or range restrictions, then let it happen outside the UNINTERRUPTABLY")

    (OR BASE (EQ LEN 0)
        (SHOULDNT))
    (OR (AND (SMALLP OFFST)
             (SMALLP LEN)
             (SMALLP (add LEN OFFST)))
        (SHOULDNT "Currently can't support fixp-sized offsets"))
    (SELECTQ ACCESS
        (NIL (SETQ ACCESS 'INPUT))
        ((INPUT OUTPUT BOTH))
        (\ILLEGAL.ARG ACCESS))
    (if (type? STREAM OSTREAM)
        then (if (EQ (ffetch (STREAM DEVICE) of OSTREAM)
                     \BASEBYTESDEVICE)
                 then (replace ACCESS of OSTREAM with NIL)
               else (CLOSEF OSTREAM)
                    (SETQ OSTREAM (create BASEBYTESTREAM
                                         DEVICE _ \BASEBYTESDEVICE smashing OSTREAM)))
      else (SETQ OSTREAM (create BASEBYTESTREAM
                                DEVICE _ \BASEBYTESDEVICE)))
    (UNINTERRUPTABLY
        (freplace USERCLOSEABLE of OSTREAM with NIL)
        (freplace USERVISIBLE of OSTREAM with NIL)
        (freplace BYTESIZE of OSTREAM with BITSPERBYTE)
        (freplace CPAGE of OSTREAM with (freplace EPAGE of OSTREAM with 0))
        (freplace CBUFPTR of OSTREAM with BASE)
        (freplace COFFSET of OSTREAM with (freplace BIASOFFST of OSTREAM with OFFST))
        (freplace CBUFSIZE of OSTREAM with (freplace EOFFSET of OSTREAM with LEN))
        (replace ACCESS of OSTREAM with ACCESS)
          
          (* ;; "Insures that the BINABLE BOUTABLE and EXTENDABLE bits are setup setup, and that the correct BIN and BOUT fns are 'inherited' from the FDEV as well")

        (freplace FULLFILENAME of OSTREAM with NIL)
        (freplace OUTCHARFN of OSTREAM with (FUNCTION \MBS.OUTCHARFN))
        (freplace LINELENGTH of OSTREAM with 0)
        (freplace CHARPOSITION of OSTREAM with 0)
        (freplace WRITEXTENSIONFN of OSTREAM with (SELECTQ ACCESS
                                                      ((OUTPUT BOTH) 
                                                           WRITEXTENSIONFN)
                                                      NIL))
        (freplace BBSNCHARS of OSTREAM with 0))
    OSTREAM])

(\MBS.OUTCHARFN
  [LAMBDA (STREAM CHAR)                                      (* JonL " 7-NOV-83 21:54")
    (BOUT (SETQ STREAM (\DTEST STREAM 'STREAM))
          CHAR)                                              (* ; 
                "The BBSNCHARS field *may* just be paralleling the CHARPOSITION field of the stream.")
    (add (ffetch BBSNCHARS of STREAM)
         1])

(\BASEBYTES.NAME.FROM.STREAM
  [LAMBDA (STREAM)                                           (* ; "Edited 17-Jan-87 16:08 by bvm:")
          
          (* ;; "STRING streams have a FULLFILENAME which is just the string itself;  other random basebytes streams have this field null")

    (OR (fetch FULLFILENAME of STREAM)
        (LIST (fetch CBUFPTR of STREAM)
              (fetch BIASOFFST of STREAM)
              (GETEOFPTR STREAM])

(\BASEBYTES.BOUT
  [LAMBDA (STREAM BYTE)                                      (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG (CO)
      A   (if (IGEQ (SETQ CO (fetch COFFSET of STREAM))
                    (fetch EOFFSET of STREAM))
              then (if (SETQ CO (fetch (BASEBYTESTREAM WRITEXTENSIONFN) of STREAM))
                       then (APPLY* CO STREAM)
                            (GO A)
                     else (ERROR "Attempt to write past end of bytes block")))
          (RETURN (\PUTBASEBYTE (fetch CBUFPTR of STREAM)
                         (PROG1 CO (freplace COFFSET of STREAM with (ADD1 CO)))
                         BYTE])

(\BASEBYTES.SETFILEPTR
  [LAMBDA (STREAM I)                                     (* ; "Edited 13-Sep-90 16:30 by jds")

    (* ;; "SETFILEPTR for string streams &c.")

    (PROG ((I' I))
          (add I' (fetch BIASOFFST of STREAM))
          (if (IGREATERP I' (fetch EOFFSET of STREAM))
              then (ERROR "Beyond end of byte range" I)
            else 

                  (* ;; "Fix both FILEPTR and CHARPOSITION to match.")

                  (replace COFFSET of STREAM with I')
                  (replace BBSNCHARS of STREAM with I'])

(\BASEBYTES.READP
  [LAMBDA (STREAM FLG)                                       (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG ((CO (fetch COFFSET of STREAM))
           (%#LEFT (fetch EOFFSET of STREAM)))
          (add %#LEFT (IMINUS CO))
          (RETURN (OR (IGEQ %#LEFT 2)
                      (if (EQ %#LEFT 0)
                          then NIL
                        elseif FLG
                        else (NEQ (\GETBASEBYTE (fetch CBUFPTR of STREAM)
                                         (fetch COFFSET of STREAM))
                                  (CHARCODE CR])

(\BASEBYTES.BIN
  [LAMBDA (STREAM)                                           (* JonL " 7-NOV-83 22:49")
          
          (* ;; "Normally, the microcoded version of BIN will handle this, since the BINABLE flag is set and since the COFFSET etc fields are setup appropriately")
          
          (* ;; 
        "Remember also that the VAX version installs a different STRMBINFN for the stringstream case")

    (PROG1 (\BASEBYTES.PEEKBIN STREAM)
           (add (fetch COFFSET of STREAM)
                1])

(\BASEBYTES.PEEKBIN
  [LAMBDA (STREAM NOERRORFLG)                                (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG ((CO (fetch COFFSET of STREAM)))
          (SELECTQ (SYSTEMTYPE)
              (VAX (if (fetch FULLNAME of STREAM)
                       then                                  (* ; "Aha, it's a string stream")
                            (RETURN (\STRINGPEEKBIN STREAM NOERRORFLG))))
              NIL)
          (RETURN (if (IGEQ CO (fetch EOFFSET of STREAM))
                      then (if (NOT NOERRORFLG)
                               then (STREAMOP 'ENDOFSTREAMOP STREAM STREAM))
                    else (\GETBASEBYTE (fetch CBUFPTR of STREAM)
                                CO])

(\BASEBYTES.TRUNCATEFN
  [LAMBDA (STREAM I)                                         (* JonL " 7-NOV-83 22:20")
    ([LAMBDA (I' BO EO)
       (add I' BO)
       (if (ILESSP I 0)
           then (add I' EO))
       (if (OR (ILESSP I BO)
               (IGREATERP I' EO))
           then (ERROR "Beyond end of byte range" I)
         else (replace EOFFSET of STREAM with I']
     I
     (fetch BIASOFFST of STREAM)
     (fetch EOFFSET of STREAM])

(\BASEBYTES.OPENFN
  [LAMBDA (NAME ACCESS RECOG OTHERINFO FDEV)                 (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (if (fetch FULLFILENAME of NAME)
        then (OPENSTRINGSTREAM NAME ACCESS)
      else (\MAKEBASEBYTESTREAM (fetch CBUFPTR of NAME)
                  (fetch BIASOFFST of NAME)
                  (GETEOFPTR NAME)
                  ACCESS
                  (fetch WRITEXTENSIONFN of NAME)
                  NAME])

(\BASEBYTES.BLOCKIO
  [LAMBDA (STREAM BASE OFFST N DIRECTION)                    (* ; "Edited 17-Jan-87 16:08 by bvm:")
    (PROG (SBASE CO EO)
      A   (if (ILEQ N 0)
              then (RETURN))
          (SETQ SBASE (fetch CBUFPTR of STREAM))
          (SETQ CO (fetch COFFSET of STREAM))
          (SETQ EO (fetch EOFFSET of STREAM))
          (if (IGREATERP N (IDIFFERENCE EO (SUB1 CO)))
              then (if (EQ DIRECTION 'INPUT)
                       then (STREAMOP 'ENDOFSTREAMOP STREAM STREAM)
                     else                                    (* ; 
                                      "Do a single BOUT to see if the WRITEXTENSIONFN will fix it up")
                          (BOUT STREAM (\GETBASEBYTE BASE OFFST))
                          (add OFFST 1)
                          (add N -1)
                          (GO A)))
          (replace COFFSET of STREAM with (IPLUS CO N))
          (if (EQ DIRECTION 'OUTPUT)
              then (swap SBASE BASE)
                   (swap CO OFFST))
          (\MOVEBYTES SBASE CO BASE OFFST N])
)
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS \BASEBYTESDEVICE)
)
(DECLARE%: DONTEVAL@LOAD 

(\BASEBYTES.IO.INIT)
)
(DEFINEQ

(OPENSTRINGSTREAM
  [LAMBDA (STR ACCESS)                                       (* rmk%: "28-Mar-85 08:40")
          
          (* ;; "Does not register the stream on \OPENFILES, nor does it search \OPENFILES for a previously opened stream.  Thus, this implementation does not side-effect the string as the 10 does.  However, the temporary coercion of strings to open streams in \GETSTREAM does simulate the side-effecting.  Note that a string stream is unnamed.")

    (PROG (STREAM FATP)
          (OR (STRINGP STR)
              (\ILLEGAL.ARG STR))
          (SETQ FATP (ffetch (STRINGP FATSTRINGP) of STR))
          [SETQ STREAM (\MAKEBASEBYTESTREAM (OR (ffetch (STRINGP BASE) of STR)
                                                T)
                              (COND
                                 (FATP (UNFOLD (ffetch (STRINGP OFFST) of STR)
                                              BYTESPERWORD))
                                 (T (ffetch (STRINGP OFFST) of STR)))
                              (COND
                                 (FATP (UNFOLD (ffetch (STRINGP LENGTH) of STR)
                                              BYTESPERWORD))
                                 (T (ffetch (STRINGP LENGTH) of STR)))
                              (SELECTQ ACCESS
                                  ((INPUT OUTPUT BOTH) 
                                       ACCESS)
                                  (NIL 'INPUT)
                                  (\ILLEGAL.ARG ACCESS]
          (PROGN                                             (* ; 
                                      "Minor differences between a basebytestream and a stringstream")
                 (if FATP
                     then (freplace (STREAM CHARSET) of STREAM with \NORUNCODE))
                 (freplace USERCLOSEABLE of STREAM with T)
                 (freplace USERVISIBLE of STREAM with T)
                 (SELECTQ (SYSTEMTYPE)
                     (VAX (freplace F2 of STREAM with 0)
                          (freplace STRMBINFN of STREAM with (FUNCTION \STRINGBIN)))
                     NIL))
          (RETURN STREAM])
)



(* ;; "STREAM interface for old-style strings")

(DEFINEQ

(\STRINGSTREAM.INIT
  [LAMBDA NIL                                                (* bvm%: "14-Feb-85 00:25")
    (SETQ \STRINGSTREAM.FDEV (create FDEV
                                    DEVICENAME _ 'STRING
                                    CLOSEFILE _ (FUNCTION NILL)
                                    DELETEFILE _ (FUNCTION NILL)
                                    DIRECTORYNAMEP _ (FUNCTION NILL)
                                    EVENTFN _ (FUNCTION NILL)
                                    GENERATEFILES _ (FUNCTION \NULLFILEGENERATOR)
                                    GETFILEINFO _ (FUNCTION NILL)
                                    GETFILENAME _ (FUNCTION NILL)
                                    HOSTNAMEP _ (FUNCTION NILL)
                                    OPENFILE _ (FUNCTION NILL)
                                    READPAGES _ (FUNCTION \ILLEGAL.DEVICEOP)
                                    REOPENFILE _ [FUNCTION (LAMBDA (FILE ACCESS RECOG OTHERINFO FDEV 
                                                                         STREAM)
                                                             STREAM]
                                    SETFILEINFO _ (FUNCTION NILL)
                                    TRUNCATEFILE _ (FUNCTION NILL)
                                    WRITEPAGES _ (FUNCTION \ILLEGAL.DEVICEOP)
                                    BIN _ [FUNCTION (LAMBDA (STREAM)
                                                      (replace F2 of STREAM
                                                         with (COND
                                                                 ((fetch F1 of STREAM)
                                                                  (PROG1 (fetch F1 of STREAM)
                                                                         (replace F1 of STREAM
                                                                            with NIL)))
                                                                 ((GNCCODE (fetch FULLFILENAME
                                                                              of STREAM)))
                                                                 (T (\EOF.ACTION STREAM]
                                    PEEKBIN _ [FUNCTION (LAMBDA (STREAM NOERRORFLG)
                                                          (OR (fetch F1 of STREAM)
                                                              (CHCON1 (fetch FULLFILENAME
                                                                         of STREAM))
                                                              (AND (NOT NOERRORFLG)
                                                                   (\EOF.ACTION STREAM]
                                    READP _ [FUNCTION (LAMBDA (STREAM)
                                                        (NOT (EOFP STREAM]
                                    BACKFILEPTR _ [FUNCTION (LAMBDA (STREAM)
                                                              (replace F1 of STREAM
                                                                 with (fetch F2 of STREAM]
                                    EOFP _ (FUNCTION (LAMBDA (STREAM)
                                                       (AND (NOT (fetch F1 of STREAM))
                                                            (EQ (NCHARS (fetch FULLFILENAME
                                                                           of STREAM))
                                                                0])
)
(DECLARE%: DONTEVAL@LOAD DOCOPY 

(\STRINGSTREAM.INIT)
)
(DEFINEQ

(GETSTREAM
  [LAMBDA (FILE ACCESS NOERROR)                              (* rrb "31-Oct-85 09:36")
                                                             (* ; "USER ENTRY")
    (\GETSTREAM FILE ACCESS NOERROR])

(\ADDOFD
  [LAMBDA (STREAM)                                           (* rmk%: "21-OCT-83 16:32")
          
          (* ;; "Returns the STREAM it adds to \OPENFILES")

    (\CLEAROFD)
    (AND (fetch NAMEDP of STREAM)
         (push \OPENFILES STREAM))
    STREAM])

(\CLEAROFD
  [LAMBDA NIL                                                (* lmm "30-SEP-80 20:08")
                                                             (* ; 
                                                "If GETOFD caches its args, this can clear the cache")
    NIL])

(\DELETEOFD
  [LAMBDA (OFD)                                              (* rmk%: "25-OCT-79 08:20")
    (SETQ \OPENFILES (DREMOVE OFD \OPENFILES])

(\GETSTREAM
  [LAMBDA (X ACCESS NOERROR)                                 (* ; "Edited 17-Jan-87 16:08 by bvm:")
          
          (* ;; "\GETSTREAM accepts a stream, NIL, T, or a window, and returns a corresponding stream.  ACCESS is INPUT, OUTPUT, APPEND, BOTH or NIL.  NOERROR, if non-NIL, means to return NIL if the file is not open in the specified access mode; otherwise, an error is caused.")

    (DECLARE (GLOBALVARS \DEFAULTLINEBUF \DEFAULTTTYDISPLAYSTREAM))
    (COND
       ((NULL X)
        (SELECTQ ACCESS
            (INPUT (COND
                      ((AND (EQ *STANDARD-INPUT* \DEFAULTLINEBUF)
                            (EQ \KEYBOARD.STREAM (fetch (LINEBUFFER KEYBOARDSTREAM) of \LINEBUF.OFD))
                            )
                       (\CREATE.TTYDISPLAYSTREAM)))
                   *STANDARD-INPUT*)
            (OUTPUT (COND
                       ((AND \DEFAULTTTYDISPLAYSTREAM (EQ *STANDARD-OUTPUT* \DEFAULTTTYDISPLAYSTREAM)
                             )
                        (\CREATE.TTYDISPLAYSTREAM)))
                    *STANDARD-OUTPUT*)
            (\IOMODEP (COND
                         ((NOT (EQ *STANDARD-INPUT* \LINEBUF.OFD))
                          *STANDARD-INPUT*)
                         (T *STANDARD-OUTPUT*))
                   ACCESS NOERROR)))
       ((EQ X T)
        (SELECTQ ACCESS
            (INPUT (COND
                      ((EQ \LINEBUF.OFD \DEFAULTLINEBUF)
                       (\CREATE.TTYDISPLAYSTREAM)))
                   \LINEBUF.OFD)
            ((OUTPUT NIL) 
                 (COND
                    ((AND \DEFAULTTTYDISPLAYSTREAM (EQ \TERM.OFD \DEFAULTTTYDISPLAYSTREAM))
                     (\CREATE.TTYDISPLAYSTREAM)))
                 \TERM.OFD)
            (\FILE.NOT.OPEN X NOERROR)))
       ((type? STREAM X)
        (\IOMODEP X ACCESS NOERROR))
       ((LITATOM X)
        (AND (NOT NOERROR)
             (ERROR "LITATOM 'streams' no longer supported" X)))
       ((AND (OR (EQ ACCESS 'OUTPUT)
                 (NULL ACCESS))
             (type? WINDOW X))
        (fetch (WINDOW DSP) of X))
       (T (\FILE.NOT.OPEN X NOERROR])

(\SEARCHOPENFILES
  [LAMBDA (NAME ACCESS)                                      (* rmk%: "14-OCT-83 15:04")
          
          (* ;; "Returns a stream whose fullname is NAME if it has accessmode ACCESS")

    (for STREAM in \OPENFILES when (EQ NAME (fetch FULLNAME of STREAM))
       do (RETURN (COND
                     (ACCESS (\IOMODEP STREAM ACCESS T))
                     (T STREAM])
)
(DECLARE%: DONTCOPY 
(* "FOLLOWING DEFINITIONS EXPORTED")

(DECLARE%: EVAL@COMPILE 

(PUTPROPS \INSTREAMARG MACRO ((STRM NOERRORFLG)
                                      (\GETSTREAM STRM 'INPUT NOERRORFLG)))

(PUTPROPS \OUTSTREAMARG MACRO ((STRM NOERRORFLG)
                                       (\GETSTREAM STRM 'OUTPUT NOERRORFLG)))

(PUTPROPS \STREAMARG MACRO [OPENLAMBDA (STRM NOERRORFLG)
                                          (COND
                                             (NOERRORFLG (\GETSTREAM STRM NIL T))
                                             (T (\DTEST STRM 'STREAM])
)

(* "END EXPORTED DEFINITIONS")

)
(DECLARE%: EVAL@COMPILE 

(PUTPROPS GETOFD MACRO (= . GETSTREAM))

(PUTPROPS \GETOFD MACRO (= . \GETSTREAM))
)
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(LOCALVARS . T)
)
(DECLARE%: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS 

(ADDTOVAR NLAMA )

(ADDTOVAR NLAML )

(ADDTOVAR LAMA WHENCLOSE)
)
(PUTPROPS AOFD COPYRIGHT ("Venue & Xerox Corporation" 1981 1982 1983 1984 1985 1986 1987 1990))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (2304 3411 (\ADD-OPEN-STREAM 2314 . 2591) (\GENERIC-UNREGISTER-STREAM 2593 . 3409)) (
3452 10531 (CLOSEALL 3462 . 4167) (CLOSEF 4169 . 5353) (EOFCLOSEF 5355 . 5651) (INPUT 5653 . 6407) (
OPENP 6409 . 6808) (OUTPUT 6810 . 7566) (POSITION 7568 . 8380) (RANDACCESSP 8382 . 8727) (\IOMODEP 
8729 . 9366) (WHENCLOSE 9368 . 10529)) (10532 10654 (STREAMADDPROP 10542 . 10652)) (11820 23932 (
\BASEBYTES.IO.INIT 11830 . 15026) (\MAKEBASEBYTESTREAM 15028 . 17621) (\MBS.OUTCHARFN 17623 . 18011) (
\BASEBYTES.NAME.FROM.STREAM 18013 . 18476) (\BASEBYTES.BOUT 18478 . 19195) (\BASEBYTES.SETFILEPTR 
19197 . 19818) (\BASEBYTES.READP 19820 . 20456) (\BASEBYTES.BIN 20458 . 20989) (\BASEBYTES.PEEKBIN 
20991 . 21772) (\BASEBYTES.TRUNCATEFN 21774 . 22278) (\BASEBYTES.OPENFN 22280 . 22770) (
\BASEBYTES.BLOCKIO 22772 . 23930)) (24055 26305 (OPENSTRINGSTREAM 24065 . 26303)) (26362 29998 (
\STRINGSTREAM.INIT 26372 . 29996)) (30060 33611 (GETSTREAM 30070 . 30293) (\ADDOFD 30295 . 30582) (
\CLEAROFD 30584 . 30865) (\DELETEOFD 30867 . 31018) (\GETSTREAM 31020 . 33184) (\SEARCHOPENFILES 33186
 . 33609)))))
STOP
