AatsHH $  KS`IH6HZff@5  d'  Footnote TableFootnotee*c*r. .. / - e:;,.!?.hlsips`2/a laBolLOMX-Ref.40imeIXIndexticTOC01Heading2HeadingPrefacetTitle0AddField(deptAndedGAsTextDept DeptData.textDept_csv_Reader7Employee,ManagerFindExisting(dept_filerFindExisting(temp FlatFileBBFlatFileBB$DeptFileFlatFileDescriptorMode:CNameField(deptiODObjectDirectoryROMsRecurseaSetName(EnglishTemp configurersdept executablesgreyednumoppathnamex=Sales   *EquationVariables3.0a [ U  U  I V  \ k +H Y  Y f_ k a  V  ڟ l  R Z T  T d L W N W O X S Z tnoQ X Foo [ c `  `  .1  3 a !?.4 a  \  ]  ]  Bol ^ X-g m b o b r c 0t c gu d Prw d itl ^ ddFi _ tj _ sTep e Deq e xt v_R [ mpl f ger` sti g fil g xis h p h B f B$DV FlX i criY i e:Cb ld(d j DObe j torf Re etN k ish k onf͟ de۟ l tab yed p x=        m            ari   3.    U   U     V   \   +   Y   Y         V     l   Z        W !  W "  X #  Z $  X %  [ &  ` '  ` (  )  a *  a +  \ ,  ] -  ] .  § /  ^ ç 0  ħ 1  b ŧ 2  b Ƨ 3  c ǧ 4  c ȧ 5  d  6 m  d ɧ 7  ^ ʧ 8  _ ˧ 9  _ ̧ :  e ͧ ;  e Χ <  ϧ =  [ Ч >  f ѧ ?  ҧ @  g ӧ A  g ԧ B  h է C  h ֧ D  f ק E  ا F  i ٧ G  i ڧ H  ۧ I  j ܧ J  j ݧ K  ާ L  ߧ M  k N  k O  P  l Q  R  S  T  U  V  W  X  m Y  Z  ! o 049178: Figure: Figure 1 Streams library classes. C48371: Heading: 2. Growing Collections, Object Identity and Streams +11181: In-line-interface: "17647: Heading: 8. Wrapper Streams +63626: 2Heading: 1.7.1 Reading from streams 43668: In-line-interface: readX # 14258: In-line-interface: close 976495: 2Heading: 1.5.3 Options when creating file streams ] (49967: In-line-interface: unread-element 050877: In-line-interface: stream-position-setter *63317: In-line-interface: get-input-buffere &37574: In-line-interface: read-element 290813: In-line-interface: type-for-sequence-stream .47613: In-line-interface: type-for-file-stream '40817: In-line-interface: discard-input 132951: In-line-interface: stream-input-available? %37762: In-line-interface: read-to-end \[stream]!  ,\[positionable-stream] $\[buffered-stream] s\[file-stream]  $\[sequence-stream]   \[string-stream]  s*\[byte-string-stream]ro  m0\[unicode-string-stream]   type-for-file-stream  ttype-for-sequence-stream  eclose1.3  s read-element epeek  read e read-into!re e discard-input07: estream-input-available?o  read-to  - read-through  u read-to-end  7 skip-through   write-element  0write-ne  a force-output  tsynchronize-output3:  ediscard-outputor  t read-line  :read-line-into!e  - write-line  :new-line   stream-open?   stream-element-typeI  tstream-at-end?d   Positionable stream protocol  $\[stream-position]  stream-positions ! ustream-position-setter\< " radjust-stream-position # uastr $ e stream-size] % stream-contents\ & sunread-element\< ' rclosee\> ( twith-open-file ) <Locking streamsr * cstream-locked? +  lock-streaml ,  unlock-streamf-s - -with-stream-lockede1 .  Buffer access protocole / \[byte] 0 e"\[byte-character]7: 1 e(\[unicode-character] 2  \[byte-vector] 3 n\[buffer]ou 4  \[buffer-index]wr 5 eget-input-buffer 7  release-input-buffer 8  with-input-buffertor 9 tnext-input-buffer : : linput-available-at-source?ne ;  get-output-buffer  < mrelease-output-buffermle = pwith-output-buffert- > next-output-buffer s ? r buffer-next @ ebuffer-next-setteros A  buffer-endam B obuffer-end-settermos C ebuffer-subsequencest D -copy-into-buffer!uas E  copy-from-buffer!% F tStream extension protocolnad G tdo-get-input-buffer H tdo-release-input-buffer I ndo-next-input-buffer J cdo-input-available-at-source?, K ndo-get-output-buffer L sdo-release-output-buffer M cdo-next-output-buffer\< N b,\[end-of-stream-error] O :0\[incomplete-read-error] P  \[file-error] Q n(\[file-exists-error] R b8\[file-does-not-exist-error] S -B\[invalid-file-permissions-error]: T lWrapper stream protocolc U  "\[wrapper-stream]re V u inner-stream W pinner-stream-setter X  outer-stream Y souter-stream-setter Z e#42007: Heading: The Streams Libraryf  U Jbuer m Jermos b 6buer c 7ncest Y 7co-i d Jr!uas \ 9co-f ] Jr!% ^ 7St  si32T W R 976495: 2Heading: 1.5.3 Options when creating file streamsI 32V\ X L-+11181: In-line-interface: 32Na [ Rt976495: 2Heading: 1.5.3 Options when creating file streamsnou32wf ` S +63626: 2Heading: 1.7.1 Reading from streamso32n a Oe43668: In-line-interface: read32 t V Lr14258: In-line-interface: closee32x Z Oi(49967: In-line-interface: unread-element32 _ Qx050877: In-line-interface: stream-position-setter32Ȅ e Os050877: In-line-interface: stream-position-setter327 f Oe290813: In-line-interface: type-for-sequence-streamin32 g Q&37574: In-line-interface: read-element-s32ǒ h O&37574: In-line-interface: read-elementU 32 i O.47613: In-line-interface: type-for-file-stream-i32 j O 132951: In-line-interface: stream-input-available?332b k O9%37762: In-line-interface: read-to-endfst32  l L(49967: In-line-interface: unread-element5UT5 26<$paratext[Chapter]>ad7<$curpagenum>ang8<$monthname> <$daynum>, <$year> +9 *<$paranum[1Heading]><$paratext[1Heading]>:<$monthname><$year>li; <$paratext[Chapter]><<$lastpagenum>=;<$monthname> <$daynum>, <$year> <$hour>:<$minute00> <$ampm>ier>"<$monthnum>/<$daynum>/<$shortyear>?<$monthname> <$daynum>, <$year>sio@"<$monthnum>/<$daynum>/<$shortyear>A <$fullfilename>mosB <$filename>2C (Continued) ID+ (Sheet <$tblsheetnum> of <$tblsheetcount>)2EChapter & Title:/Chapter <$paranumonly[Chapter]>, <$paratext> FHeading & Page <$paratext> on page <$pagenum>GChapterChapter <$paranumonly[Chapter]HAppendix & Title'Appendix <$paranumonly>, <$paratext>ierI Number Onlyt<$paranumonly>JStatus 06 Feb 19977KFigure Number & Page<$paranum>, page <$pagenum>LFunction & Paget3<$paratext>, page <$pagenum>paM Title Only<$paratext>uN Figure Number <$paranum>$dOPage <$pagenum>PHeading[<$paratext> QFunction<$paratext>mRSection & Page)Section <$paranumonly> on page <$pagenum>uSSectiontSection <$paranumonly>  ,, .. aAe>s  GGTOCe TTIX [[LOFe qqLOT> uuIXr  33 66 ?? BB JJ MM ]]  "" A ge  Al  $$A) 9. AlyG ) $xt * iumэ + a$d , nu - e~} . > / x<$f 0 mč 1 eioō 2 on ٙ 3 nҍ 4 octƍ 5 u 6  ܍ 7  8 y 9 r 0.1.2 :  ; f < Gs = O{_ >  0.1 |_ ? LO @  A  B u C X D  E  F  G ? H s I  J   K R L s M }_ N m~_ O m_ P m Q mh R  H S  ge_ T m U mm_ V _ W m0 X Ah Y  y Z t 0.3 [ _ \ qe_ ] >h ^  _ _ _ ` e_ a oQ b n c o_ d uh e   _ f _ g _ h i i  _ j  _ k  _ l  _ m  _ n  i o  _ p _ q LO_ r  0.3.1  s  t  I u  i v  _ w  x sU y _ z  _ {  0.4 _ | _ } _ ~ ze  p  0.4.1.2  r p  0.4.1.3 7 \Y nm} ~ z  |}    >     H    K  Ǎ  Ӎ  ԍ   f  |} :v  ;v  0.5.5  p  0.4.1.1 @ r s ot {^  / :    b Q  e R   R  ч  u u  a Ο z _  0.5.7   v u  r 0.7.3  x oy oz o{ o| oz} ~ o| o| o b |} tJ  0.5 S ϟ |}a z П p` џ .ҟ sȟ zz v v ` ` x ` ` ` `  ` z`  ׉ ` l x |}x `  ` z!` "`   $`   0.5.2 %`  &`  z'`  o(`  o)`  o*`  o+` o,` -` o.` o/` o0`  1`  |2`   0.5.3 3`  4`  5`  6`  7`  8`  9`  .:`  ;`  <`  =`  \  ?`  @`  A`  B` C` ! D` " E` # F` $  0.5.4 G` % H` & I` ' J` ( K` ) L` * M` + N` , O` - v .  v /  v 0   1  2 oo5.T` 3 U` 4 v 5  v 6  v 7  Y` 8 Z` 9 z[` : \` ; ]` < z = |}z > `` ? ] @ b` A  0.5.6 c` B O C e` D f` E z F z h` G i` H j` I k` J l` K m` L  M o` N p` O ^ P r` Q C R D S u` T ߠ U  w` V  x` W  y` X  z` Y  ` Z z |` [  }` \  ~` ]  ` ^  ` _  a ` z ` a  ` b  ` c  9 d  ` e  d f  g  ` h  ` i  ` j  ` k  ` l  z m   ` n  0.6 ` o ` p ` q ` r .` s ` t ` u e v |f w s` x ` y ` z  0.7 ` {   |  ` }  0.7.2 ` ~ `  ` ` ` ` `   0.7.2.1 ` z c  ` z `  ` z `  ` z `  `   0.7.2.2 ` z){ z` ,{ |}ǐ ` ` ` V d z` `  [ g ` z  `  `  i{ z `    `  Б  ё  `  `   0.7.2.3 ` `  ` .` ` ` z` ` ` ` ` z7.` ` z ` ` `  z< R  |} ||  z ||   `  ` z `  `   `  `     ` |  `  `  `   | z ۔ |}  0.7.4  `   0.7.4.1 .` h| z` ` .` & |}| z` ` a a   0.7.4.2 ] |}| z^ a a a z a  a a  0.8 a  a z a  a z   a z a  a z a  a z a  a z a  a  0.9 1}  v   v   "a  6}   $a  z%a  |s   'a  (a .|  *a  w  7.     .a   0.9.1 ./a  0a  1a  2a  3a  4a      7.9a  :a  ;a  a  z?a  @a  Aa Ba ! zDa # zEa $ Fa % Ga & Ha ' Ia ( h *  h +  h ,  i -  &i .  Ci /  \i 0  i 1  i 2  M~ 3 ~ 5   6 i 7  i 8 kj :  lj ;   j <   j =   j >  j ?  k @ |} k B . k C  k D k E k F ..k G k H k I k J k K  Figure 1 ΁ M zρ N |}7.Ё O с P ҁ Q zӁ R |} S P T 103 U 7 V ; W q X ~ Y  Z  [ w \ x ] Ս ^ ֍ _ ׍ `  a  b v c  v d  v e  E} f  v g  v h  v i  v j   w k T} l  w m  w n  w o  } p  0.2 w q   "w r   &w s   (w t  . >w u   Bw v  Fw w  Hw x  ..Jw y  Lw z  bw {  fw |  jw }  lw ~  erw  |}< 7.E Ҋ  r 0.1.1 {x |}x }0 x x |}x zx |}x |}wx zxx x x |}x |x x zx |} x z x |}x z x |}x z y |} y z y |} (y z )y |},y z 7y |}:y z;y |}>y z _y |} by z y z y |} y |} y  y |} y z y |} y z y |} y  y |} y z y |} y z z  z z z |}z |} z zz |}$z z,z |}4z z5z |}8z z9z |} l ? m @ zn A |}o B p C ԁ D Ձ E  ց G ׁ H ؁ I zف J |}ځ K ہ L  ܁ M ݁ N ށ O ߁ P z Q |} R  S   T  U X W r 0.5.1 0 X  Y i r 0.4.2 Z j z[ k |}\ l ] m  o  r  s M t p u q v wx w wy x ȍ y ɍ z ʍ { ˍ | ̍ } $ ~ r 0.7.1 6 ;  @ s     *     ґ  T  W  ’   Д Ԕ j   5.      AZH 2 AH 2l   HH  B_ HH y x c  TUTU`; HThe class supports the same init-keywords as . r)h<   RU)TU`= Open instantiable class PU?TU`> VThe class of streams over byte strings. It is a subclass of . NUSTU`?  IThe class supports the same init-keywords as . uh@   LUuTU`A Open instantiable class JUTU B KThe class of streams over Unicode strings. It is a subclass of . FUTU`C HThe class supports the same init-keywords as . UUd Creating streams CUTU` H4The following functions are used to create streams. UUd File streams @UTU  HQFile streams are intended only for accessing the contents of files. They are not >U%TU Pintended to provide a general file handling facility of renaming, deleting, movs Gbuffer-size element-type encoding A ` ia!=> file-stream-instance h8UTU`  o(Creates and opens a stream over a file. 6UTU  LReturns a new instance of a concrete subclass of  that in4UTU . reQH  C rinQH ` fTUTU  UOConsider the example of an output stream instantiated over an empty string. As RUTU Qsoon as a write operation is performed on the stream, it is necessary to replace PU#TU Nthe string object used in the representation of the string stream. As well as NU1TU ilRincurring the cost of creating a new string, the replacement operation can affect LU?TU@  Ethe integrity of other references to the string within the program. >JUSTU ! QTo guarantee that alias references to a sequence used in an output  will have access to any elements written to the sequence via the stream, uFUoTU! ]supply a  to make. A stream over a stretchy vector will use sDU}TU@! gu=the same stretchy vector throughout the streams existence. BUTU`"  For example: `) "let sv = make(); `S &let stream = make(, `u  icontents: sv, st`  direction: #"output"); at`v n ,write(stream,#(1, 2, 3, 4, 5, 6, 7, 8, 9)); ` stwrite(stream,"ABCDEF"); pr`2 st%values(sv, stream-contents(stream)); @UTU`w e VThe example returns two values. Each value is the same (\==) stretchy vector: 0`7  o:(1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F) >UETU`8 ua@If a stretchy vector is not supplied, the result is different: seY`s !let v = make(, size: 5); el`t  w%let stream = make(, uw`x contents: v, vec`: ke direction: #"output"); to`; ,write(stream,#(1, 2, 3, 4, 5, 6, 7, 8, 9)); ou`< stwrite(stream,"ABCDEF"); `= $values(v, stream-contents(stream)); ch n :(1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F)  DGOm-ntaa ExplHH vueHH  F 0HH 2,  , B,  TUTUg IfOwill be accessed by the next operation. The following example uses positioning RUTU@g ctQto return the character w from a stream over the string "hello world": )`h =let stream = make(, contents: "hello world"); "4`i stream-position(stream) := 6; ?`- 8,read-element(stream); PUTTU j ,"QThe following example returns a string, but the contents of the first ten characNUbTU@j mpters are undefined: t v`k  v:let stream = make(, direction: #"output"); `. lu%adjust-stream-position(stream, 10); `/ 6,write(stream, "whoa!"); D`0 stream-contents(stream); LUTU l LYou can request a sequence containing all of the elements of a positionable JUTUl  vTstream by calling stream-contents on it. The sequence returned never shares HUTUl , Kstructure with any underlying sequence that might be used in future by the eraFUTUl g Wstream. For instance, the string returned by calling stream-contents on an outam DUTUl Xput  will not be the same string as that being used to represent llBUTU@l the string stream. pos@UTU m ; RWhen making an input , you can cause the stream to produce >UTU@m Celements from any subsequence of the supplied string. For example: s a(`n v#read-to-end(make(, str3`o ti(contents: "hello there, world", st>`p trstart: 6, I`1 reend: 11));  condition is signalled at the time the file sLU?TU@ itstream is created.  JUSTU  ouWThe element-type init-keyword controls how the elements of the underlying file grHUaTU@ seare accessed. usFUuTU  heZImplementation Note: Ideally, element-type could be any valid Dylan type such DUTU Yas limited(, min: 0, max: 255) or . This BUTU  Mapproach may make it possible to implement a potentially inefficient but gen@UTU Qeral set of file streams. Unfortunately the current language definition does not >UTU enMinclude adequate support for this approach, so we specify instead an interim 6UTU` gn 4U TU`  8The file is accessed as a sequence of 8-bit characters. el2U#TU` t- e0U5TU  ly:The file is accessed as a sequence of 16-bit Unicode char.UCTU@ emacters. ot,UWTU 2 EThe file is accessed as a sequence of unsigned 8-bit inte*UeTU@2 edgers. (UyTU  55NPortability Note: Portable code can count on the existence of these three &UTU@  i>element types, but implementations are free to provide more. zUUd  sSequence streams #UTU  ua`There are make methods on , ,  and . The make methods on r UTU W and  might not create direct instances of UUTU thPthose classes, but instead an instance of a subclass determined by type-for- UTU@ Thsequence-stream. QH  Jd QH ly:Thf ssTUTU   USThe locator init-keyword should be a string naming a file. If the Locators isRUTU ue_library is in use, locator should be an instance of  or a string that  PU#TU@ cocan be coerced to one. hesNU7TU` JThe direction init-keyword specifies the direction of the stream. LUKTU  SeaThe if-exists and if-does-not-exist init-keywords specify actions to take if the JUYTU Tfile named by locator does or does not already exist when the stream is crem>HUgTU Xated. These init-keywords are discussed in more detail in  Section 0.4.1.2 on page 62ghFUuTUN t  . DUTUn bThe buffer-size init-keyword is explained in  , page 60 . BUTU  enUThe element-type init-keyword specifies the type of the elements in the file @UTU Vnamed by locator. This allows file elements to be represented abstractly; for >UTU inLinstance, contiguous elements could be treated as a single database record.  and  are n8UTUN K8likely choices. See  Section 0.4.1.2 on page 62 . t-h wo!  type-for-file-stream 6UTU` Open generic function `# esntype-for-file-stream locator element-type #rest all-keys => file-stream-type 4U.TU 1 ctKReturns the kind of file-stream class to instantiate for a given file. The 2U<TU1 inVmethod for make on  calls this function to determine the 0UJTU@1 en-class of which it should create an instance. hkUUl ' Options when creating file streams cat-UTU  s NWhen creating file streams, you can can supply the following init-keywords to +UTU@ s .make in addition to the usual direction: )UTU` d <if-existsAn action to take if the file already exists. ba'UTU` Lif-does-not-existAn action to take if the file does not already exist. e-%UTU`  nGelement-typeHow the elements of the underlying file are accessed. #UTU   WThe if-exists init-keyword allows you to specify an action to take if the file !UTU@ -f:named by locator already exists. The options are: l  KD .l rn  m class G f e1 <6openObjectId <$relfilename>:<$ObjectType> <$ObjectId> UUe2 hi<$paratext> <$pagenum> e TUe5 en#<$paranum><$paratext> <$pagenum> insUUe +Appendix <$paranum><$paratext><$pagenum> amsTUey  <$paratext><$pagenum> strUUez su&<$paranum><$paratext><$pagenum> jKe{ ma"<$paranum><$paratext><$pagenum> e| #<$paranum><$paratext><$pagenum> takUUe} ad xHH  L xtHH ifdy existTUTU T HRA standard object-printing package such as Smalltalks printOn: or Lisps RUTUT itRprint-object, or a formatted printing facility such as Lisps format. PU#TU@T atCAdditional libraries are expected to provide these facilities. NU7TU`U l$General object dumping and loading. LUKTU V GA comprehensive range of I/O facilities for using memory-mapped files, tTyJUYTUV Inetwork connections, and so on. Such facilities should be easy to add to >HUgTU@V ge9the Streams library because of its extensible framework. tFU{TU`W !An interface for naming files. eDUTU Q IAn interface to operating system functionality, such as file renaming or aBUTU@Q $pdeleting operations.  UUdZ at Concepts e?UTU [ UA stream provides sequential access to an aggregate of data, such as a Dylan =UTU[ Nsequence or a disk file. Streams grant this access according to a metaphor of ;UTU@[ maWreading and writing: elements can be read from streams or written to them. d p9UTU 5 ucOStreams are represented as Dylan objects, and all are general instances of the ed 7UTU@5 ac;class , which the Streams library defines. and5U'TU Y YWe say that a stream is established over the data aggregate. Hence, a stream pro3U5TUY neYviding access to the string "hello world" is said to be a stream over the string e1UCTU@Y ar"hello world". nsi/UWTU  {VStreams permitting reading operations are called input streams. Input streams -UeTU  fFallow elements from the underlying data aggregate to be consumed. Con+UsTU Yversely, streams permitting writing operations are called output streams. Output s)UTU ofOstreams allow elements to be written to the underlying data aggregate. Streams ant'UTU@ diNpermitting both kinds of operations are called input-output streams. %UTU \ omKThe library provides a set of functions for reading elements from an input as#UTU\ d Pstream. These functions hide the details of indexing, buffering, and so on. For wh!UTU\ brVinstance, the function read-element reads a single data element from an input UTU@\  H stream. eUTU  QThe following expression binds stream to an input stream over the string oUTU@ C"hello world": lo`] =let stream = make(, contents: "hello world"); lHH Ħ M HH em data agcoTUTU   JReturns a sequence of all the elements up to, and including, the last eleRUTU@  sKment of input-stream, starting from the streams current position. datPU)TU  msVThe type of the result sequence is as described for read. There is no special NU7TU Mend-of-stream behavior; if the stream is already at its end, an empty collecfLUETU@ tion is returned. gh on skip-through oJUgTU` in Function n{` Wskip-through input-stream element #key test => found? inHUTU  \ hPositions input-stream after the first occurrence of element, starting from the r FUTU ]streams current position. Returns #t if the element was found, or #f if the nDUTU d"Oend of the stream was encountered. When skip-through does not find the BUTU@ atCelement, it leaves input-stream positioned at the end. of @UTU  p MThe skip-through function determines whether the element occurred by >UTU th^calling the test function test, which defaults to \==. The test function must , you must 3UOTU ftdprovide methods for write-element, write, force-output, and discard-out c1U]TU@ et put. h  w write-element /UTU` Open generic function ` te;write-element output-stream element => () -UTU  [Writes element to output-stream at the streams current position. It is an p-t+UTU n Serror if the type of element is inappropriate for the strreams underlying nct)UTU@ wh aggregate. to 'UTU  esEIf the stream is positionable, and it is not positioned at its end, f%UTU thJwrite-element overwrites the element at the current position and then #UTU@ advance the stream position. sHH  N e HH itTU ,mpTUTU   tVThe resulting buffer is never completely full of pending output. If this funcRUTU emGtions methods cannot return a buffer with the minimum number of bytes UPU#TU@ 7specified by bytes, they must signal an error.  Eh  f Ldo-release-output-buffer rNUETU` tpOpen generic function Y` 7do-release-output-buffer buffered-stream => () reaLUnTU  mMThe methods of this generic function implement release-output-buffer eJU|TU prHfor new streams. These methods can assume that the stream is locked, so o HUTU@ esno other thread can access it. andh ne Mdo-next-output-buffer FUTU` emOpen generic function ` enTdo-next-output-buffer buffered-stream #key bytes => buffer DUTU  NThe methods of this generic function implement next-output-buffer for BUTU Anew streams. These methods must signal an error when they cannot @UTU  INreturn a buffer for any reason, or the current buffer is not held for output. >UTU  bGIf this functions methods cannot return a buffer with the minimum numl a 'UTU` Error %UTU  ciESignalled when one of the read functions reaches the end of an input #UTU@ e Ystream. It is a subclass of . It takes one init-keyword, stream:. elm ³ Í OGD nbulm ³ llTable of Contents Specification fr͍ P`TXnscag} Q r s llHH  R enHH  ay condit(inTUTU   MThe do-next-output-buffer function signals an error when the current dRUTU@ buffer is not held for output. r fPU)TU  e NThe do-next-output-buffer function may force output to a streams desNU7TU e Mtination, but it is not required to do so. It might empty the current buffer LUETU amKinto secondary buffers or get a new buffer from a queue, while not forcing of JUSTU@  r any output. oHUgTU  YThe bytes argument is the same as for get-output-buffer, but do-next-tFUuTU@  Doutput-buffer signals any error associated with this parameter. UUd teCopying to and from buffers CUTU  NAll generic sequence operations work on buffers. The Streams library provides AUTU Msome additional functions to compensate for lacking functionality in Dylans ?UTU  aLsequence operations. There are also a few functions for updating a buffers Th=UTU@ utstate.  h n  ?buffer-next re;UTU`  Function r ` ut4buffer-next buffer => buffer-index uf9UTU  ayKFor buffers held for input, this function returns the location of the next re7U-TU t Svalid byte of input to be read. When the location equals buffer-end, there ne5U;TU@ eu+is no more valid input data in the buffer. an3UOTU  LFor buffers held for output, this function returns the location of the next fe1U]TU neMfree byte that should be written in the buffer, and when the location equals h/UkTU@ 6buffer-end, the buffer is full of pending output. hf ge @buffer-next-setter wo-UTU`v  S Function a` Bbuffer-next-setter new-value buffer => new-value +UTU`w an#Sets buffers next index. erah ls Abuffer-end fo)UTU` r Function ` e.3buffer-end buffer => buffer-index QH Ҧ S uerQH > 9UTUFoTUTU O thYThe position may also be #"start", meaning that the stream should be oRUTUO  l[positioned at its start, or #"end", meaning that the stream should be posi inPU#TU@O Otioned at its end. buEh pu "adjust-stream-position locNUETU` feOpen generic function Y`Q d ladjust-stream-position positionable-stream delta #key from => new-position llLUnTU  . [Moves the position of positionable-stream to be offset delta elements from  JU|TU@ seGthe position indicated by from. The new position is returned. SeHUTU s s ^The value of from can be one of the symbols #"current", #"start", and FUTUs er`#"end". The default value is #"current". When from is #"start", the QDUTUs > Sstream is positioned relative to the beginning of the stream. When from is poBUTU@s o :#"end", the stream is positioned relative to its end. @UTU T  lKUsing adjust-stream-position to set the position of a stream to be sh>UTUT #Fbeyond its current last element causes the underlying aggregate to be integer e4UQTU W rnYCoerces a  to an integer. The integer-class argument is r2U_TU@W arthe class . rh de $stream-size #0UTU` n Open generic function `X 9stream-size positionable-stream => size n.UTU`Y . @Returns the number of elements in positionable-stream. am,UTU R atIFor input streams, this number is the number of elements that were availt*UTUR  oJable when the stream was created. It is unaffected by any read operations (UTU@R g /that might have been performed on the stream. new&UTU S inFFor output and input-output streams, this number is the number of ele$UTUS  uJments that were available when the stream was created (just as with input l u΍ TXP bl ul WW  z UeQ]a QH  V ntQH t the clerTUTU`G de*Creates and opens a stream over a string. RUTU H n ZThis method returns an instance of . If supplied, contents PU)TUH thYmust be an instance of . The string-stream-class argument is the eNU7TUH s jclass . The direction, start, and end init-keywords are as LUETU@H pe/for make on . n pg`I re'make byte-string-stream-class andJUgTU`J am G.f. method i{`K eimake byte-string-stream-class #key contents direction start end `L X(=> byte-string-stream-instance lHUTU`M /Creates and opens a stream over a byte string. FUTU N KThis method returns a new instance of . If supHDUTU@N Gplied, contents must be an instance of . CrBUTU O stYThe byte-string-stream-class argument is the class . r@UTUO iemThe direction, start, and end init-keywords are as for make on UTU@O  stream>. `P tr*make unicode-string-stream-class unicode-string-stream-instance K :UCTU`T e-2Creates and opens a stream over a Unicode string. 8UWTU U arNThis method returns a new instance of . If sup6UeTU@U M Jplied, contents must be an instance of . 4UyTU  rnRThe unicode-string-stream-class argument is the class . The direction, start, and end init-keywords are as for make on a0UTU@ ss. ׄUUdi O Closing streams ct-UTU X LWhen creating new stream classes it may be necessary to add a method to the +UTU@X  Qclose function, even though it is not part of the Stream Extension Protocol. l uύ WP l uVincontTire+  Level2IX ae4 g Level1IX ie -i 1, 23  e T $<$symbols><$numerics><$alphabetics> a e^ WLSymbols[\ ];Numerics[0];A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z ree_ e <$pagenum> M e` nt lqo Ѝ XTP glqo lvlvIndex Specificationlas؍ Yrg-[oaml ٍ [oYdl lee fa \^^ctH${ ]UcssH$l  X QH ia ^\ t QH  HHcyy  ja _inccnt `LeagLeHH a`HHl  HH  b ;G;HH S;!!e_ m>!`  $make sequence-stream-class TUTU` o G.f. method l` ecfmake sequence-stream-class #key contents direction start end &` o%=> sequence-stream-instance RU;TU` ,Creates and opens a stream over a sequence. PUOTU  NThis method returns a general instance of . To deterNU]TU Mmine the concrete subclass to be instantiated, this method calls the generic LUkTUN HBfunction type-for-sequence-stream (see page  65 ). JUTU` SThe sequence-stream-class argument is the class . HUTU  WThe contents init-keyword is a general instance of  which is FUTU Nused as the input for input streams, and as the initial storage for an output DUTU Vstream. If contents is a stretchy vector, then it is the only storage used by BUTU@  the stream. @UTU  lUThe direction init-keyword specifies the direction of the stream. It must be c>UTU@ ione of #"input", #"output", or #"input-output"; the default is #"input". n sequence-stream-type  2UhTU P GReturns the sequence-stream class to instantiate over a given sequence U0UvTUP thXobject. The method for make on  calls this function to on.UTUP  mLdetermine the concrete subclass of  that it should ,UTU@P instantiate. *UTU X  nJThere are type-for-sequence-stream methods for each of the string (UTUX diLobject classes. These methods return a stream class object that the particuti&UTU@X 2lar Streams implementation considers appropriate. `Q us"make string-stream-class $UTU`R re G.f. method ti`D  dmake string-stream-class #key contents direction start end `E #=> string-stream-instance UHH ma c_HH  H ^fBB quena dReffcls l ڍ eY l  Th on [eae7  t"<$paranum><$paratext><$pagenum> QH qa fdaQH  HckJJ Ura gcstkkofheQH  h sThQH tr$$e partic$TUTU _ em^The first invocation of read-element on stream returns the character h, the RUTU_  mOnext invocation e, and so on. Once a stream has been used to consume all the PU#TU_  Qelements of the data, the stream is said to be at its end. This condition can be NU1TU_  Utested with the function stream-at-end?. The following code fragment applies LU?TU@_ .function to all elements of the sequence: S`` s 5let stream = make(, contents: seq); ^`R !while (~stream-at-end?(stream)) i`Y !function(read-element(stream)); tt`a Qend; JUTU b TWhen all elements of a stream have been read, further calls to read-element HUTUb Vresult in the  condition being signalled. An alternative FUTUb HPend-of-stream behavior is to have a distinguished end-of-stream value returned. DUTUb t LYou can supply such an end-of-stream value as a keyword argument to the var, BUTUb _ Mious read functions; the value can be any object. Supplying an end-of-stream l@UTUb Rvalue to a read function is more efficient than asking whether a stream is at its >UTU@b #end on every iteration of a loop. s, direction: #"output"); bjex`^ ndwrite-element(stream, I); `e fuwrite-element(stream, ); as`* eawrite(stream, "see"); `+ vewrite-element(stream, !); `, Thstream-contents(stream); e,UTU f  w`Calling write on a sequence has the same effect as calling write-element on all up*UTUf thVthe elements of the sequence. However, it is not required that write be imple(UTUf inUmented directly in terms of write-element; it might be implemented more effim&UTU@f in*ciently, especially for buffered streams. $UTU g  WSome streams are positionable; that is, they permit random access to their ele em"UTUg KMments. Postionable streams allow you to set the position at which the stream t ic  armHH  j tngHH "o`^ nd"t(h  1 reTUTU` Type RUTU  , FA type representing Unicode characters that instances of  can contain. f Mh wr 2 NUMTU` ecType lLUcTU` meFA subtype of  whose element-type is . h ui  3 iJUTU` Sealed instantiable class HUTU` NA subclass of  whose element-type is . FUTU  foSInstances of  contain a data vector and two indices: the inclusive isDUTU omKstart and the exclusive end of valid data in the buffer. The accessors for w yBUTU tiYthese indexes are called buffer-next and buffer-end. This class supports @UTU Hdthree init-keywords: size:, next: (defaults to zero), and end: (defaults to >UTU@ zero). ; if you supply a value with the size: init-keyword, that size is 6U%TU  iNallocated, or, if that is not possible, an error is signalled, as with making 4U3TU@ cl any vector. Uh ss 4 who2UUTU` eType 0UkTU` !A subtype of . <.UTU  n IAll buffer-index return values and parameters are of this type. See also ,UTU@ en4Harlequin and CMUs proposal for . UUd thUsing buffers for input bh    5get-input-buffer u)UTU`  Function h`  hget-input-buffer buffered-stream, #key wait?, bytes => buffer-or-false ).HH ua kgeHH  H fnzz e, va ls wnno HH  mE e-HH susize:++HrdTUTU ? PThis difference arises because the output stream in the second example does not akRUTU?  Suse a stretchy vector to hold the stream data. A vector of at least 15 elements is TyPU#TU?  Lnecessary to accommodate the elements written to the stream, but the vector rNU1TU? ar_supplied, v, can hold only 5. Since the stream cannot change vs size, it must nteLU?TU@? +allocate a new vector each time it grows. b UUd{ Stream classes ffIUwTU`|  5The exported streams class heterarchy is as follows: GUTUh"J   y:UTUhK  Streams library classes. +S;TU } ZExcept for the classes , , and , these are instantiable classes. kh~    'SkTU`@ Open abstract class %STU T VThe superclass of all stream classes and a direct subclass of . It is #STU@T utnot instantiable. h% no  !STU`& r Open abstract class a.STU ' asRA subclass of  supporting the Positionable Stream Protocol. It is STU@'  bnot instantiable. UQH ya nl lyQH  HkII ntelm Q ۍ o[Y chlm Q llList of Figures Specificationݍ ptarqsl ލ qsptaml l rr sesl ߍ rp anl  I>, tqnte: "<$paranum><$paratext><$pagenum> lm z sqp T lm z llList of Tables Specificationf  ttnouw% H~ uwt& H~lvv of H~ vt etrH~]stantiabuHe; 1, 23 lye@ $<$symbols><$numerics><$alphabetics> eA  Level3IX eB ] Level2IX eC  Level1IX oeD atLSymbols[\ ];Numerics[0];A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z eE  <$pagenum> sea l HNbl-^m wut rHNbl-^m HuHuIndex SpecificationlQH  x QH "<$parat>=UTU  ]from page  79 , means only that the result of using unread-element in the case i;UTUD described is undefined: tPU)TU  QIt is an error to apply unread-element to an element that is not the eleNU7TU@ )ment most recently read from the stream. LUKTU  LOnly when we specifically mention signaling do we mean that a Streams impleHJUYTU Pmentation must signal an error condition. Note that we may not, in such a case, HUgTU LeMsay exactly which error condition must be signaled; if we do not say so, the FUuTU olLchoice is again up to the implementor. In this text from the description of DUTU gee stream-position-setter  on page  77 , for instance, we state that an implementaBUTU@ x Jtion must signal an error, but we do not say what error must be signaled: @UTU  ]When position is a , if it is invalid for some reason, this n>UTU@ sufunction signals an error. t condition. y UUdp seGoals of the library 3U/TU`? ,The Dylan Streams library aims to provide: s1UCTU N IA generic, easy-to-use interface for streaming over sequences and files. d/UQTUN FThe same high-level interface for consuming or producing is available -U_TUN  wGirrespective of the type of stream, or the types of the elements being or,+UmTU@N  wstreamed over. si)UTU`O 8Efficiency, especially for the common case of file I/O. 'UTU`P id4Access to an underlying buffer management protocol. s%UTU 0 EAn extensible framework. Other areas of functionality that require a i#UTU@0 -e?stream interface should be easy to integrate with the library. act!UTU < t MThe proposal presents the design of a Streams library that meets these goals nUTU@< plFusing Dylans built-in sequences and a buffered disk file interface. UTU`3 EThe proposal does not address a number of related issues, including: tQH  y\ reQH ov  IA ^ to h( ng   UTUTU`) saOpen abstract class e RUTU * roPA subclass of  supporting the Stream Extension Protocol and the hePU+TU@* en1Buffer Access Protocol. It is not instantiable. iNU?TU + OStreams of this class support the buffer-size: init-keyword, which can AcLUMTU+ inJbe used to suggest the size of the streams buffer. However, the instantiJU[TU+ fuHated stream might not use this value: it is taken purely as a suggested beHUiTU+  wKvalue. For example, a stream that uses a specific devices hardware buffer a FUwTU+ atFmight use a fixed buffer size regardless of the value passed with the DUTU@+ di buffer-size: init-keyword. 3 h-  d  BUTU`. suOpen abstract class H@UTU / LThe class of streams over disk files. It is a subclass of UTU@/  ,stream> and . re 2U?TU`4  iOpen instantiable class te0UUTU 5 + KThe class of streams over sequences. It is a subclass of . ,UwTU 6 e GThe  class can be used for streaming over all :*UTU6 3 Ssequences, but there are also subclasses , , and , which are specialized for &UTU@6 ststreaming over strings. d-$UTU 7 aThe class supports several init-keywords: contents:, direction:, start:, "UTU@7 anand end:. h8 re  e UTU`9 0 Open instantiable class thUTU`: RThe class of streams over strings. It is a subclass of . HH  zg xtsHH -nh3 k ueTUTU  4 C#f No action. This is the default when the streams direction reaRUTU@  I0is #"input" or #"input-output". PU,TU*` #"new-version" 6 N=TU  ue:If the underlying file system supports file versioning, a LKTU 3 =new version of the file is created. This is the default when JYTU@ ng.the streams direction is #"output". HkTU  ea9If the file system does not support file versioning, the tFyTU gs9implementation should substitute one of the other if-eDՇTU ts@exists behaviors; the #"replace" behavior is a good anBՕTU@  choice. @թTU  stQ#"overwrite"3Set the streams position to the beginning of the file, but l>շTU r :preserve the current contents of the file. This is useful <TU  >when the direction is #"input-output" and you want to :TU@ overwrite an existing file. 8TU` NoI#"replace"Delete or rename the existing file and create a new file. 6TU  utK#"append"Set the streams initial position to the end of the existing =4 TU@ If;file so that all new output occurs at the end of the file. U2TU  veR#"truncate"If the file exists, it is truncated, setting the size of the file 0+TU@ 6to 0. If the file does not exist, create a new file. .?TU` or?#"signal"Signal a  condition. ld ,STU  thZThe if-does-not-exist init-keyword allows you to specify an action to take if the *aTU@ ?file named by locator does not exist. The options are: S(uTU` si#fNo action. &ՉTU   lP#"signal"$ Signal a  condition. This $՗TU@ wh@is the default when the streams direction is #"input". "իTU  wrJ#"create"Create a new zero-length file. This is the default when the չTU@ e Dstreams direction is #"output" or #"input-output". reTU  ioYBecause creating a file stream .always involves an attempt to open the underlying TU e.Qfile, the aforementioned error conditions will occur during file stream instance iTU@  finitialization. HH  { a aHH Signal asthj d   close TUTU`k noOpen generic function `l ci+close stream #key #all-keys => () RU0TU`m 9Closes stream, an instance of . S UUd o !Reading and writing from streams nOUhTU  l WIt is an error to call any of these functions on a buffered stream while its buffer is ultMUvTU@  dheld. UUlW  Reading from streams "JUTU   aOThe following are the basic functions for reading from streams. To implement a s dHUTU ouSnew input stream that is not a , you must provide methods stFUTU  ofor read-element, stream-input-available?, peek, read, read-into!, and occDUTU eaMdiscard-input. If you implement a new stream that is a , you might need to supply a new method for unread-element. h    read-element @UTU` erOpen generic function ` ead-element input-stream #key on-end-of-stream => element-or-eof of >U,TU   MReturns the next element in the stream. If the stream is not at its end, the t condition. ea0UTU  .PIf no input is available and the stream is not at its end, read-element st.UTU@ ht&blocks until input becomes available. ,UTUn 7See also  unread-element, page 79 . h er  peek *UTU` Open generic function ` Speek input-stream #key on-end-of-stream => element-or-eof neQH  | n aQH advancedexTUTU` OBehaves as read-element does, but the stream position is not advanced. U)h Th  read -RU)TU`  aOpen generic function =` d ^read input-stream n #key on-end-of-stream => sequence-or-eof PURTU`  NReturns a sequence of the next n elements from input-stream. NUfTU U FThe type of the sequence returned depends on the type of the streams LUtTUU Runderlying aggregate. For instances of , the type of the JUTUU esJresult is given by type-for-copy of the underlying aggregate. For HUTUU Uinstances of , the result is a vector that can contain elements FUTU@U utKof the type returned by calling stream-element-type on the stream. HDUTU  SThe stream position is advanced so that subsequent reads start after the n BUTU@  elements. @UTU  eaVIf the end of the stream is reached before all n elements have been read, the >UTU@ )behavior is as follows. r condil4U4TU r Ution is signalled. When signalling this condition, read supplies two values: 2UBTU@ foHa sequence of the elements that were read successfully, and n. s 0UVTU  m>PIf the on-end-of-stream argument was not supplied, and no elements were he.UdTU@ caOread from the stream, an  condition is signalled. eam,UxTU` ceTIf the stream is not at its end, read blocks until input becomes available. . *UTU  eaIImplementation Note: Buffered streams are intended to provide a very e(UTU Mefficient implementation of read, particularly when the result is an -&UTU@ meWinstance of , , or . Uh he read-into! rea$UTU`  nOpen generic function ` read-into! input-stream n sequence #key start on-end-of-stream => count-or-eof d."UTU  hiZReads the next n elements from input-stream, and inserts them into a muta UTU d Tble sequence starting at the position start. Returns the number of elements arHH  } rheHH reTUTU d.Tactually inserted into sequence unless the end of the stream is reached, in npRUTU@ leJwhich case the on-end-of-stream behavior is as for read. PU)TU  vekIf the sum of start and n is greater than the size of sequence, read-into! UNU7TU anTreads only enough elements to fill sequence up to the end. If sequence is a LUETU@  1stretchy vector, no attempt is made to grow it. fJUYTU  UIf the stream is not at its end, read-into! blocks until input becomes avail HUgTU@  able. FU{TU  IImplementation Note: Buffered streams are intended to provide a very sDUTU erMefficient implementation of read, particularly when the result is an BUTU@ urWinstance of , , or . h   discard-input @UTU` Open generic function ` *discard-input input-stream => () >UTU  RDiscards any pending input from input-stream, both buffered input and, if  so that applications can call this function on to4U.TU@  i5any kind of stream. The default method does nothing. Ph em$  stream-input-available? e 2UPTU` e Open generic function d` plDstream-input-available? input-stream => available? 0UyTU  anaReturns #t if input-stream would not block on read-element, otherwise it .UTU@ direturns #f. ,UTU  erJThis function differs from stream-at-end?. When stream-input- *UTU _available? returns #t, read-element will not block, but it may detect that  (UTU y Mit is at the end of the streams source, and consequently inspect the on-n&UTU@ efIend-of-stream argument to determine how to handle the end of stream. tQH ¦ ~ dioQH    ult methea UUd s /Convenience functions for reading from streams anSUTU  gQThe following is a small set of convenient reading functions that search for parlQU*TU Oticular elements in a stream. These functions behave as though they were impleinOU8TUL Umented in terms of the more primitive functions described in  Section 0.5.1 . uZh   read-to MUZTU`  Function n  #fsread-to input-stream element #key on-end-of-stream test => sequence-or-eof  y@  found? tKUTU  enPReturns a new sequence containing the elements of input-stream from the eIUTU  sVstreams current position to the first occurrence of element. The result does GUTU@ honot contain element. EUTU y dThe second return value is #t if the read terminated with element, or #f if CUTUy  Dthe read terminated by reaching the end of the streams source. The  AUTUy  Gboundary element is consumed, that is, the stream is left positioned U?UTU@y laafter element. hes=UTU   aPThe read-to function determines whether the element occurred by calling it;U TU ri]the test function test, which defaults to \==. The test function must accept i9UTU  Htwo arguments. The order of the arguments is the element retrieved from am7U&TU@ =>.the stream first and element second. 5U:TU  QThe type of the sequence returned is the same that returned by read. The m3UHTU@ Aend-of-stream behavior is the same as that of read-line. jh .  read-through 1UjTU` no Function ~` ^read-through input-stream element #key on-end-of-stream test `  i+=> sequence-or-eof found? by/UTU  of]This function is the same as read-to, except that element is included in the s-UTU@ tiresulting sequence. +UTU V emXIf the element is not found, the result does not contain it. The stream is left en)UTU@V in"positioned after element. h   read-to-end ='UTU` ti Function e`  6read-to-end input-stream => sequence QH Ʀ  >thQH eTUtyh d  write TUTU` Open generic function ` ofSwrite output-stream sequence #key start end => () reRU0TU  [Writes the elements of sequence to output-stream, starting at the streams  PU>TU@ -scurrent position.  NURTU   iRThe elements in sequence are accessed in the order defined by the forward LU`TU Riteration protocol on . This is effectively the same as the folJUnTU@  lowing: ` >do (method (elt) write-element(stream, elt) end, sequence); `  sequence; inHUTU   cIf supplied, start and end delimit the portion of sequence to write to the FUTU -t[stream. The value of start is inclusive and that of end is exclusive. They thDUTU@ 6default to 0 and sequence.size, respectively. BUTU   WIf the stream is positionable, and it is not positioned at its end, write over@UTU Kwrites elements in the stream and then advance the streams position to be Wr>UTU@ of!beyond the last element written. e, , , or ing6U,TU  O, and the streams element type is the same as the element type of  4U:TU@ insequence. \h   force-output 2U\TU` heOpen generic function p` he)force-output output-stream => () 0UTU` s SForces any pending output from output-streams buffers to its destination. to.UTU d e.HWhen creating new stream classes it may be necessary to add a method to e,,UTUd itRthe force-output function, even though it is not part of the Stream Exten*UTU@d dvsion Protocol. poh  synchronize-output the(UTU` teOpen generic function ` ot0synchronize-output output-stream => () veHH Ȧ  ntiHH arnce y TUTU  SForces any pending output from output-streams buffers to its destination. RUTU SBefore returning to its caller, synchronize-output also attempts to ensure  PU#TU . Ithat the output reaches the streams destination before, thereby synchrofNU1TU@ :nizing the output destination with the application state. LUETU  esHWhen creating new stream classes it may be necessary to add a method to n.JUSTU d Rthe synchronize-output function, even though it is not part of the Stream HUaTU@ thExtension Protocol. fh gh discard-output e SFUTU` Open generic function `! +discard-output output-stream => () DUTU`" er@Attempts to abort any pending output for output-stream. reBUTU # HTA default method on  is defined, so that applications can call this @UTU@# Afunction on any sort of stream. The default method does nothing. mUUd$ Reading and writing by lines .=UTU`%  KThe following functions facilitate line-based input and output operations. s t;UTU & LThe newline sequence for string streams is a sequence comprising the single s9U%TU& Wnewline character \n. For character file streams, the newline sequence is whatWh7U3TU& reLever sequence of characters the underlying platform uses to represent a new5UATU& utGline. For example, on MSDOS platforms, the sequence might comprise two th3UOTU@& ol6characters: a carriage return followed by a linefeed. 1UcTU '  gTImplementation Note: The functions described in this section are potentially an /UqTU' AtKinterim solution to one aspect of the more general problem of encoding and # -UTU' thKdata translation. At some point, these functions may be moved into, or subU+UTU' y Psumed by, another higher level library that deals with the encoding problems in Re)UTU' byQa better way. Note that no other functions in the Streams library do anything to n'UTU' s.[manage the encoding of newlines; calling write-element on the character \n e s%UTU' Vdoes not cause the \n character to be written as the native newline sequence, #UTU@' except by coincidence. ce h un read-line !UTU` t Open generic function `( amhread-line input-stream #key on-end-of-stream => string-or-eof newline? etQH ʦ  gQH ed in th pTUTU ) UReturns a new string containing all the input in input-stream up to the next RUTU@) thnewline sequence. t sPU)TU W unGThe resulting string does not contain the newline sequence. The second er NU7TUW ry]value returned is #t if the read terminated with a newline or #f if the read hLUETU@W e 5terminated because it came to the end of the stream. aJUYTU * ofNThe type of the result string is chosen so that the string can contain characHUgTU*  nQters of input-streams element type. For example, if the element type is FUuTU@* exB, the string will be a . DUTU +  g[If input-stream is at its end immediately upon calling read-line (that is, mBUTU+ r-Kthe end of stream appears to be at the end of an empty line), then the end-Q@UTU+ Pof-stream behavior and the interpretation of on-end-of-stream is as for rn>UTU@+ taread-element. h m read-line-into!  @,  t$string-or-eof newline? i:U TU - YFills string with all the input from input-stream up to the next newline h8UTU- ltZsequence. The string must be a general instance of  that can hold 6U%TU@- le(elements of the streams element type. e 4U9TU  * ]The input is written into string starting at the position start, which is an f2UGTU@ integer defaulting to 0. 0U[TU  ea[The second return value is #t if the read terminated with a newline, or #f n e.UiTU@ heAif the read completed by getting to the end of the input stream. t,U}TU = offIf grow? is #t, and string is not large enough to hold all of the input, this *UTU@=  2function takes one of the two following actions. (UTU` in[If string is stretchy, read-line-into! grows it enough to hold the input. &UTU  stYIf string is not stretchy, read-line-into! creates a new string which it $UTU utLwrites to and returns instread. The resulting string holds all the original ri"UTU enNelements of string, except where read-line-into! overwrites them with UTU@ me"input from input-stream. HH ̦  tg HH arTUgeTUTU  XIn a manner consistent with the intended semantics of grow?, when grow? oRUTU igis true and start is greater than or equal to string.size, read-line-into! IfPU#TU@ Ogrows string to accomodate the start index and the new input. UNU7TU  fugIf grow? is #f (the default) and string is not large enough to hold the input, reaLUETU@ rothe function signals an error. JUYTU M stQThe end-of-stream behavior and the interpretation of on-end-of-stream is hHUgTU@M 'the same as that of read-line. Thh  h write-line inaFUTU`  Open generic function `1 heVwrite-line output-stream string #key start end => () DUTU`S PWrites string followed by a newline sequence to output-stream. BUTU  WThe default method behaves as though it calls write on string and then @UTU@ Mcalls new-line, with output-stream locked across both calls. e>UTU 3 aIf supplied, start and end delimit the portion of string to write to the e () 8UATU` Th5Writes a newline sequence to output-stream. o6UUTU   TA method for new-line is defined on  that writes the h4UcTU@ na+character \n to the string stream. UUd wrQuerying streams -1UTU  inIThe following functions can be used to determine various properties of a /UTU@ edstream. in-UTU 8 ouMTo implement a new stream you must provide methods for stream-open?, i+UTU@8 5stream-at-end?, and stream-element-type. ah9  stream-open? t)UTU` roOpen generic function ` up.stream-open? stream => open? QH Φ  eQH amstri TUTU`: JReturns #t if stream is open and #f if it is not. )h li stream-element-type > RU)TU`  Open generic function =`; pu<stream-element-type stream => element-type ePURTU`< FReturns the element type of stream as a Dylan . th st stream-at-end? NUtTU`= yiOpen generic function `> ow2stream-at-end? stream => boolean LUTU  bReturns #t if the stream is at its end and #f if it is not. For input streams, it JUTU Xreturns #t if a call to read-element with no supplied keyword arguments HUTU@ am0would signal an . n FUTU  upPThis function differs from stream-input-available?. See the description DUTUN H%of that function on page  69 . BUTU`? BFor output-only streams, this function always returns #f. UUlA y ! Positionable stream protocol ?U$TU`B le?The following comprises the protocol for positionable streams. =U8TU C leDTo implement a new positionable stream you must provide methods for ;UFTUC enUstream-position, stream-position-setter, adjust-stream-position, -9UTTU@C Fstream-size, stream-contents, and unread-element. 7UhTU D bKA stream position can be thought of as a natural number that indicates how end5UvTUD  iOmany elements into the stream the streams current location is. However, it is l t3UTUD Pnot always the case that a single integer contains enough information to reposiQtion a stream. Consider the case of an uncompressing file stream that requires ?/UTUD riRadditional state beyond simply the file position to be able to get the next input -UTU@D nl$character from the compressed file. s +UTU E PThe Streams library addresses this problem by introducing the class , which is subclassed by various kinds of stream implementations 'UTUE usMthat need to maintain additional state. A stream can be repositioned as effio%UTUE  Tciently as possible when stream-position-setter is given a value previously en#UTU@E re4returned by stream-position on that stream. n HH Ц  iicHH into thereTUTU r HoVIt is also legal to set the position of a stream to an integer position. However, for RUTUr n Psome types of streams, to do so might be slow, perhaps requiring the entire conssPU#TU@r ha1tents of the stream up to that point to be read. bEh il  NUETU` t Abstract class nlLU[TU G hePA direct subclass of . It is used to represent positions within emJUiTUG e Istreams of a certain kind: those for which a natural number is not suffidHUwTUG ofJcient to fully describe the position in the stream. For example, a stream FUTUG  cIthat supports compression will have some state associated with each posiDUTU@G -sItion in the stream that a single integer is not sufficient to represent. BUTU`H SThe  class is disjoint from the class . hF  stream-position @UTU` Open generic function `I thAstream-position positionable-stream => position >UTU`J  tTReturns the current position of positionable-stream for reading or writing.  or an > :UTU$ t Ointeger. When the value is an integer, it is an offset from position zero, and It 8U"TU$ ntMis in terms of the streams element type. For instance, in a Unicode stream, w6U0TU@$ be@a position of 4 means that 4 Unicode characters have been read. poRh am#  !stream-position-setter G 4URTU` s Open generic function f`K d ]stream-position-setter position positionable-stream => new-position t2U{TU`L KChanges the streams position for reading or writing to position. ass0UTU`o . GThe position can be either an integer or a . n g.UTU M PWhen it is an integer, if it is less than zero or greater than positionable- ,UTU@M  t;stream.stream-size this function signals an error. fo*UTU N ng]When position is a , if it is invalid for some reason, this (UTUN Ufunction signals an error. Streams are permitted to restrict the position to ,&UTUN  Dbeing a member of the set of values previously returned by calls to U$UTU@N 0(stream-position on the same stream. at{   stamۀ p gK HNb$R3 i HNb$R3 H-H-FootnoteHH Ԧ  m pHH  w. asso TUTUS eiFstreams), added to the number of elements written past the end of the RUTU@S te6stream (regardless of any repositioning operations). PU)TU t EIt is assumed that there is no more than one stream open on the same oNU7TUt ngNsource or destination at a time; that there are no shared references to files LUETUt Eby other processes; that there are no alias references to underlying eJUSTUt itMsequences, or any other such situations. In such situations, the behavior of yHUaTU@t  tstream-size is undefined. h he %stream-contents FUTU` Open generic function `[ ^stream-contents positionable-stream #key clear-contents? => sequence DUTU \ TReturns a sequence that contains all of positionable-streams elements from BUTU\ Jits start to its end, regardless of its current position. The type of the @UTUN\ ?returned sequence is as for read. See page  68 . ast>UTU ] [Note: For streams whose direction is #"input", stream-contents signals It element tai0UsTU  tiYUnreads the last element from positionable-stream. That is, it returns eleo.UTU tibment to the stream so that the next call to read-element will return element. ,UTU@ 4The stream must be a . #*UTU  tr]It is an error (i) to apply unread-element to an element that is not the eles(UTU ag[ment most recently read from the stream; (ii) to call unread-element twice th&UTU heWin succession; (iii) to unread an element if the stream is at its initial posi. T$UTU toStionl; and (iv) to unread an element after explicitly setting the streams aft"UTU@ ll position. HH  Q HH ad` . fTUTU  onOWrapper streams provide a mechanism for working with streams which require taiRUTU tiMsuch conversion. Wrapper streams hold on to an underlying stream, delegating rPU#TU Nto it most of the operations that implement streaming. The wrapper stream carNU1TU eLries out appropriate processing in its own implementations of the streaming m>LU?TU@  protocol. JUSTU  iUThe Dylan Streams Library includes a base class called  upon HUaTU@ ce1which other wrapping streams can be implemented. u`  t)define class () ;` un!slot inner-stream :: , ` *required-init-keyword: inner-stream:; `. me end class; iciFUTU  re\A subclass of  can pass on functions such as read-element HDUTU@ Uand write-element by simply delegating these operations to the inner stream: t` ch8define method read-element (ws :: ); `/ veread-element(ws.inner-stream) an`0 , end method; #`5 toBdefine method write-element (ws :: , element); `6 (write-element(ws.inner-stream,element) in `7 at end method; reBU!TU  VAssuming that  delegates all other operations to its inner @U/TU peLstream, the following would suffice to implement a 16-bit Unicode character im>U=TU@ +stream wrapping an 8-bit character stream. () end class; d` yw4define method read-element (s :: ) cio` re=> ch :: ; am>z`  fwith-stream-locked (s) el` 1let first-char = read-element(s.inner-stream); e`c ra1let second-char = read-element(s.inner-stream) e`d leend; ` re7convert-byte-pair-to-unicode(first-char, second-char) am)`e 0 end method; odQH   telQH er+teh le Hdo-release-input-buffer enTUTU` Open generic function ` r-7do-release-input-buffer buffered-stream => () U/RU0TU  stLThe methods of this generic function implement release-input-buffer =PU>TU stHfor new streams. These methods can assume that the stream is locked, so laNULTU@ > no other thread can access it. nh yw Ido-next-input-buffer tLUnTU` reOpen generic function ` nikdo-next-input-buffer buffered-stream #key wait?, bytes => buffer-or-false reaJUTU  stMThe methods of this generic function implement next-input-buffer for eHUTU leGnew streams. These methods can assume that the stream is locked, so no ecoFUTU Hother thread can access it. Methods must signal an error if the current elDUTU Mbuffer is not held for input, or they for any reason cannot return a buffer, eBUTU npLor a buffer with the minimum number of bytes specified by bytes (an do@UTU@ fe). U/h st" Jdo-input-available-at-source? >UTU` elOpen generic function ` stMdo-input-available-at-source? buffered-stream => available? buffer r t1UTU   cMThe methods of this generic function implement get-output-buffer for e/UTU edGnew streams. These methods can assume that the stream is locked, so no ). -UTU  Mother thread can access it. Methods must signal an error if the stream is an t+UTU@  Finput only stream, or if they cannot return a buffer for any reason. z dof   ntQH   soQH amume that - h ed O s TUTU` igError RUTU  DSignalled when input functions are reading a required number of elePU+TU  nIments but they read the end of the stream before completing the required -NU9TU Qread. It is a subclass of . It takes two additional eLUGTU y Tinit-keywords, sequence: and count:. The sequence is whatever input fuJUUTU Kwas read before reaching the end of the stream. The count is the number of canHUcTU@ tr)elements that were requested to be read. h  a P uFUTU`  iError DUTU  [The base class for all errors related to file I/O. It is a subclass of . It BUTU@ *takes one init keyword, locator:. h   Q @UTU`  Error >UTU  NSignalled when an output file stream creation function tries to create a file . onsh ui  R :UTU` eyError 8U'TU  m KSignalled when an input file stream creation function tries to read a file of 6U5TU@ -e?that does not exist. It is a subclass of . ywoWh % S w4UWTU` UError 2UmTU   bKSignalled when one of the file stream creation functions tries to access a 0U{TU  tJfile in a manner for which the user does not have permission. It is a sub.UTU@ Erclass of . e c UUl s  Wrapper streams t +UTU  PSometimes stream data requires conversion before an application can use it: you . )UTU  Lmight have a stream over a file of EBCDIC characters which you would prefer Si'UTU tpNto handle as their ASCII equivalents, or you might need to encrypt or decrypt %UTU@  I file data. s QH ֦  uiQH xi` eyUUd enUsing file streams crSUTU`_ ie<The following are operations that pertain to file streams. I>h`    'close QU>TU`  G.f. method  R`a rm<close file-stream #key abort wait? bOUgTU b neJCloses a file stream. This method frees whatever it can of any underlying MUuTU@b nn/system resources held on behalf of the stream. t iKUTU c TIf abort is false (the default), any pending data is forced out and synchrot IUTUc Wnized with the files destination. If abort is true, then any errors caused by UGUTUc t Xclosing the file are ignored. Furthermore, if abort is true, the file should be tpEUTUc irPrestored to its initial state if possible (for example, on a versioned file sysfiCUTUc HKtem, the previous version of the file should be restored as the latest verAUTU@c sion). h  (with-open-file str?UTU` Macro `e e \with-open-file (stream-var = locator, #rest keys) body end =UTU * RGProvides a safe mechanism for working with file streams. The macro cre;U(TU* b _ates a file stream and binds it to stream-var, evaluates a body of code within nn9U6TU*  hIthe context of this binding, and then closes the stream. The macro calls a7UDTU@*  a&close upon exiting body. 5UXTU`F c EThe .locator argument should evaluate to a valid argument to l`G byas(, locator) th3UTU`H . AThe values of the last expression in body are returned. 1UTU`h orMThe keys are passed to the make method on . /UTU i teSFor example, the following expression yields the contents of file foo.text -UTU@i as a : -o`j 9with-open-file (fs = ("foo.text", element-type: )) `  read-to-end(fs) s` end; +UTU`k It is roughly equivalent to: noreAat aQH ڦ  ,QH TUcoTUTU  tLdirectly manipulate a streams buffer from within routines that are already xiRUTU  Ldirectly manipulating the streams buffer. This situation must be forbidden arPU#TU Qbecause the inner call to get the buffer cannot reliably return the state of the NU1TU@ n @streams buffer while the application already holds the buffer. Sh he *stream-locked? on LUSTU`  Function g`p pl2stream-locked? stream => boolean JU|TU`q LReturns #t if stream is locked and #f if it is not. wih  ( +lock-stream t-HUTU`  Function `r (f"lock-stream stream => () FUTU`s ItLocks stream. : nDUTU L TIf stream is already locked by another thread, this function waits until it BUTU@L ,gets the lock. @UTU`t IIn a single-threaded Dylan implementation, this function does nothing. ph uf ,unlock-stream >UTU` ad Function 3`u ct#unlock-stream stream => () Thi, 2`J 6locator: "foo.text", element-type: ); =` let fs = hidden-fs; H`m read-to-end(fs); HS`  cleanup ^` b'if (hidden-fs) close(hidden-fs) end; i` H end block; t` end;  UUln  )Locking streams SUTU o NStream locks have multilocking semantics. That is, a single thread can lock a QUTUo Nstream more than once, but the thread must unlock the stream for each time it OUTUo Olocked the stream. Furthermore, threads waiting for a stream lock are expected MUTU@o H)to do so by blocking, not by spinning. KUTU  SThis allows a high-level printing routine to lock a stream across several calls to in IUTU Poutput functions, ensuring all the output is contiguous at the streams destina GUTU 'Vtion. For example, the write-line function locks its stream argument and then EUTU ",dcalls the write and new-line functions. The write function locks its stream d(CU TU Oargument by calling get-output-buffer, but because of the multilocking AU.TU Hcsemantics, the call to write within write-line does not block waiting for a lock. o ?U<TU  h[The same thing happens with new-line. Before returning, write-line unlocks mor=UJTU heQthe stream so that other routines may call output functions on the stream or get r;UXTU@ th-the streams buffer for direct manipulation. 9UlTU K HQThe Locking Protocol isolates access to a stream so that only one thread may use h7UzTUK utNthe stream at any time. In a single-threaded Dylan implementation, these func5UTU@K lltions do nothing. uou3UTU  deRThe Buffer Access Protocol functions that get a buffer first lock the stream, and 1UTU Rthose functions that release the buffer unlock the stream. Thus, getting a buffer /UTU eSboth isolates access to the stream for a single thread and ensures that the single put-UTU ecQthread does not try to get the streams buffer multiple times while already hold+UTU@ e-ing the buffer. bl)UTU  loQThe Buffer Access Protocol isolates access to a buffer within a single thread to r'UTU e-Mprevent reentrancy problems and programming mistakes. Essentially, the light %UTU onRweight buffer locking ensures that applications do not call output functions that QH  rocQH  Hhh e hQH a eInQH  HVV a  otolHH ܦ  reHH  at relea unTUTU b tiEUpon exiting the body, the code resulting from the macro unlocks the rRUTU@b nd)stream once, as a block cleanup. 8 UUdz noUsing buffered streams buOUMTU { s QA goal of the streams library is to provide efficient support for general use of hMU[TU{ otNbuffered I/O. At the same time, programmers using the library should not need KUiTU{ cyQto be concerned with buffering in most cases. For most uses of buffered streams, eIUwTU{ g Mthe buffering is transparent, but programs requiring more control can access GUTU{ Obuffering functionality when appropriate. This section describes the available EUTU@{ buffering functionality. UUd~  Overview BUTU | NA buffered stream maintains some sort of buffer. All buffered streams use the @UTU| Zsealed class  for their buffers. You can suggest a buffer size when creat>UTU| King buffered streams, but normally you do not need to do so. Streams impleloc also contain some state information. This state . 6U"TU prLinformation includes an index where reading or writing should begin, and an ne4U0TU n Rindex that is the end of input to be read, or the end of space available for writ2U>TU@ t ing. 0URTU  ntXBuffered streams also maintain a held state, indicating whether the application on.U`TU ilMhas taken the buffer for a stream and has not released it yet. When a thread v,UnTU Valready holds the buffer for a stream, it is an error to get the buffer again (or any *U|TU Sother buffer for the same stream); this property holds for the one thread of a sin cr(UTU | Kgle-threaded Dylan implementation as well as for multi-threaded implementaple&UTU@ | tions. atzUUl}  b .Buffer access protocol ate#UTU ~ g NThis section describes the functions that users of buffered streams invoke to !UTU~ buKmanipulate stream buffers directly. These functions use corresponding funcprUTU~ udPtions from the Stream Extension Protocol to do their work. For example, get-inUTU~ d Winput-buffer calls do-get-input-buffer. All Stream Extension Protocol funcURHH a ninHH  H {{ U`a atrt t.QH ަ  dhoQH  tr  et the b!r TUTU~ otVtions are named with a do- prefix on the corresponding Buffer Access Protocol RUTU@~ glJfunction. Users should never call the Stream Extension Protocol directly. PU)TU  | DThreaded Dylan implementations should place system-dependent mutual NU7TU  sPexclusion calls in the Buffer Access Protocol functions. All streams implementaLUETU teRtions are encouraged to check the buffer-held state in the Buffer Access Protocol JUSTU heOfunctions, and these functions should signal an error if the buffer is already ~ HUaTU Lheld. The separation of the Buffer Access Protocol and the Stream Extension HFUoTU  NProtocol allows users to more portably extend the buffered stream protocol to DU}TU Inew stream types. Programmers avoid the following design and maintenance BUTU@  hassles: @UTU  EDeciding whether to write for a threaded or non-threaded Dylan imple>UTU@ ti mentation. wi. izUUd he Useful types when using buffers h rs  / U#UTU` PrType t!UTU` feHA type representing limited integers in the range 0 to 255 inclusive. erh mi 0 aUTU` sType UTU   QA type representing 8-bit characters that instances of  can nUTU@  contain. orQH a nthQH  H|| area r QH   yntQH hi"" #ch"TUTU  PCalls do-get-input-buffer to return a buffer for the stream. You should RUTU@ hi1never call do-get-input-buffer directly. mPU)TU  gTThe stream extension function signals an error if buffered-stream is an outNU7TU@ ulBput-only stream, or if it cannot return a buffer for any reason. LUKTU X TybThe wait? keyword is a  and defaults to #t. It indicates whether JUYTUX miIget-input-buffer should ensure that there is valid data in the input HUgTU@X 8-+buffer, and block for input if necessary. rinFU{TU  \When wait? is #f, this function returns the streams current buffer in whatDUTU@ ever state it is in. BUTU  ^When wait? is #t, do-get-input-buffer waits until there is some valid @UTU HQdata in the buffer. If do-get-input-buffer needs to wait for valid data, >UTU Land it encounters the end of the stream before any valid data arrives, then  or #f, and is the minimum number of bytes that must be h6UTU ywQpresent in the buffer when it is returned. If do-get-input-buffer cannot 4UTU inJreturn a buffer with the specified minimum number of bytes, it signals an 2UTU@ er. 0U'TU  VValues supplied for bytes should be small relative to a buffers size. If you .U5TU Ineed to read large numbers of bytes at once, specify a large buffer size ?,UCTU , Owhen making the stream and do not specify any values for the bytes keyda*UQTU If]word parameter. When bytes is not #f, get-input-buffer may block for t(U_TU@  sinput if necessary. d&UsTU  LIf an application thread calls get-input-buffer, and another thread $UTU bJalready holds any buffer the stream owns, then this function might block. "UTU BMulti-threaded implementations should eventually return. In multi- UTU  hHthreaded implementations this function calls lock-stream before calling -gUTU@  7do-get-input-buffer, and it does not release the lock. eciUTU  r MIf an applications thread calls this function, and that same thread already UTU VaHholds the buffer, this situation is a re-entrancy programmer error. The e.UTU Kstream cannot return the buffer and guarantee that its state is up to date siUTU  Iwith input consumption that occurred between the first call to this funcsUTU Ition and the current call. Implementations should detect and signal this -UTU@ ayerror. tHH a dsHH  H }}  a  ff tHH   o. HH Mu!!ions sho0 r!TUTU Rguages has shown that it is .very useful to provide delegation for wrapper RUTU  Ostreams. So we provide an explicit implementation of delegation in the streams IfPU#TU@ thsystem. tNU7TU  thPDelegation is implemented by the use of the outer-stream slot, which is a LUETU@ mm,defined in the base class : anY` fe*define abstract class () d`x  =slot outer-stream :: , init-keyword: outer-stream:; lo`y  end class; JUTU  rePouter-stream is used instead of the stream itself whenever a stream invokes r.HUTU@  $one of its other protocol methods. HFUTU  HYNote: A stream must not use inner-stream if performing recursion, since this DUTU@ ff"would cause an infinite regress. BUTU  HUA correct implementation of the read method in the example above would be as @UTU@ as follows: `  u6define method read (stream :: , ` wen :: e`z io!#key on-end-of-stream) `{ 7prompt(s.outer-stream); n`|  tnext-method() ou!`} t, end method; E>U6TU  deeThe initialize method on  is defined to set the outer-stream slot to c is special cl:URTU@ Eized to set the outer-stream slot to be the parent stream: rf` r.6define method initialize (stream :: , q`~  # #key on, #rest all-keys); |`  i)an-inner-stream.outer-stream := stream; `f d next-method() re`l  end method; rr8UTU   oPImplementation Note: One disadvantage of this scheme is that it may prevent fo6UTU Ruseful optimizations, such as inlining. If this is an important performance issue 4UTU inPin circumstances where wrapper streams are not necessary, then it is relatively 72UTU stUsimple to provide an implementation of the streams module that omits the del0UTU@ Thegation mechanism. metQH a hQH  H~~ am a wralclQH   ur-QH th%%/ne%`g  :5define method write-element(s :: , ` !c :: ); -`h m Blet (first-char, second-char) = convert-unicode-to-byte-pair(c); '`i rrwith-stream-locked (s) em2`  O-write-element(s.inner-stream, first-char); r=`j -write-element(s.inner-stream, second-char) gH` poend; S`k c ^` ms end method; raq`m ot7define method stream-position (s :: ) si|`  i=> p :: ; `n e /truncate/(stream-position(s.inner-stream), 2) me`o H end method; `q h7define method stream-position-setter(p :: , ~` *s :: ); `r al*stream-position(s.inner-stream) := p * 2 `s  end method; UUd Wrapper streams and delegation SUTU  deKOne problem with wrapper streams is the need for a wrapper stream to interQUTU acMcept methods invoked by its inner stream. For example, consider two hypothettOUTU '^ical streams,  and , the latter a subclass MU#TU =\of . Both of these classes have a method called prompt. The SKU1TU@ c> class specializes read thus: E` -p1define method read (s :: , P` ntn :: , [`t m-"#key on-end-of-stream); f`u en prompt(s); q`v denext-method() m-p|`w :: end method; IUTU  ^If a $ is used to wrap an  then an invoGUTU ]cation of read on the  will call prompt on the inner EUTU leV, not on the , as desired. The problem CUTU okVis that the  wants to delegate some tasks to its inner stream, AUTU@ ac$but handle some other tasks itself. m>?UTU   sNSome languages, notably Self, support such delegation in the language. Dylan, =UTU leMin keeping with other generic-function-based languages, does not, but experie;UTU Kence with streams packages in a number of other generic-function-based lan HH a e, HH  H MM a  de7 If iH$| U  tH$ read ]iaTUTU*nZ  Running H/F 2  QH a , QH  H a tammeasH1 icbuitFootnoteHH   e, HH n =UTU$inh c- 7release-input-buffer oTUTU` e Function ` h 3release-input-buffer buffered-stream => () n-bRU0TU  HICall this function to announce that you have finished using the streams PU>TU MMcurrent buffer. There may still be valid input in the buffer even though you NULTU@ have finished with it. LU`TU  OThis function calls do-release-input-buffer so that the stream can perJUnTU Eform any record-keeping or management tasks it has. You should never HU|TU@  /call do-release-input-buffer directly. QFUTU   JAfter consuming input from the buffer, you must update the buffers state DUTU Pby assigning to buffer-next before releasing the buffer. When a user of BUTU@ FoOthe Buffer Access Protocol sets buffer-end, the results are undefined. @UTU  NIf the calling application does not hold the buffer, this function signals an >UTU@ eerror. n buffer-or-false ,UTU  OCall this function to get more input when you are already holding buffered- re*UTU Pstreams buffer. If the application does not hold the streams buffer, this  (UTU@ r function signals an error. &&UTU  wiOThis function calls do-next-input-buffer to get more input. You should $UTU@ ; 3never call do-next-input-buffer directly. on HH a  bHH  H  ultQH   pofQH  ter the %asTUTU  buNYou must update the buffers state by assigning to buffer-next before RUTU edJgetting the next buffer; otherwise, it might seem that the current buffer PU#TU  nWstill has valid input in it. When buffer-next = buffer-end there is no yteNU1TU@ r-.valid input remaining in the current buffer. LUETU  reRIf a user of the Buffer Access Protocol sets buffer-end while holding the JUSTU@ ap,streams buffer, the results are undefined. hiHUgTU   NThe stream extension function may return a new  object or the FUuTU ffXcurrent one with buffer-next and buffer-end updated to reflect the loca-bDUTU . Ftion of the new input data. You should not make any assumptions about BUTU@ .which option a streams implementation uses. @UTU   pLThe do-next-input-buffer function signals an error when the current >UTU@  buffer is not held for input. available? 8UTU   bYReturns #t when buffered-streams source has any available input or when 6U TU e Vthe stream is at the end of its source. If this function returns #t, the next 4U.TU@ si2call to next-input-buffer will not block. 2UBTU  MThis function calls do-input-available-at-source? to get more input. o0UPTU@ -bGYou should never call do-input-available-at-source? directly. as.UdTU  KCall this function while you are holding a streams buffer. If the applica ,UrTU@ exHtion does not hold the streams buffer, this function signals an error. *UTU  s JThe stream extension function signals an error when the current buffer is (UTU@ e not held for input. pu|UUd Using buffers for output -h e? ;get-output-buffer %UTU`  Function ` atQget-output-buffer buffered-stream, #key bytes => buffer na  ur owhHH ` t eHH hit, taTUTUe, ne iHH   HH ll  -at-sour& m TUTU   WCalls do-get-output-buffer to return a buffer for buffered-stream. You RUTU@ s :should never call do-get-output-buffer directly. PU)TU  IThe stream extension function signals an error if the stream is an input eNU7TU Konly stream, or if it cannot return a buffer for any reason. The resulting ferLUETU@  3buffer is never completely full of pending output. ng JUYTU   -VThe bytes keyword is an , and is the minimum number of bytes HUgTU utIthat must be available for writing in the buffer when it is returned. It FUuTU  Odefaults to 1. If do-get-output-buffer cannot return a buffer with the DUTU@  e9specified minimum number of bytes, it signals an error. BUTU g VValues supplied for bytes should be small relative to a buffers size. If you @UTUg Jneed to write large numbers of bytes at once, specify a large buffer size >UTUg erOwhen making the stream and do not specify any values for the bytes keysh () $UTU  d ICall this function to announce that you have finished using the streams "UTU -TEcurrent buffer. When you have written output to the buffer, you must . UTU  Supdate the buffers state by assigning to buffer-next before releasing the calUTU  Obuffer. When a user of the Buffer Access Protocol sets buffer-end, the UTU@ plresults are undefined. is UTU`  sMIf the application does not hold the buffer, this function signals an error. H 2 a`H 2l a its5  withfiQH   aYQH . etect an'erTUTU  bPThis function calls do-release-output-buffer so that the stream can perreRUTU r Eform any record-keeping or management tasks it has. You should never nPU#TU@ yo0call do-release-output-buffer directly. NU7TU  erNIn multi-threaded implementations, release-output-buffer releases the LUETU@ st,lock obtained in get-output-buffer. rgh  =with-output-buffer WhJUgTU` ufMacro {` \with-output-buffer (buffer-var = exp, #key bytes) body end; IfHUTU  oelCalls get-output-buffer on exp and bytes, binding buffer-var to the result, FUTU@ lDthen executes body within the scope of the buffer binding. DUTU  YAfter the body has executed, with-output-buffer calls release-output-BUTU@ <buffer and returns any values returned by body. Thh  >next-output-buffer r@UTU` eaMacro `  Qnext-output-buffer buffered-stream #key bytes => buffer >U TU   JCall this function to get the next buffer for writing output when you are You should never call do-next-output-buffer directly. 4U]TU  feNYou must update the buffers state by assigning to buffer-next before 2UkTU  Mgetting the next buffer; otherwise, it might seem that the current buffer is 0UyTU AfNempty (or does not contain the output you just stored in it). When buffer-.UTU@ Qnext = buffer-end there is no pending output in the current buffer. ,UTU  -oSWhen a user of the Buffer Access Protocol sets buffer-end, the results are *UTU@  undefined. es(UTU  NThe stream extension function may return a new  object or the &UTU e Pcurrent one with buffer-next updated to indicate the next available eleot$UTU Cment to be written for output. You should not make any assumptions U"UTU@  f4about which option a streams implementation uses. nHH 5 oshHH  H FF UH 2 ` steH 2ufTUinH[$ `eurH[$l && ainQH 7 ufQH  HHCC  is  Wh a  Hnf< i ,heHnf< H9 oH9 o Table RuleHq ii f Table RuleHZ inon u TableFootnoteaQH a  QH  H mptQH   ponQH ti )TUTU   MFor buffers held for input, this function returns the index of the exclusive RUTU HKend of data to be read. For buffers held for output, this function returns HPU#TU@  the size of the buffer. NU7TU` +See also buffer-end-setter, below. HYh  Bbuffer-end-setter LUYTU`  Function m` CIbuffer-end-setter new-value buffer => new-value hJUTU`  "Sets buffers end index. HUTU  fLNote: Users of the Buffer Access Protocol functions should not set this FUTU Iaccessor because the results are undefined; however, stream implementors nDUTU Hmay need to set this accessor inside Stream Extension Protocol methods, QBUTU@  7which execute while users are holding a stream buffer. h  Cbuffer-subsequence @UTU` Open generic function ` fbuffer-subsequence buffer result-class start end => sequence >U TU  ofUReturns an instance of the class result-class, filled with the elements from . end8UATU  luLImplementation Note: This function should be implemented as efficiently fe6UOTU  Pas possible. There should be sealed methods for when result-class is an ld4U]TU@ Pinstance of , , and . emh  Dcopy-into-buffer! 2UTU` siOpen generic function ` mcopy-into-buffer! buffer buffer-start sequence #key start end => () b0UTU` pCopies the portion of sequence given by the indices start and end into buffer. .UTU` 8The buffer is filled starting at buffer-start. ns,UTU`  `The start index defaults to 0, while end defaults to sequence.size. x *UTU` heHIf buffer is too small to hold the data, an error is signalled. dt fr- HH   nhoHH Nef  2 TTUTU`( odPSets the outer-stream slot of stream to wrapper-stream. e-RUTU  byZNote: Applications should not set inner-stream and outer-stream slots PU)TU  gNdirectly. The inner-stream-setter function is for use only when impleNU7TU@ qumenting stream classes.  LUKTU`3  b HTf#} ]UquHTf#l  ntoa hbu bHH   hHH ul defau*ueTUTU  LImplementation Note: This function should be implemented as efficiently naRUTU Las possible. There should be sealed methods for when sequence is an PU#TU@ Oinstance of , , or . 2Eh H Ecopy-from-buffer! NUETU`  Open generic function Y` amlcopy-from-buffer! buffer buffer-start sequence #key start end => () LUnTU  fCopies a portion of buffer starting at buffer-start into sequence. The number JU|TU amZof elements copied is determined by start and end, which are indices into HUTU lYsequence. The sequence is filled starting at start, which defaults to 0, and FUTU  pending at end, which defaults to sequence.size. If sequence is too small to DUTU@ &hold the data, an error is signalled. BUTU  hoLImplementation Note: This function should be implemented as efficiently ho@UTU odLas possible. There should be sealed methods for when sequence is an e->UTU@ byOinstance of , , or . r! UUl   FStream extension protocol ;U TU  -fMThese are the generic functions to which implementors of streams add methods 9UTU  (Swhen extending the stream protocol to new subclasses of . tar7U'TU ueSAlthough the close function is not described here, you might need to add a rt5U5TUN ,Vmethod to it when implementing a new stream. See  close, page 67 . VUUd +Creating new input or input-output streams  xh d Gdo-get-input-buffer s2UxTU` Open generic function `  t]do-get-input-buffer buffered-stream #key wait? bytes => buffer-or-f a0UTU  s LThe methods of this generic function implement get-input-buffer for bl.UTU  sGnew streams. These methods can assume that the stream is locked, so no tan,UTU riMother thread can access it. Methods must signal an error if the stream is an *UTU  pNoutput-only stream, or if they cannot return a buffer for any reason. If this (UTU  mEfunctions methods cannot return a buffer with the specified minimum &UTU@ . eHH a g nHH  H  mena  p QH   s QH  2UxTU1Op UUl  TWrapper stream protocol fe-h ea U SU-TU` buOpen instantiable class QUCTU` ofBThe class that implements the basic wrapper-stream functionality. OUWTU  neQIt takes a required init-keyword inner-stream:, which is used to specify MUeTU@ rethe wrapped stream. odKUyTU  rrMThe  class implements default methods for all of the nIUTU r Cstream protocol functions described in this document. Each default ot GUTU@ thMmethod on  simply trampolines to its inner stream. h! -e Vinner-stream EUTU` Open generic function `  ?inner-stream wrapper-stream => wrapped-stream CUTU`  p6Returns the stream wrapped by wrapper-stream. h#  s Winner-stream-setter  AUTU` Open generic function `  Minner-stream-setter stream wrapper-stream => stream s?U+TU $ aWraps stream with wrapper-stream. It does so by setting the inner-stream e=U9TU$ liislot of wrapper-stream to stream, and the outer-stream slot of stream to ;UGTU@$ rewrapper-stream. od9U[TU  rrZNote: Applications should not set inner-stream and outer-stream slots 7UiTU roNdirectly. The inner-stream-setter function is for use only when imple5UwTU@ ramenting stream classes. rah nn Xouter-stream 3UTU` inOpen generic function `% er8outer-stream stream => wrapping-stream -s1UTU`& ra5Returns the stream that is wrapping stream. th  Youter-stream-setter /UTU` inOpen generic function `' OpUouter-stream-setter wrapper-stream stream => wrapper-stream rQH a $ QH  H es a wrpeHH w teHH  H  wrHH a o:HH  H  outa ictetr amlaQH a e QH  HSS era nst& raw tam HH a nOpHH  H   a wpp   QH a QH  H  a  HH  HH  H  HH a HH  H  a  HTf#~ U  HTf# `[  n\ & 0 06 Feb 1997    #  amQH a  QH  H a wppHH  UHH  H  HH a HH  H   a  *12OWD  iH Chapter RuleQH a QH  H a QH C  QH H3v v 06vvHH a HH  H jj a  HQH a QH  H Ha x HH a HH  H  a  HH  HHBtD/ h  ZThe Streams Library pTU`. FAuthors: Scott McKay, Bill Chiles, Marc Ferguson, and Eliot Miranda. QH a QH  H a  QH  QH  H HH a HH  H  a  QH ހ QH  H QH a QH  H a   QH  QH  H ThHH a uorHH  H RR . a  HHH w HH  H  QH a QH  H H 2  H 2 ATUTU`I TNote: This document was written by Harlequin, Inc., and not by the Gwydion Project. RUTU`-  Editor: Andrew Shires. PU/TUh Date:  606 Feb 1997 . R UU`> HAbout this document tUU` Acknowledgments LUTU  MWed like to thank the other people who have been instrumental in the producJUTU Otion of this proposal: Jonathan Bachrach, Dave Berry, John Dunning, Chris Fry, HUTU IPaul Haahr, William Lott, Rob Maclachlan, Tim McNerney, Tony Mann, Keith FUTU@  2Playford, Robert Stockton, and Tucker Withington. UU`9  Discussing error conditions CUTU`6 JThis document uses two special terms in discussions of error conditions. AUTU  QYWhen we say that something is an error, we mean that the result is undefined. In ?U TU HVparticular, we do not mean that a Streams implementation must signal an error =UTU isScondition; that is the implementors choice. So, for instance, the following text, QH x QH  H  Hv AcvUvvQH h  bn QH  odOtion o$l:TUTUex er R3J i R3J R3;_R3;_ Chapter RuleNeQH { PlQH  H  9 HH z HH  H  NN  ofHH f U h wHH  n that tndTUTU`]   f  re$gn aQ$g "aisQ$l   xt,Q$h  Q$  TUTU*nu  Running H/F 4  QT$i "$QT$l## QT$j # QT$3i"3`v  nw Q' #  06 Feb 1997  PlQH k $"QH  H H[$ &` H[$HUH`/  n8 + 06 Feb 1997  #  Hq{k +Ee,_m  aQc H k ,.+sQc H l -- Qc H k -+ Qc H  ,`B  /  k .,3+  l //   k /+  .`C   k 3.6+ b  l 44 Q  k 4+   3`D  8 k 63?+ 8 l 77 H 8 k 7+ 8  ak ,6s`E  8 k ?6B+ 8 l @@  8 k @+  8  /.,3?`F l S k B?J+ S l DD  S k D+ C S > 3.6Bb `G l Bl k JBM+Bl l KK Bl k K+ D Bl rek 6J`H  QBl k MJQ+QBl l OO k QBl k O+ QBl 8+M`I  Zk QMR+ Z  6 Qk RQS+6 Q..< >< >< >.< >< >< > Body. fq % Body. frHQ  2Heading'H:..< >< >< >< =0>< >< >< > Body. fs %  Body-Indent.  ftNU %Description-ItemN:< =0>< >< =0> Description-C. %llfu %l Description-C Step Number. (fv` %Heading Chapter RuleBody. @w %. . XLeftFooter. @x %. . XRightFooter. @y %. . XChapterFooter. fzPd  In-line-interfaceIn-line-interface-type.  f{!NU  Description-ItemN:< =0>< >< =0> Description-C. ad f|Pd %In-line-interface-type Body-Indent.  f}Pd %z In-line-interface-type Body-Indent. f~HQ  Appendix!H:Appendix < >< =0>< =0>< => Appendix. Fof %Body. fP  !%.0.df;.03F.P.sc[.-emf.N:`fq.>=0,3|.cpt.ad̑..\f.(3....dXf.$3..%..-lTf.eac 3.(.o-I3.>.PfI.3T.^.i.t.Lf. Code-first Code-body. fU l REntry-head Step NumberRBody. f % Body-Indent. fPd   In-line-interfaceIn-line-interface-type. fPd % In-line-interface-type Body-Indent3. . f Callout. fN %CellBody-smallN:< =0>< >< =0>. f`  !%.0.df;.03F.P.[.f.`fq.%,3|..dy̑... \f.(3....Xf.$3.d...Tf. 3.-l(.eac3.>.ninPfI.-pe3T.^. i.t.Lf. Code-lastBody. f % CellHeading. fHQ  1Heading&H:.< >< >< >< =0>< >< >< >< > Body. f@d  !%.0.df;.03F.P.[.f.%`fq.0,3|.;.F̑.P.[\f.f(3.q.|..yXf.$3. ...Tf. 3.(.3.>.PfI.3T.^.i.l(t.c3Lf. Code-linefBody. f % Body-Next. fNA %ContentsN:< =0>< >< =0>Body. fP * Author1Heading. fD %RBodyRBody. f %Glossary-definition. fT % Glossary-entryGlossary-definition. fHQ * 1Heading H:. Body. f %Body. fHQ %Table Table RuleH:Table < >< >< >< > HTable. f % CellHeading. f@d   !%.0.df;.03F.P.[. f.`fq.,3|..̑.ynt.\f.a-d(3.o...Xf.$3....Tf. 3.(.3.>.gPfI.:+>3T.o^.i.t.Lf. Code-lineBody.  fHQ %Table Table RuleH:Table < >< >< >< > HTable. fN %CellBody-smallN:< =0>< >< =0>. f * Body. @ *  ActiveTOC. @  z GlossaryTOC. .6@ %? 1Heading-TopTOC.  @  z AppendixTOC.  @ % PrefaceTOC. @   z TitleTOC. ?f %? z  1HeadingTOC. Q6f %H  2HeadingTOC. lH@ * l . 3HeadingTOC.  @ * Level2IX. $@ * Level1IX. @ * SpecIX. @ *  SortSpecIX.  @ *  GroupTitlesIX. l@ * IndexIX. @ *  Paragraph. H * H . FigureLOF.  fHa %Figure Table RuleH:Figure < >< >< >< > @Body. fN %XIndexN:< =0>< >< =0>. H * H .TableLOT. f *  SeparatorsIX. f *  SortOrderIX. $f * Level3IX.  f * Level2IX. f * Level1IX. f    GroupTitlesIX. Taf * IndexIX. f *  Paragraph.  fB * . Bullet Bullet SymbolB:\t. @ * veH     h  BodyInterruptus. fHQ  1Heading&H:.< >< >< >< =0>< >< >< >< > Body. HfHA %Chapter-NumberH:< =0>< =0>< =0>< =>Chapter.  @D *  p    h  lablistlablist. fHQ  3Heading&H:..< >< >< >.< >< >< > Body. HH@  H    h  Example. fHQ  2Heading'H:..< >< >< >< =0>< >< >< > Body. (f` %Chapter Chapter RuleBody.  fNU %Description-ItemN:< =0>< >< =0> Description-C. fSE %.. .RStep-1<Bold S:.\tStep-ref. @    6 Q l  x l    ) D _ z   Code. f %RStep-C. @ * H    h  Body. @P * c. DefinitionBody. fS % . RStepBold S:.\t.  f * DefinitionBody. llf %l Description-C Step Number.  fHa %Figure Table RuleH:Figure < >< >< >< > Body. @ %P. RBullet\t. *f % RBullet-C. fPd  REntry REntry-type. fHQ * 3HeadingH:.. Body. Qf %Q. RDescription Step Number. f % Bodyright. @D * $    h  BodyBody. @ %P. . XLeftFooter. @ T  * HeadingBody. f   Body. @P * c. DefinitionBody. 3333 @ * DH    h  Comment. $$@  6.H.Z.l.~......LtF..... .2.D.V. h.z..*..ad..yExample. QQf %l RDescription-C Step Number. @ %. . XRightFooter. @D *  H n   h  BodyInterruptusBody.  fSE %. Step-1Bold S:.\tStep. .@ %. . mXChapterFooter. @    r i6 Qm l        ) D _ z   CodeSqueezed. @ *  H   n  h  BodyCont. rr fS % StepBold S:.\t. f %Step-C.  @D * H    h  BodyBody. m fNU %RDescription-ItemN:< =0>< >< =0>RDescription-Item. fPd  In-line-interfaceIn-line-interface-type. fHQ  1Heading&H:.< >< >< >< =0>< >< >< >< > Body. .\lf %l p Description Step Number. fHQ  3Heading&H:..< >< >< >.< >< >< > Body. BofHQ  2Heading'H:..< >< >< >< =0>< >< >< > sBody.  @ % lBullet\t. fPd %z Entry-type Entry-head. +>@ %.. XHeader. pf %Body. f % Body-Indent. (f` %Chapter Chapter RuleBody. fPd %In-line-interface-type Body-Indent.  @ % Bullet\t. f@d   ..df .03+.5.@.K.`fV. ,3a.k.v..\f.(3. .̬..Xf.$3....Tf. 3. ..ynd#. RCode-lineRBody. lf %lel y Description Step Number. f P  !-I%.0.df;.03F.P.[.f.`fq.,3|..̑.%.\f.(3.Bu... .Xf.$3....Tf.d 3.(.3.>.PfI. 3T.^. i.+t.5Lf. Code-body Code-body. fP   ..df .03+.5.@.yndK. `fV.i,3a.RBk. lv..\f.(3..̬..Xf.$3....Tf.eri 3. .Nbe.#. RCode-first RCode-body. fP  P .[.fdf .q03+.|5.@.K.`fV.,3a.k.uv.. \f.(3..̬..Xf.$3..(.3.>Tf.I 3.T .^.i#. RCode-body RCode-body. f %Bullet-C. f`   ..df .03+.5.@.K.`fV.,3a.k.v.eri.\f.Nbe(3.. ̬.it. Xf.o$3....Tf. 3. .. #. RCode-lastRBody. fP  !%.0.df;.03F.P.[.f.`fq.,3|..̑..\f. (3..#.od.Xf.Ce-$3. ...Tf. 3.(.3.>.PfI.3T.^.i.l-Ct.Lf. Code-first Code-body. fP  !.%..0..df;..03F..P..[..f..e`fq..,3|..N..̑....i\f..(3..o......Xf..$3........Tf.. 3.dla(.3.. >.PfI.3T.^.i.t.Lf. Code-body Code-body. f`  !%.0.df;. 03F.P.#[.odf.`fq.Ce-,3|. .̑..\f.(3....Xf.$3...l-C.Tf. 3.(.Co3.. >.PfI.3T.^.i.t.Lf. Code-lastBody. fU  .l Entry-head Step NumberRBody. . f'Pd  >z.Entry Entry-type. f0@d  !%.0. df;.03F.P.[.f.`fq.,3|. .̑.#.od\f.(3.Ce-. ..Xf.$3....Tf. 3.(.3.>.l-CPfI.3T. ^.i.Cot.. Lf. Code-lineBody. . f1Pd % REntry-type REntry-head. A: kv%   `) %  ܝ * kv   }  %Variable `) % `) %`) % f`   kv   # % Bold }  % }  % 3   Button. }  %ItalicT ܝ*  [    [       }  % kv   `) % `) % ܝ *  ܝ *  ) *  ) * ) *  [    |$ % Bold `)% % |$ % Bold 3  Callout oK %  Variable f`  Code `) % Fm_i  kv    }  %  3  Code #  %Italicv 3  % MethodType3  %XWhite)  *  >cy   %  Variable2%Variable kv   oK %  Variable f`    }  % }  % |$ %  >cy    f`!   [$    code in text } . %Emphasis |$3 %    @ lL  @ @   y @ @  Thin Mediumv Double Thick@  Very Thin     Am No row rules     EGJdRu Row rulesa q g %a Commentsb Doc-Statusc  Harlequin d Papere  Proposalf WWW -      %  U u n  U  V M W P X   Y Q Z y [   \  ]  ^ h _  `  2 a n b umvs c  v d o e Thk f   g n h  W i c j  k ٟ l  m 6   d owBlack!T WhiteddA Red dd Greendd JBluedCyand Magentaotsd atYellow W.Palatino.R.400Palatino-RomanW.Helvetica-Narrow.R.700Helvetica-Narrow-BoldW.Palatino.I.400Palatino-ItalicW.Courier.R.700 Courier-BoldW.Helvetica-Narrow.R.400Helvetica-NarrowW.Courier.R.400Courier W.Times.R.700 Times-BoldW.Palatino.R.700 Palatino-Bold W.Times.R.400 Times-Roman W.Helvetica.R.700 Helvetica-BoldW.Helvetica.R.400 HelveticaW.AvantGarde.R.700AvantGarde-Demi W.Palatino.I.700Palatino-BoldItalic 7 AvantGardeCourier Helvetica%Palatino*Times RegularNarrow RegularDemiBold BoldItalicRegularpI j8B$o-2"Ll~]kņ+"^$;zMctP^PT>@_iNk#Ծj =jn'AW\VFf͇hO/W*P1,Y/В J[MUgs!4;1nxŭVW@+(!Iy2|lҸDzwĚjm𚮁bwMnpva`OR)JSD4, yB/kᏳݏ߶}9{s7btrٸ{ lkƔPR *`|'b6 JA듄X('e3q*КHaTu? XM[TS/l8lJfecϾ[S}T"}ܥQeTFk)N 1QCdth4}_[k ¦i$XOD;!9 ijх0CCãC]#ioU;b_).l!uAX mKz+#D7 ,p#eW}ذ]P Û{%\)z)4ףptgU 6hڃij Cx@ OR01}ܠ12G{.NPYdCz4Tv2c$x<قlԵ[\Y\!\T ^aXC%hgJQeiᬄ_`MX>/BK &ޅl(%ߚAXv!`Z5%E~g1NSicf