index.html - clic - Clic is an command line interactive client for gopher written in Common LISP (HTM) git clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ (DIR) Log (DIR) Files (DIR) Refs (DIR) Tags (DIR) README (DIR) LICENSE --- index.html (62454B) --- 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 2 <html> 3 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 6 <title>FLEXI-STREAMS - Flexible bivalent streams for Common Lisp</title> 7 <style type="text/css"> 8 pre { padding:5px; background-color:#e0e0e0 } 9 h3, h4 { text-decoration: underline; } 10 a { text-decoration: none; padding: 1px 2px 1px 2px; } 11 a:visited { text-decoration: none; padding: 1px 2px 1px 2px; } 12 a:hover { text-decoration: none; padding: 1px 1px 1px 1px; border: 1px solid #000000; } 13 a:focus { text-decoration: none; padding: 1px 2px 1px 2px; border: none; } 14 a.none { text-decoration: none; padding: 0; } 15 a.none:visited { text-decoration: none; padding: 0; } 16 a.none:hover { text-decoration: none; border: none; padding: 0; } 17 a.none:focus { text-decoration: none; border: none; padding: 0; } 18 a.noborder { text-decoration: none; padding: 0; } 19 a.noborder:visited { text-decoration: none; padding: 0; } 20 a.noborder:hover { text-decoration: none; border: none; padding: 0; } 21 a.noborder:focus { text-decoration: none; border: none; padding: 0; } 22 </style> 23 </head> 24 25 <body bgcolor=white> 26 27 <h2>FLEXI-STREAMS - Flexible bivalent streams for Common Lisp</h2> 28 29 <blockquote> 30 <br> <br><h3><a name=abstract class=none>Abstract</a></h3> 31 32 FLEXI-STREAMS implements "virtual" bivalent streams that can be 33 layered atop real binary or bivalent streams and that can be used to 34 read and write character data in various single- or multi-octet 35 encodings which can be changed on the fly. It also supplies 36 <em>in-memory</em> binary streams which are similar to string streams. 37 <p> 38 The library needs a Common Lisp implementation that 39 supports <a 40 href="http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html"><em>Gray 41 streams</em></a> and relies on David 42 Lichteblau's <a 43 href="http://www.cliki.net/trivial-gray-streams">trivial-gray-streams</a> 44 to offer portability between different Lisps. 45 <p> 46 The code comes with 47 a <a 48 href="http://www.opensource.org/licenses/bsd-license.php">BSD-style 49 license</a> so you can basically do with it whatever you want. 50 51 <p> 52 <font color=red>Download shortcut:</font> <a 53 href="https://github.com/edicl/flexi-streams/releases/latest">https://github.com/edicl/flexi-streams/releases/latest</a> 54 </blockquote> 55 56 <br> <br><h3><a class=none name="contents">Contents</a></h3> 57 <ol> 58 <li><a href="#example">Example usage</a> 59 <li><a href="#install">Download and installation</a> 60 <li><a href="#support">Support</a> 61 <li><a href="#dictionary">The FLEXI-STREAMS dictionary</a> 62 <ol> 63 <li><a href="#external-formats">External formats</a> 64 <ol> 65 <li><a href="#make-external-format"><code>make-external-format</code></a> 66 <li><a href="#external-format-name"><code>external-format-name</code></a> 67 <li><a href="#external-format-eol-style"><code>external-format-eol-style</code></a> 68 <li><a href="#external-format-little-endian"><code>external-format-little-endian</code></a> 69 <li><a href="#external-format-id"><code>external-format-id</code></a> 70 <li><a href="#external-format-equal"><code>external-format-equal</code></a> 71 <li><a href="#*default-eol-style*"><code>*default-eol-style*</code></a> 72 <li><a href="#*default-little-endian*"><code>*default-little-endian*</code></a> 73 <li><a href="#external-format-condition"><code>external-format-condition</code></a> 74 <li><a href="#external-format-condition-external-format"><code>external-format-condition-external-format</code></a> 75 <li><a href="#external-format-error"><code>external-format-error</code></a> 76 <li><a href="#external-format-encoding-error"><code>external-format-encoding-error</code></a> 77 <li><a href="#*substitution-char*"><code>*substitution-char*</code></a> 78 <li><a href="#accept-overlong-sequence"><code>accept-overlong-sequence</code></a> 79 </ol> 80 <li><a href="#flexi-streams">Flexi streams</a> 81 <ol> 82 <li><a href="#flexi-stream"><code>flexi-stream</code></a> 83 <li><a href="#flexi-input-stream"><code>flexi-input-stream</code></a> 84 <li><a href="#flexi-output-stream"><code>flexi-output-stream</code></a> 85 <li><a href="#flexi-io-stream"><code>flexi-io-stream</code></a> 86 <li><a href="#make-flexi-stream"><code>make-flexi-stream</code></a> 87 <li><a href="#flexi-stream-external-format"><code>flexi-stream-external-format</code></a> 88 <li><a href="#flexi-stream-element-type"><code>flexi-stream-element-type</code></a> 89 <li><a href="#flexi-stream-column"><code>flexi-stream-column</code></a> 90 <li><a href="#flexi-stream-position"><code>flexi-stream-position</code></a> 91 <li><a href="#flexi-stream-bound"><code>flexi-stream-bound</code></a> 92 <li><a href="#flexi-stream-stream"><code>flexi-stream-stream</code></a> 93 <li><a href="#unread-byte"><code>unread-byte</code></a> 94 <li><a href="#peek-byte"><code>peek-byte</code></a> 95 <li><a href="#octet"><code>octet</code></a> 96 <li><a href="#flexi-stream-error"><code>flexi-stream-error</code></a> 97 <li><a href="#flexi-stream-out-of-sync-error"><code>flexi-stream-out-of-sync-error</code></a> 98 <li><a href="#flexi-stream-element-type-error"><code>flexi-stream-element-type-error</code></a> 99 <li><a href="#flexi-stream-element-type-error-element-type"><code>flexi-stream-element-type-error-element-type</code></a> 100 </ol> 101 <li><a href="#in-memory">In-memory streams</a> 102 <ol> 103 <li><a href="#in-memory-stream"><code>in-memory-stream</code></a> 104 <li><a href="#in-memory-input-stream"><code>in-memory-input-stream</code></a> 105 <li><a href="#in-memory-output-stream"><code>in-memory-output-stream</code></a> 106 <li><a href="#list-stream"><code>list-stream</code></a> 107 <li><a href="#vector-stream"><code>vector-stream</code></a> 108 <li><a href="#make-in-memory-input-stream"><code>make-in-memory-input-stream</code></a> 109 <li><a href="#make-in-memory-output-stream"><code>make-in-memory-output-stream</code></a> 110 <li><a href="#get-output-stream-sequence"><code>get-output-stream-sequence</code></a> 111 <li><a href="#output-stream-sequence-length"><code>output-stream-sequence-length</code></a> 112 <li><a href="#with-input-from-sequence"><code>with-input-from-sequence</code></a> 113 <li><a href="#with-output-to-sequence"><code>with-output-to-sequence</code></a> 114 <li><a href="#in-memory-stream-error"><code>in-memory-stream-error</code></a> 115 <li><a href="#in-memory-stream-closed-error"><code>in-memory-stream-closed-error</code></a> 116 <li><a href="#in-memory-stream-position-spec-error"><code>in-memory-stream-position-spec-error</code></a> 117 <li><a href="#in-memory-stream-position-spec-error-position-spec"><code>in-memory-stream-position-spec-error-position-spec</code></a> 118 </ol> 119 <li><a href="#strings">Strings</a> 120 <ol> 121 <li><a href="#string-to-octets"><code>string-to-octets</code></a> 122 <li><a href="#octets-to-string"><code>octets-to-string</code></a> 123 <li><a href="#octet-length"><code>octet-length</code></a> 124 <li><a href="#char-length"><code>char-length</code></a> 125 </ol> 126 </ol> 127 <li><a href="#position">File positions</a> 128 <li><a href="#ack">Acknowledgements</a> 129 </ol> 130 131 <br> <br><h3><a name="example" class=none>Example usage</a></h3> 132 133 The examples were created with <a href="http://www.lispworks.com/">LispWorks</a> 4.4.6 pro on Windows. The following two functions create <a href="foo.txt">the same file</a>: 134 135 <pre> 136 (defun foo (pathspec) 137 "With standard LispWorks streams." 138 (with-open-file (out pathspec 139 :direction :output 140 :if-exists :supersede 141 :external-format '(:utf-8 :eol-style :crlf)) 142 (write-line "ÄÖÜ1" out)) 143 (with-open-file (out pathspec 144 :direction :output 145 :if-exists :append 146 :external-format '(:latin-1 :eol-style :lf)) 147 (write-line "ÄÖÜ2" out)) 148 (with-open-file (out pathspec 149 :direction :output 150 :if-exists :append 151 :element-type 'octet) 152 (write-byte #xeb out) 153 (write-sequence #(#xa3 #xa4 #xa5) out)) 154 (with-open-file (out pathspec 155 :direction :output 156 :if-exists :append 157 :external-format '(:unicode :little-endian nil :eol-style :crlf)) 158 (write-line "ÄÖÜ3" out))) 159 160 (defun bar (pathspec) 161 "With a <a href="#flexi-streams" class=noborder>flexi stream</a>." 162 (with-open-file (out pathspec 163 :direction :output 164 :if-exists :supersede 165 :external-format '(:latin-1 :eol-style :lf)) 166 (setq out (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> out <a href="#external-formats" class=noborder>:external-format</a> :utf-8)) 167 (write-line "ÄÖÜ1" out) 168 (setf (<a href="#flexi-stream-external-format" class=noborder>flexi-stream-external-format</a> out) '(:latin-1 :eol-style :lf)) 169 (write-line "ÄÖÜ2" out) 170 (write-byte #xeb out) 171 (write-sequence #(#xa3 #xa4 #xa5) out) 172 (setf (flexi-stream-external-format out) :ucs-2be) 173 (write-line "ÄÖÜ3" out))) 174 </pre> 175 176 <p> 177 And applying this function 178 <pre> 179 (defun baz (pathspec) 180 (let (result) 181 (with-open-file (in pathspec :element-type '<a href="#octet" class=noborder>octet</a>) 182 (setq in (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in <a href="#external-formats" class=noborder>:external-format</a> :utf-8)) 183 (push (read-line in) result) 184 (push (read-byte in) result) 185 (setf (<a href="#flexi-stream-external-format" class=noborder>flexi-stream-external-format</a> in) '(:latin-1 :eol-style :lf)) 186 (push (read-line in) result) 187 (setf (flexi-stream-external-format in) :greek) 188 (push (read-char in) result) 189 (setf (flexi-stream-external-format in) :latin0) 190 (let ((string (make-string 3 :element-type 'character))) 191 (read-sequence string in) 192 (push string result)) 193 (let ((octets (make-array 2 :element-type 'octet))) 194 (read-sequence octets in) 195 (push octets result)) 196 (setf (flexi-stream-external-format in) :ucs-2be) 197 (push (read-line in) result)) 198 (nreverse result))) 199 </pre> 200 to the file created above will yield the list 201 <pre> 202 ("ÄÖÜ1" 196 "ÖÜ2" #\λ "£€¥" #(0 196) "ÖÜ3") 203 </pre> 204 205 <p> 206 For more examples see the source code 207 of 208 <a href="http://mr-co.de/projects/cl-rfc2047/">CL-RFC2047</a>, 209 <a 210 href="http://weitz.de/drakma/">Drakma</a>, <a 211 href="http://weitz.de/chunga/">Chunga</a>, 212 or <a href="http://weitz.de/cl-wbxml/">CL-WBXML</a>. 213 214 <br> <br><h3><a name="install" class=none>Download and installation</a></h3> 215 216 Before you try to install FLEXI-STREAMS, first check that in your Lisp 217 each <a 218 href="http://www.lispworks.com/documentation/HyperSpec/Body/13_.htm">character</a>'s 219 <a 220 href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#character_code">character 221 code</a> is equal to 222 its <a 223 href="http://en.wikipedia.org/wiki/Unicode">Unicode</a> <a 224 href="http://unicode.org/glossary/">code point</a> and 225 that <code>(CHAR-CODE #\Newline)</code> 226 and <code>(CHAR-CODE #\Linefeed)</code> have the same 227 value (10). (This is the case for all relevant CL 228 implementations which were in use when this library was written. It 229 is <em>not</em> mandated by the ANSI standard, though.) 230 <p> 231 FLEXI-STREAMS together with this documentation can be downloaded from <a 232 href="https://github.com/edicl/flexi-streams/releases/latest">https://github.com/edicl/flexi-streams/releases/latest</a>. 233 <p> 234 Before you install FLEXI-STREAMS you first need to 235 install the <a 236 href="http://www.cliki.net/trivial-gray-streams">trivial-gray-streams</a> library 237 unless you already have it. 238 <p> 239 FLEXI-STREAMS comes with a system definition for <a 240 href="http://www.cliki.net/asdf">ASDF</a> so you can install the library with 241 <pre> 242 (asdf:oos 'asdf:load-op :flexi-streams) 243 </pre> 244 if you've unpacked it in a place where ASDF can find it. Installation 245 via <a href="http://www.cliki.net/asdf-install">asdf-install</a> 246 should also be possible, and there's a port 247 to <a href="http://www.cliki.net/Gentoo">Gentoo Lisp</a> thanks to 248 Matthew Kennedy. 249 <p> 250 You can run a test suite which tests <em>some</em> (but 251 not <em>all</em>) aspects of the library with 252 <pre> 253 (asdf:oos 'asdf:test-op :flexi-streams) 254 </pre> 255 This might take a while... 256 <p> 257 The current development version of FLEXI-STREAMS can be found 258 at <a href="http://bknr.net/trac/browser/trunk/thirdparty">http://bknr.net/trac/browser/trunk/thirdparty</a>. 259 This is the one to send <a href="#mail">patches</a> against. Use at 260 your own risk. 261 <p> 262 Luís Oliveira maintains a <a href="http://darcs.net/">darcs</a> 263 repository of FLEXI-STREAMS 264 at <a href="http://common-lisp.net/%7Eloliveira/ediware/">http://common-lisp.net/~loliveira/ediware/</a>. 265 <p> 266 A <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> 267 repository of older versions is available 268 at <a 269 href="http://arcanes.fr.eu.org/~pierre/2007/02/weitz/">http://arcanes.fr.eu.org/~pierre/2007/02/weitz/</a> 270 thanks to Pierre Thierry. 271 272 <br> <br><h3><a name="support" class=none>Support</a></h3> 273 274 The development version of flexi-streams can be 275 found <a href="https://github.com/edicl/flexi-streams" target="_new">on 276 github</a>. Please use the github issue tracking system to submit bug 277 reports. Patches are welcome, please 278 use <a href="https://github.com/edicl/flexi-streams/pulls">GitHub pull 279 requests</a>. If you want to make a change, 280 please <a href="http://weitz.de/patches.html" target="_new">read this 281 first</a>. 282 283 <br> <br><h3><a class=none name="dictionary">The FLEXI-STREAMS dictionary</a></h3> 284 285 <h4><a name="external-formats" class=none>External formats</a></h4> 286 287 <code>EXTERNAL-FORMAT</code> objects are used to denote the external 288 formats of <a href="#flexi-streams">flexi streams</a>. These objects are created using 289 the <a 290 href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a> 291 function, and there are <a href="#external-format-name">various 292 readers</a> to query their attributes. Once such an object is 293 created it can't be changed. 294 <p> 295 An external format consists of a basic encoding 296 (like <a 297 href="http://en.wikipedia.org/wiki/Iso-8859-1">ISO 8859-1</a> 298 or <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>), a 299 definition how line endings are denoted - by a carriage return 300 character (ASCII 13), by a line feed character (ASCII 10), 301 or by both of these characters in a row -, and optionally (for 302 encodings that use units larger than 8 bits) information 303 about the <a href="http://en.wikipedia.org/wiki/Endian">endianess</a> 304 of the encoding. 305 <p> 306 The following encodings are currently supported by FLEXI-STREAMS: 307 <ul> 308 <li><a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> (denoted by the keyword <code>:UTF-8</code>), 309 <li><a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a> (denoted by the keyword <code>:UTF-16</code>), 310 <li><a href="http://en.wikipedia.org/wiki/UTF-32">UTF-32</a> (denoted by the keyword <code>:UTF-32</code>), 311 <li>all <a href="http://czyborra.com/charsets/iso8859.html">ISO 8859</a> character sets (denoted by keywords like <code>:ISO-8859-15</code>), 312 <li><a href="http://en.wikipedia.org/wiki/KOI8-R">KOI8-R</a> (denoted by the keyword <code>:KOI8-R</code>), 313 <li>a couple 314 of <a href="http://czyborra.com/charsets/codepages.html">Windows code 315 pages</a> (denoted by the keyword <code>:CODE-PAGE</code> and an 316 obligatory <code>:ID</code> argument), and 317 <li><a href="http://en.wikipedia.org/wiki/ASCII">US-ASCII</a>. 318 </ul> 319 <p> 320 A couple of alternative names are allowed that are listed below: 321 <p> 322 <table border=1> 323 <tr><td><code>:UTF-8</code></td><td><code>:UTF8</code></td></tr> 324 <tr><td rowspan=4 valign=top><code>:UTF-16</code></td><td><code>:UTF16</code></td></tr> 325 <tr><td><code>:UCS-2</code></td></tr> 326 <tr><td><code>:UCS2</code></td></tr> 327 <tr><td><code>:UNICODE</code></td></tr> 328 <tr><td rowspan=3 valign=top><code>:UTF-32</code></td><td><code>:UTF32</code></td></tr> 329 <tr><td><code>:UCS-4</code></td></tr> 330 <tr><td><code>:UCS4</code></td></tr> 331 <tr><td rowspan=2 valign=top><code>:ISO-8859-1</code></td><td><code>:LATIN-1</code></td></tr> 332 <tr><td><code>:LATIN1</code></td></tr> 333 <tr><td rowspan=2 valign=top><code>:ISO-8859-2</code></td><td><code>:LATIN-2</code></td></tr> 334 <tr><td><code>:LATIN2</code></td></tr> 335 <tr><td rowspan=2 valign=top><code>:ISO-8859-3</code></td><td><code>:LATIN-3</code></td></tr> 336 <tr><td><code>:LATIN3</code></td></tr> 337 <tr><td rowspan=2 valign=top><code>:ISO-8859-4</code></td><td><code>:LATIN-4</code></td></tr> 338 <tr><td><code>:LATIN4</code></td></tr> 339 <tr><td><code>:ISO-8859-5</code></td><td><code>:CYRILLIC</code></td></tr> 340 <tr><td><code>:ISO-8859-6</code></td><td><code>:ARABIC</code></td></tr> 341 <tr><td><code>:ISO-8859-7</code></td><td><code>:GREEK</code></td></tr> 342 <tr><td><code>:ISO-8859-8</code></td><td><code>:HEBREW</code></td></tr> 343 <tr><td rowspan=2 valign=top><code>:ISO-8859-9</code></td><td><code>:LATIN-5</code></td></tr> 344 <tr><td><code>:LATIN5</code></td></tr> 345 <tr><td rowspan=2 valign=top><code>:ISO-8859-10</code></td><td><code>:LATIN-6</code></td></tr> 346 <tr><td><code>:LATIN6</code></td></tr> 347 <tr><td><code>:ISO-8859-11</code></td><td><code>:THAI</code></td></tr> 348 <tr><td rowspan=2 valign=top><code>:ISO-8859-13</code></td><td><code>:LATIN-7</code></td></tr> 349 <tr><td><code>:LATIN7</code></td></tr> 350 <tr><td rowspan=2 valign=top><code>:ISO-8859-14</code></td><td><code>:LATIN-8</code></td></tr> 351 <tr><td><code>:LATIN8</code></td></tr> 352 <tr><td rowspan=4 valign=top><code>:ISO-8859-15</code></td><td><code>:LATIN-9</code></td></tr> 353 <tr><td><code>:LATIN9</code></td></tr> 354 <tr><td><code>:LATIN-0</code></td></tr> 355 <tr><td><code>:LATIN0</code></td></tr> 356 <tr><td rowspan=2 valign=top><code>:ISO-8859-16</code></td><td><code>:LATIN-10</code></td></tr> 357 <tr><td><code>:LATIN10</code></td></tr> 358 <tr><td rowspan=2 valign=top><code>:CODE-PAGE</code></td><td><code>:CODEPAGE</code></td></tr> 359 <tr><td><code>WIN32:CODE-PAGE<br>(only on <a href="http://www.lispworks.com/products/lww.html">LWW</a>)</code></td></tr> 360 <tr><td><code>:KOI8-R</code></td><td><code>:KOI8R</code></td></tr> 361 <tr><td><code>:US-ASCII</code></td><td><code>:ASCII</code></td></tr> 362 </table> 363 <p> 364 (Note that we treat UCS-2 exactly like UTF-16 although there 365 are <a href="http://en.wikipedia.org/wiki/UTF-16">subtle 366 differences</a>. Also note that even though we support encodings like 367 UTF-32 some Lisps only supports characters contained within 368 the <a 369 href="http://en.wikipedia.org/wiki/Basic_Multilingual_Plane">Basic 370 Multilingual Plane</a> (like LispWorks) or even less (like CMUCL), so 371 if other characters are read from a 372 <a href="#flexi-streams">flexi 373 stream</a>, <a 374 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_cha.htm"><code>READ-CHAR</code></a> 375 will try to be helpful and return the corresponding Unicode code point - 376 an integer - instead. This might lead to an error if you're using 377 functions 378 like <a 379 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_lin.htm"><code>READ-LINE</code></a>, though.) 380 381 <p> 382 Whenever a FLEXI-STREAMS function accepts an external format as one of 383 its arguments, you can provide either an <code>EXTERNAL-FORMAT</code> 384 object or a shortcut which can be a list or a symbol. The list 385 shortcuts have a syntax similar 386 to <a 387 href="http://www.lispworks.com/documentation/lw50/LWUG/html/lwuser-360.htm">the 388 one used by LispWorks</a> - the cars are the names of and encoding 389 and the cdrs of these lists correspond to the keyword arguments 390 to <a 391 href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>, so 392 for example 393 <pre>(:latin-1 :eol-style :crlf)</pre> 394 is equivalent to 395 <pre>(<a class=noborder href="#make-external-format">make-external-format</a> :latin-1 :eol-style :crlf)</pre> The 396 symbol shortcuts are equivalent to 397 calling <a 398 href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a> 399 without keyword arguments, i.e. 400 <pre>:thai</pre> 401 behaves like 402 <pre>(<a class=noborder href="#make-external-format">make-external-format</a> :thai)</pre> 403 Finally, the following expansions are 404 available: 405 <p> 406 <table border=1> 407 <tr><td><code>:UCS-2LE</code></td><td><code>(:UCS-2 :LITTLE-ENDIAN T)</code></td></tr> 408 <tr><td><code>:UCS-2BE</code></td><td><code>(:UCS-2 :LITTLE-ENDIAN NIL)</code></td></tr> 409 <tr><td><code>:UCS-4LE</code></td><td><code>(:UCS-4 :LITTLE-ENDIAN T)</code></td></tr> 410 <tr><td><code>:UCS-4BE</code></td><td><code>(:UCS-4 :LITTLE-ENDIAN NIL)</code></td></tr> 411 <tr><td><code>:UTF-16LE</code></td><td><code>(:UTF-16 :LITTLE-ENDIAN T)</code></td></tr> 412 <tr><td><code>:UTF-16BE</code></td><td><code>(:UTF-16 :LITTLE-ENDIAN NIL)</code></td></tr> 413 <tr><td><code>:UTF-32LE</code></td><td><code>(:UTF-32 :LITTLE-ENDIAN T)</code></td></tr> 414 <tr><td><code>:UTF-32BE</code></td><td><code>(:UTF-32 :LITTLE-ENDIAN NIL)</code></td></tr> 415 <tr><td><code>:IBM437</code></td><td><code>(:CODE-PAGE :ID 437)</code></td></tr> 416 <tr><td><code>:IBM850</code></td><td><code>(:CODE-PAGE :ID 850)</code></td></tr> 417 <tr><td><code>:IBM852</code></td><td><code>(:CODE-PAGE :ID 852)</code></td></tr> 418 <tr><td><code>:IBM855</code></td><td><code>(:CODE-PAGE :ID 855)</code></td></tr> 419 <tr><td><code>:IBM857</code></td><td><code>(:CODE-PAGE :ID 857)</code></td></tr> 420 <tr><td><code>:IBM860</code></td><td><code>(:CODE-PAGE :ID 860)</code></td></tr> 421 <tr><td><code>:IBM861</code></td><td><code>(:CODE-PAGE :ID 861)</code></td></tr> 422 <tr><td><code>:IBM862</code></td><td><code>(:CODE-PAGE :ID 862)</code></td></tr> 423 <tr><td><code>:IBM863</code></td><td><code>(:CODE-PAGE :ID 863)</code></td></tr> 424 <tr><td><code>:IBM864</code></td><td><code>(:CODE-PAGE :ID 864)</code></td></tr> 425 <tr><td><code>:IBM865</code></td><td><code>(:CODE-PAGE :ID 865)</code></td></tr> 426 <tr><td><code>:IBM866</code></td><td><code>(:CODE-PAGE :ID 866)</code></td></tr> 427 <tr><td><code>:IBM869</code></td><td><code>(:CODE-PAGE :ID 869)</code></td></tr> 428 <tr><td><code>:WINDOWS-1250</code></td><td><code>(:CODE-PAGE :ID 1250)</code></td></tr> 429 <tr><td><code>:WINDOWS-1251</code></td><td><code>(:CODE-PAGE :ID 1251)</code></td></tr> 430 <tr><td><code>:WINDOWS-1252</code></td><td><code>(:CODE-PAGE :ID 1252)</code></td></tr> 431 <tr><td><code>:WINDOWS-1253</code></td><td><code>(:CODE-PAGE :ID 1253)</code></td></tr> 432 <tr><td><code>:WINDOWS-1254</code></td><td><code>(:CODE-PAGE :ID 1254)</code></td></tr> 433 <tr><td><code>:WINDOWS-1255</code></td><td><code>(:CODE-PAGE :ID 1255)</code></td></tr> 434 <tr><td><code>:WINDOWS-1256</code></td><td><code>(:CODE-PAGE :ID 1256)</code></td></tr> 435 <tr><td><code>:WINDOWS-1257</code></td><td><code>(:CODE-PAGE :ID 1257)</code></td></tr> 436 <tr><td><code>:WINDOWS-1258</code></td><td><code>(:CODE-PAGE :ID 1258)</code></td></tr> 437 </table> 438 <p> 439 Note that if you provide a shortcut, it 440 will be converted to an <code>EXTERNAL-FORMAT</code> object first. 441 So, if you're concerned about efficiency, create these objects once and 442 re-use them. 443 444 <p><br>[Function] 445 <br><a class=none name="make-external-format"><b>make-external-format</b> <i>name <tt>&key</tt> eol-style little-endian id</i> => <i>external-format</i></a> 446 447 <blockquote><br> Creates and returns 448 an <a href="#external-formats"><code>EXTERNAL-FORMAT</code> 449 object</a>. <code><i>name</i></code> is a 450 symbol, <code><i>eol-style</i></code> is one of the 451 keywords <code>:CR</code>, <code>:LF</code>, or <code>:CRLF</code>, 452 and <code><i>little-endian</i></code> is 453 a <a 454 href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_g.htm#generalized_boolean">generalized 455 boolean</a>. The default value for <code><i>eol-style</i></code> is the value of <a href="#*default-eol-style*"><code>*DEFAULT-EOL-STYLE*</code></a> except for Windows code pages where it is <code>:CRLF</code>. The default value 456 for <code><i>little-endian</i></code> is the value of <a href="#*default-little-endian*"><code>*DEFAULT-LITTLE-ENDIAN*</code></a> - this value is ignored unless <code><i>name</i></code> denotes one of UTF-16 or UTF-32. 457 <code><i>id</i></code> must be an integer denoting a Windows code page 458 known by FLEXI-STREAMS if <code><i>name</i></code> 459 is <code>:CODE-PAGE</code> or <code>WIN32:CODE-PAGE</code>, otherwise 460 the value is ignored. See <a href="#external-formats">the section 461 about external formats</a> for more info. 462 <p> 463 Examples (run on Windows): 464 465 <pre> 466 CL-USER 1 > (make-external-format :latin-1) 467 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:ISO-8859-1 :EOL-STYLE :CRLF) 2067DA84> 468 469 CL-USER 2 > (make-external-format :latin-1 :eol-style :lf) 470 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:ISO-8859-1 :EOL-STYLE :LF) 2068B4D4> 471 472 CL-USER 3 > (make-external-format :ibm437) 473 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2069B33C> 474 475 CL-USER 4 > (make-external-format :ucs-2) 476 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 206B4F4C> 477 478 CL-USER 5 > (make-external-format :ucs-2be) 479 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :CRLF :LITTLE-ENDIAN NIL) 2067DBE4> 480 481 CL-USER 6 > (make-external-format :ucs-2be :eol-style :cr) 482 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :CR :LITTLE-ENDIAN NIL) 206B54AC> 483 </pre> 484 </blockquote> 485 486 <p><br>[Readers] 487 <br><a class=none name="external-format-name"><b>external-format-name</b> <i>external-format</i> => <i>name</i></a> 488 <br><a class=none name="external-format-eol-style"><b>external-format-eol-style</b> <i>external-format</i> => <i>eol-style</i></a> 489 <br><a class=none name="external-format-little-endian"><b>external-format-little-endian</b> <i>external-format</i> => <i>little-endian</i></a> 490 <br><a class=none name="external-format-id"><b>external-format-id</b> <i>external-format</i> => <i>id</i></a> 491 492 <blockquote><br> 493 These methods can be used to query an <a href="#external-formats"><code>EXTERNAL-FORMAT</code> object</a> for its attributes. 494 </blockquote> 495 496 <p><br>[Functions] 497 <br><a class=none name="external-format-equal"><b>external-format-equal</b> <i>external-format-1 external-format-2</i> => <i>generalized-boolean</i></a> 498 499 <blockquote><br> 500 Checks whether the two <a href="#external-formats">external formats</a> <code><i>external-format-1</i></code> and <code><i>external-format-2</i></code> are equivalent with respect to their effects on <a href="#flexi-streams">flexi streams</a>. 501 <p> 502 Examples (run on Windows): 503 504 <pre> 505 CL-USER 1 > (<a href="#make-external-format" class=noborder>make-external-format</a> :ucs-4le) 506 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-32 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 2067FB74> 507 508 CL-USER 2 > (external-format-equal <a href="http://www.lispworks.com/documentation/HyperSpec/Body/v__stst_.htm" class=noborder>*</a> (make-external-format :utf32 :little-endian t)) 509 T 510 511 CL-USER 3 > (make-external-format :code-page :id 437) 512 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2069428C> 513 514 CL-USER 4 > (external-format-equal * (make-external-format :ibm437)) 515 T 516 </pre> 517 518 </blockquote> 519 520 <p><br>[Special variable] 521 <br><a class=none name="*default-eol-style*"><b>*default-eol-style*</b></a> 522 523 <blockquote><br> 524 The default value for the <code><i>eol-style</i></code> keyword argument of <a href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>. Its initial value is <code>:CRLF</code> on Windows and <code>:LF</code> on other operating systems. 525 </blockquote> 526 527 <p><br>[Special variable] 528 <br><a class=none name="*default-little-endian*"><b>*default-little-endian*</b></a> 529 530 <blockquote><br> 531 The default value for the <code><i>little-endian</i></code> keyword argument of <a href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>. Its initial value corresponds to the endianess of the platform FLEXI-STREAMS is used on as revealed by the <code>:LITTLE-ENDIAN</code> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/24_ab.htm">feature</a>. 532 </blockquote> 533 534 <p><br>[Condition] 535 <br><a class=none name="external-format-condition"><b>external-format-condition</b></a> 536 537 <blockquote><br> 538 All conditions related to <a href="#external-formats">external formats</a> are of this type. 539 There's a slot for the external format which can be accessed with <a href="#external-format-condition-external-format"><code>EXTERNAL-FORMAT-CONDITION-EXTERNAL-FORMAT</code></a>. 540 </blockquote> 541 542 <p><br>[Reader] 543 <br><a class=none name="external-format-condition-external-format"><b>external-format-condition-external-format</b> <i>condition</i> => <i>external-format</i></a> 544 545 <blockquote><br> If <code><i>condition</i></code> is of 546 type <a href="#external-format-condition"><code>EXTERNAL-FORMAT-CONDITION</code></a>, 547 this function will return the associated external format. Note that 548 there are situation which happen during the creation of external 549 formats where this method returns <code>NIL</code>. 550 </blockquote> 551 552 <p><br>[Condition] 553 <br><a class=none name="external-format-error"><b>external-format-error</b></a> 554 555 <blockquote><br> 556 All errors related to <a href="#external-formats">external formats</a> are of this type. 557 This is a subtype of <a href="#external-format-condition"><code>EXTERNAL-FORMAT-CONDITION</code></a>. 558 </blockquote> 559 560 <p><br>[Condition] 561 <br><a class=none name="external-format-encoding-error"><b>external-format-encoding-error</b></a> 562 563 <blockquote><br> 564 All errors related to encoding problems with <a href="#external-formats">external formats</a> are of this type. (This includes situation where an end of file is encountered in the middle of a multi-octet character.) When this condition is signalled during reading, <a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm"><code>USE-VALUE</code> 565 restart</a> is provided. See also <a href="#*substitution-char*"><code>*SUBSTITUTION-CHAR*</code></a> and the example for it. <a href="#external-format-encoding-error"><code>EXTERNAL-FORMAT-ENCODING-ERROR</code></a> is a subtype of <a href="#external-format-error"><code>EXTERNAL-FORMAT-ERROR</code></a>. 566 </blockquote> 567 568 <p><br>[Special variable] 569 <br><a class=none name="*substitution-char*"><b>*substitution-char*</b></a> 570 571 <blockquote><br> 572 If this value is not NIL, it should be a character which is used 573 (as if by a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm"><code>USE-VALUE</code> restart</a>) whenever during reading an error of 574 type <a href="#external-format-encoding-error"><code>EXTERNAL-FORMAT-ENCODING-ERROR</code></a> would have been signalled otherwise. 575 576 <pre> 577 CL-USER 1 > (defun foo () 578 <font color=orange>;; not a valid UTF-8 sequence</font> 579 (<a href="#with-input-from-sequence" class=noborder>with-input-from-sequence</a> (in '(#xe4 #xf6 #xfc)) 580 (setq in (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in :external-format :utf8)) 581 (read-line in))) 582 FOO 583 584 CL-USER 2 > (foo) 585 586 Error: Unexpected value #xF6 in UTF-8 sequence. 587 1 (continue) Specify a character to be used instead. 588 2 (abort) Return to level 0. 589 3 Return to top loop level 0. 590 591 Type :b for backtrace, :c <option number> to proceed, or :? for other options 592 593 CL-USER 3 : 1 > :c 594 Type a character: x 595 596 Error: End of file while in UTF-8 sequence. 597 1 (continue) Specify a character to be used instead. 598 2 (abort) Return to level 0. 599 3 Return to top loop level 0. 600 601 Type :b for backtrace, :c <option number> to proceed, or :? for other options 602 603 CL-USER 4 : 1 > :c 604 Type a character: y 605 "xy" 606 T 607 608 CL-USER 5 > (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_handle.htm" class=noborder>handler-bind</a> ((<a href="#external-format-encoding-error" class=noborder>external-format-encoding-error</a> (lambda (condition) 609 (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm" class=noborder>use-value</a> #\-)))) 610 (foo)) 611 "--" 612 T 613 614 CL-USER 6 > (let ((<a href="#*SUBSTITUTION-CHAR*" class=noborder>*substitution-char*</a> #\?)) 615 (foo)) 616 "??" 617 T 618 </pre> 619 </blockquote> 620 621 <p><br>[Restart] 622 <br><a class=none name="accept-overlong-sequence"><b>accept-overlong-sequence</b></a> 623 624 <blockquote><br> This is 625 a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/09_adb.htm">restart</a> 626 which is established whenever a UTF-8 "overlong" sequence is 627 encountered. If 628 you <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_invo_1.htm">invoke</a> 629 this restart, the corresponding code point will be accepted although 630 it was encoded in an illegal way. 631 </blockquote> 632 633 <h4><a name="flexi-streams" class=none>Flexi streams</a></h4> 634 635 <em>Flexi streams</em> are the core of the FLEXI-STREAMS library. You 636 create them using the 637 function <a 638 href="#make-flexi-stream"><code>MAKE-FLEXI-STREAM</code></a> which 639 takes an open binary stream (called the <em>underlying</em> stream) as its only required argument. 640 A <em>binary</em> stream in this context means that if it's an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#input">input 641 stream</a>, you can read from it with 642 <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_by.htm"><code>READ-BYTE</code></a> 643 (or, as a workaround for LispWorks, you can at least apply 644 <a 645 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_seq.htm"><code>READ-SEQUENCE</code></a> 646 to it where the sequence is an array of element 647 type <a href="#octet"><code>OCTET</code></a>), and similarly for 648 <a 649 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_by.htm#write-byte"><code>WRITE-BYTE</code></a> 650 (<a 651 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_seq.htm"><code>WRITE-SEQUENCE</code></a> 652 for LispWorks) 653 and <a 654 href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#output">output 655 streams</a>. (Note that this specifically holds 656 for <a 657 href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-91.htm"><em>bivalent</em> 658 streams</a> like socket streams.) 659 <p> 660 A flexi stream behaves like an ordinary Lisp stream. It is an input 661 stream if the underlying binary stream is an input stream, and it is 662 an output stream when the underlying binary stream is an output 663 stream. You can write characters as well 664 as <a href="#octet">octets</a> to an output flexi stream and similarly 665 you can read characters and octets from an input flexi stream. 666 <p> 667 A flexi stream always has an <a href="#external-formats">external 668 format</a> associated with it which is deployed whenever you read 669 characters from the stream or write characters to it. You 670 can <a href="#flexi-stream-external-format">change</a> the external 671 format while you use the stream. 672 <p> 673 Once you're using a flexi stream you should <em>not</em> read from or 674 write to the underlying stream directly anymore. 675 <p> 676 If 677 you <a 678 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_close.htm">close</a> 679 a flexi stream, the underlying stream will also be closed. However, it 680 also suffices to close the underlying stream directly should you not 681 want to use the flexi stream anymore. So, the following usage 682 (where <code>IN</code> is implicitly closed at the end) is OK: 683 <pre> 684 (with-open-file (in "/foo/bar/baz.txt") 685 (let ((flexi (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in <a href="#external-formats" class=noborder>:external-format</a> :hebrew))) 686 (read-line flexi))) 687 </pre> 688 <p> 689 Output flexi streams will try to keep track of 690 the <a 691 href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-591.htm">column</a> 692 they're in but you can also <a href="#flexi-stream-column">set</a> the 693 column directly. This value will be incremented by one for each 694 character written to the stream and it will be set to <code>0</code> 695 if you send a <code>#\Newline</code> character. The column will be 696 set to <code>NIL</code> if an <a href="#octet"><code>OCTET</code></a> 697 is sent to the stream. Once the column is <code>NIL</code> it'll stay 698 like that unless it is explicitly set to another value. 699 <p> 700 Input flexi streams keep track of 701 their <a href="#flexi-stream-position">position</a> within the stream. 702 This value is incremented by one for 703 each <a href="#octet"><code>OCTET</code></a> read from the stream, and 704 it is incremented by the number of octets actually read for each 705 character read from the stream. So, if the encoding is UTF-8, reading 706 the character <code>#\ä</code> (a-umlaut) will advance the position by two. 707 If the encoding is UTF-32 and the end-of-line style 708 is <code>:CRLF</code>, reading a <code>#\Newline</code> will advance 709 the position by eight. 710 <p> 711 You can also set the <a href="#flexi-stream-bound">bound</a> of an 712 input flexi stream. Initially it is <code>NIL</code>, but when it's 713 an integer and the 714 stream's <a href="#flexi-stream-position">position</a> has gone beyond 715 this bound, the stream will behave as if no more input is available. 716 <p> 717 Caveat: You can 718 only <a 719 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_unrd_c.htm">unread</a> 720 a character from a flexi stream if you haven't changed the external format after you read it. 721 <p> 722 Caveat: The <em>underlying</em> stream should either be a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary stream</a> (i.e. have an element type that is a subtype of integer) or it should explicitly use an <a href="http://www.lispworks.com/documentation/lw50/LWUG/html/lwuser-360.htm">external format</a> with <code>:LF</code> as its end-of-line style. Otherwise it might perform unwanted conversion of line endings on its own. (LispWorks <a href="http://article.gmane.org/gmane.lisp.lispworks.general/4859">does this</a> even if you write binary data to the stream using <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_seq.htm"><code>WRITE-SEQUENCE</code></a>.) 723 724 <p><br>[Standard class] 725 <br><a class=none name="flexi-stream"><b>flexi-stream</b></a> 726 727 <blockquote><br> 728 Every <a href="#flexi-streams"><em>flexi stream</em></a> returned by <a href="#make-flexi-stream"><code>MAKE-FLEXI-STREAM</code></a> is of this type which is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stream.htm"><code>STREAM</code></a>. 729 </blockquote> 730 731 <p><br>[Standard class] 732 <br><a class=none name="flexi-input-stream"><b>flexi-input-stream</b></a> 733 734 <blockquote><br> 735 A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if its underlying stream is an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_in_stm.htm">input stream</a>. This is a subtype of <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>. 736 </blockquote> 737 738 <p><br>[Standard class] 739 <br><a class=none name="flexi-output-stream"><b>flexi-output-stream</b></a> 740 741 <blockquote><br> 742 A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if its underlying stream is an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_in_stm.htm">output stream</a>. This is a subtype of <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>. 743 </blockquote> 744 745 <p><br>[Standard class] 746 <br><a class=none name="flexi-io-stream"><b>flexi-io-stream</b></a> 747 748 <blockquote><br> 749 A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if it is both a <a href="#flexi-input-stream"><code>FLEXI-INPUT-STREAM</code></a> as well as a <a href="#flexi-output-stream"><code>FLEXI-OUTPUT-STREAM</code></a>. 750 </blockquote> 751 752 <p><br>[Function] 753 <br><a class=none name="make-flexi-stream"><b>make-flexi-stream</b> <i>stream <tt>&key</tt> external-format element-type column position bound</i> => <i>flexi-stream</i></a> 754 755 <blockquote><br> 756 Creates and returns a <a href="#flexi-streams"><em>flexi stream</em></a>, i.e. an object of type <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>. <code><i>stream</i></code> is the underlying Lisp stream. <code><i>external-format</i></code> is the initial <a href="#external-formats">external format</a> to be used by the stream, the default is the value of evaluating <code>(<a href="#make-external-format">MAKE-EXTERNAL-FORMAT</a> :LATIN1)</code>. <code><i>element-type</i></code> is the initial <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stm_el.htm">element type</a> of the flexi stream the default of which is <a href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-346.htm"><code>LW:SIMPLE-CHAR</code></a> for LispWorks and <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_ch.htm"><code>CHARACTER</code></a> otherwise. <code><i>column</i></code> is the initial column of the stream and should only be provided for output streams, the default is <code>0</code>. <code><i>position</i></code> is the initial octet position of the stream and must only be provided for input streams, the default is <code>0</code>. <code><i>bound</i></code> should be <code>NIL</code> (the default) or an integer and must only be provided for input streams. If the octet position of the stream has gone beyond this bound, the stream will behave as if no more input is available. See <a href="#flexi-streams">the section about flexi streams</a> for more information. 757 </blockquote> 758 759 <p><br>[Accessors] 760 <br><a class=none name="flexi-stream-external-format"><b>flexi-stream-external-format</b> <i>flexi-stream</i> => <i>external-format</i></a> 761 <br><tt>(setf (</tt><b>flexi-stream-external-format</b> <i>flexi-stream</i>) <i>external-format</i><tt>)</tt> 762 <br><a class=none name="flexi-stream-element-type"><b>flexi-stream-element-type</b> <i>flexi-stream</i> => <i>element-type</i></a> 763 <br><tt>(setf (</tt><b>flexi-stream-element-type</b> <i>flexi-stream</i>) <i>element-type</i><tt>)</tt> 764 <br><a class=none name="flexi-stream-column"><b>flexi-stream-column</b> <i>flexi-output-stream</i> => <i>column</i></a> 765 <br><tt>(setf (</tt><b>flexi-stream-column</b> <i>flexi-output-stream</i>) <i>column</i><tt>)</tt> 766 <br><a class=none name="flexi-stream-position"><b>flexi-stream-position</b> <i>flexi-input-stream</i> => <i>position</i></a> 767 <br><tt>(setf (</tt><b>flexi-stream-position</b> <i>flexi-input-stream</i>) <i>position</i><tt>)</tt> 768 <br><a class=none name="flexi-stream-bound"><b>flexi-stream-bound</b> <i>flexi-input-stream</i> => <i>bound</i></a> 769 <br><tt>(setf (</tt><b>flexi-stream-bound</b> <i>flexi-input-stream</i>) <i>bound</i><tt>)</tt> 770 771 <blockquote><br> 772 These methods can be used to get and set the corresponding attributes of a <a href="#flexi-streams">flexi stream</a>. 773 <p> 774 <a href="#flexi-stream-external-format"><code>(SETF 775 FLEXI-STREAM-EXTERNAL-FORMAT)</code></a> accepts keyword symbols 776 (<a href="#external-formats">names of external formats</a>), lists 777 (which should be valid lists of parameters 778 to <a 779 href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>), or <code>EXTERNAL-FORMAT</code> objects: 780 <pre> 781 CL-USER 1 > (setf (flexi-stream-external-format *my-stream*) :ucs-4le) 782 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-32 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 206920DC> 783 784 CL-USER 2 > (setf (flexi-stream-external-format *my-stream*) '(:ucs-2be :eol-style :br)) 785 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :BR :LITTLE-ENDIAN NIL) 20696934> 786 787 CL-USER 3 > (setf (flexi-stream-external-format *my-stream*) (make-external-format :ibm437)) 788 #<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2068716C> 789 </pre> 790 </blockquote> 791 792 <p><br>[Reader] 793 <br><a class=none name="flexi-stream-stream"><b>flexi-stream-stream</b> <i>flexi-stream</i> => <i>stream</i></a> 794 795 <blockquote><br> 796 This method returns the underlying stream of a <a href="#flexi-streams">flexi stream</a>. 797 </blockquote> 798 799 <p><br>[Generic function] 800 <br><a class=none name="unread-byte"><b>unread-byte</b> <i>byte stream</i> => <i>nil</i></a> 801 802 <blockquote><br> 803 Similar to <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_unrd_c.htm"><code>UNREAD-CHAR</code></a> in that it "unreads" the last <a href="#octet">octet</a> from 804 <code><i>stream</i></code> which must be a <a href="#flexi-streams">flexi stream</a>. Note that you can only call <code>UNREAD-BYTE</code> after a corresponding 805 <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_by.htm"><code>READ-BYTE</code></a>, <em>not</em> after <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_cha.htm"><code>READ-CHAR</code></a>. 806 </blockquote> 807 808 <p><br>[Generic function] 809 <br><a class=none name="peek-byte"><b>peek-byte</b> <i>stream <tt>&optional</tt> peek-type eof-error-p eof-value</i> => <i>byte</i></a> 810 811 <blockquote><br> 812 <code>PEEK-BYTE</code> is like <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_peek_c.htm"><code>PEEK-CHAR</code></a>, i.e. it returns an <a href="#octet">octet</a> from <code><i>stream</i></code> (which must be a <a href="#flexi-streams">flexi stream</a>) 813 without actually removing it. If <code><i>peek-type</i></code> is <code>NIL</code>, the next octet is 814 returned, if <code><i>peek-type</i></code> is <code>T</code>, the next octet which is not <code>0</code> is 815 returned, if <code><i>peek-type</i></code> is an octet, the next octet which equals 816 <code><i>peek-type</i></code> is returned. <code><i>eof-error-p</i></code> and <code><i>eof-value</i></code> are interpreted as usual. 817 <p> 818 Note that the parameters aren't in the same order as with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_peek_c.htm"><code>PEEK-CHAR</code></a> because it doesn't make much sense to make <code><i>stream</i></code> an optional argument. 819 </blockquote> 820 821 <p><br>[Type] 822 <br><a class=none name="octet"><b>octet</b></a> 823 824 <blockquote><br> 825 Just a shortcut for <code>(UNSIGNED-BYTE 8)</code>. 826 </blockquote> 827 828 <p><br>[Condition] 829 <br><a class=none name="flexi-stream-error"><b>flexi-stream-error</b></a> 830 831 <blockquote><br> 832 All errors related to <a href="#flexi-streams">flexi streams</a> are of this type. This is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/e_stm_er.htm"><code>STREAM-ERROR</code></a>. 833 </blockquote> 834 835 <p><br>[Condition] 836 <br><a class=none name="flexi-stream-out-of-sync-error"><b>flexi-stream-out-of-sync-error</b></a> 837 838 <blockquote><br> This can happen if you're trying to write to 839 an <a href="#flexi-io-stream">IO stream</a> which had prior to that 840 "looked ahead" while reading and now can't "rewind" to the octet where 841 you <em>should</em> be. 842 </blockquote> 843 844 <p><br>[Condition] 845 <br><a class=none name="flexi-stream-element-type-error"><b>flexi-stream-element-type-error</b></a> 846 847 <blockquote><br> 848 All errors related to problems with the element type of <a href="#flexi-streams">flexi streams</a> are of this type. This is a subtype of <a href="#flexi-stream-error"><code>FLEXI-STREAM-ERROR</code></a> and has an additional slot for the element type which can be accessed with <a href="#flexi-stream-element-type-error-element-type"><code>FLEXI-STREAM-ELEMENT-TYPE-ERROR-ELEMENT-TYPE</code></a>. 849 </blockquote> 850 851 <p><br>[Reader] 852 <br><a class=none name="flexi-stream-element-type-error-element-type"><b>flexi-stream-element-type-error-element-type</b> <i>condition</i> => <i>element-type</i></a> 853 854 <blockquote><br> 855 If <code><i>condition</i></code> is of type <a href="#flexi-stream-element-type-error"><code>FLEXI-STREAM-ELEMENT-TYPE-ERROR</code></a>, this function will return the offending element type. 856 </blockquote> 857 858 <h4><a name="in-memory" class=none>In-memory streams</a></h4> 859 860 The library also provides <em>in-memory</em> binary streams which are modeled after <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stg_st.htm">string streams</a> and behave very similar only that they deal with <a href="#octet">octets</a> instead of characters and the underlying data structure is not a string but either a list or a vector. These streams can obviously be used as the underlying streams for <a href="#flexi-streams">flexi streams</a>. 861 862 <p><br>[Standard class] 863 <br><a class=none name="in-memory-stream"><b>in-memory-stream</b></a> 864 865 <blockquote><br> 866 Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a> or <a href="#make-in-memory-output-stream"><code>MAKE-IN-MEMORY-OUTPUT-STREAM</code></a> is of this type which is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stream.htm"><code>STREAM</code></a>. 867 </blockquote> 868 869 <p><br>[Standard class] 870 <br><a class=none name="in-memory-input-stream"><b>in-memory-input-stream</b></a> 871 872 <blockquote><br> 873 Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a> is of this type which is a subtype of <a href="#in-memory-stream"><code>IN-MEMORY-STREAM</code></a>. 874 </blockquote> 875 876 <p><br>[Standard class] 877 <br><a class=none name="in-memory-output-stream"><b>in-memory-output-stream</b></a> 878 879 <blockquote><br> 880 Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-output-stream"><code>MAKE-IN-MEMORY-OUTPUT-STREAM</code></a> is of this type which is a subtype of <a href="#in-memory-stream"><code>IN-MEMORY-STREAM</code></a>. 881 </blockquote> 882 883 <p><br>[Standard class] 884 <br><a class=none name="list-stream"><b>list-stream</b></a> 885 886 <blockquote><br> 887 Every <a href="#in-memory"><em>in-memory input stream</em></a> is of this type if it reads from a list. 888 </blockquote> 889 890 <p><br>[Standard class] 891 <br><a class=none name="vector-stream"><b>vector-stream</b></a> 892 893 <blockquote><br> 894 Every <a href="#in-memory"><em>in-memory stream</em></a> is of this type if it reads from or writes to a vector. 895 </blockquote> 896 897 <p><br>[Generic function] 898 <br><a class=none name="make-in-memory-input-stream"><b>make-in-memory-input-stream</b> <i>sequence <tt>&key</tt> start end transformer</i> => <i>in-memory-input-stream</i></a> 899 900 <blockquote><br> 901 Returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary</a> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#input">input</a> stream (of type <a href="#in-memory-input-stream"><code>IN-MEMORY-INPUT-STREAM</code></a>) which will supply, in order, the 902 octets in the subsequence of <code><i>sequence</i></code> bounded by <code><i>start</i></code> (the default is <code>0</code>) and <code><i>end</i></code> (the default is the length of <code><i>sequence</i></code>). <code><i>sequence</i></code> must either be a list or a vector of <a href="#octet">octets</a>. 903 Each octet returned will be transformed in turn by the optional 904 <code><i>transformer</i></code> function. 905 </blockquote> 906 907 <p><br>[Function] 908 <br><a class=none name="make-in-memory-output-stream"><b>make-in-memory-output-stream</b> <i><tt>&key</tt> element-type transformer</i> => <i>in-memory-output-stream</i></a> 909 910 <blockquote><br> 911 Returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary</a> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#output">output</a> stream (of type <a href="#in-memory-output-stream"><code>IN-MEMORY-OUTPUT-STREAM</code></a>) which accepts objects of type <code><i>element-type</i></code> (a subtype of <a href="#octet"><code>OCTET</code></a>) and makes 912 available a sequence (see <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a>) that contains the octets that were actually 913 output. The octets stored will each be transformed by the optional <code><i>transformer</i></code> function. 914 </blockquote> 915 916 <p><br>[Generic function] 917 <br><a class=none name="get-output-stream-sequence"><b>get-output-stream-sequence</b> <i>stream <tt>&key</tt> as-list</i> => <i>sequence</i></a> 918 919 <blockquote><br> 920 Returns a vector containing, in order, all the octets that have 921 been output to the <a href="#in-memory">in-memory output stream</a> <code><i>stream</i></code>. This operation clears any 922 octets on <code><i>stream</i></code>, so the vector contains only those octets which have 923 been output since the last call to <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a> or since 924 the creation of the stream, whichever occurred most recently. If 925 <code><i>as-list</i></code> is true the return value is coerced to a list. 926 </blockquote> 927 928 <p><br>[Generic function] 929 <br><a class=none name="output-stream-sequence-length"><b>output-stream-sequence-length</b> <i>stream</i> => <i>length</i></a> 930 931 <blockquote><br> Returns the current length of the underlying vector 932 of the <a href="#in-memory">in-memory output 933 stream</a> <code><i>stream</i></code>, i.e. this is the length of the 934 sequence that <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a> would return if called at 935 this very moment. 936 </blockquote> 937 938 <p><br>[Macro] 939 <br><a class=none name="with-input-from-sequence"><b>with-input-from-sequence</b> <i>(var sequence <tt>&key</tt> start end transformer) statement*</i> => <i>result*</i></a> 940 941 <blockquote><br> Creates an <a href="#in-memory">in-memory input 942 stream</a> from the sequence <code><i>sequence</i></code> using the 943 parameters <code><i>start</i></code> and <code><i>end</i></code> 944 (see <a 945 href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a>), 946 binds <code><i>var</i></code> to this stream and then executes 947 the <code><i>statement*</i></code> forms. A 948 function <code><i>transformer</i></code> may optionally be specified 949 to transform the returned octets. The stream is automatically closed 950 on exit from 951 <a href="#with-output-to-sequence"><code>WITH-OUTPUT-TO-SEQUENCE</code></a>, no matter whether the exit is normal or 952 abnormal. The return value of this macro is the return value of 953 the last statement of <code><i>statement*</i></code>. 954 </blockquote> 955 956 <p><br>[Macro] 957 <br><a class=none name="with-output-to-sequence"><b>with-output-to-sequence</b> <i>(var <tt>&key</tt> as-list element-type transformer) statement*</i> => <i>sequence</i></a> 958 959 <blockquote><br> 960 Creates an <a href="#in-memory">in-memory output stream</a>, binds <code><i>var</i></code> to this stream and 961 then executes the <code><i>statement*</i></code> forms. The stream stores 962 data of type <code><i>element-type</i></code> (a subtype of <a href="#octet"><code>OCTET</code></a>) which is (optionally) transformed by the 963 function <code><i>transformer</i></code> prior to storage. The stream is automatically closed on 964 exit from <a href="#with-output-to-sequence"><code>WITH-OUTPUT-TO-SEQUENCE</code></a>, no matter whether the exit is 965 normal or abnormal. The return value of this macro is a vector (or a 966 list if <code><i>as-list</i></code> is true) containing the octets that were sent to the 967 stream within the body of the macro. 968 </blockquote> 969 970 <p><br>[Condition] 971 <br><a class=none name="in-memory-stream-error"><b>in-memory-stream-error</b></a> 972 973 <blockquote><br> 974 All errors related to <a href="#in-memory">in-memory streams</a> are of this type. This is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/e_stm_er.htm"><code>STREAM-ERROR</code></a>. 975 </blockquote> 976 977 <p><br>[Condition] 978 <br><a class=none name="in-memory-stream-closed-error"><b>in-memory-stream-closed-error</b></a> 979 980 <blockquote><br> 981 An error of this type is signalled if one tries to read from or write to an <a href="#in-memory">in-memory stream</a> which had already been closed. This is a subtype of <a href="#in-memory-stream-error"><code>IN-MEMORY-STREAM-ERROR</code></a>. 982 </blockquote> 983 984 <p><br>[Condition] 985 <br><a class=none name="in-memory-stream-position-spec-error"><b>in-memory-stream-position-spec-error</b></a> 986 987 <blockquote><br> Errors of this type are signalled if an erroneous 988 position spec is used in conjunction 989 with <a href="#position"><code>FILE-POSITION</code></a>. This is a 990 subtype 991 of <a href="#in-memory-stream-error"><code>IN-MEMORY-STREAM-ERROR</code></a> 992 and has an additional slot for the position spec which can be accessed 993 with <a href="#in-memory-stream-position-spec-error-position-spec"><code>IN-MEMORY-STREAM-POSITION-SPEC-ERROR-POSITION-SPEC</code></a>. 994 </blockquote> 995 996 <p><br>[Reader] 997 <br><a class=none name="in-memory-stream-position-spec-error-position-spec"><b>in-memory-stream-position-spec-error-position-spec</b> <i>condition</i> => <i>position-spec</i></a> 998 999 <blockquote><br> 1000 If <code><i>condition</i></code> is of type <a href="#in-memory-stream-position-spec-error"><code>IN-MEMORY-STREAM-POSITION-SPEC-ERROR</code></a>, this function will return the offending position spec. 1001 </blockquote> 1002 1003 <h4><a name="strings" class=none>Strings</a></h4> 1004 1005 This section collects a few convenience functions for strings conversions. 1006 1007 <p><br>[Function] 1008 <br><a class=none name="string-to-octets"><b>string-to-octets</b> <i>string <tt>&key</tt> external-format start end</i> => <i>vector</i></a> 1009 1010 <blockquote><br> 1011 1012 Converts the Lisp string <code><i>string</i></code> from <code><i>start</i></code> to <code><i>end</i></code> to an array of 1013 <a href="#octet">octets</a> corresponding to the <a href="#external-formats">external 1014 format</a> designated by <code><i>external-format</i></code>. The defaults for 1015 <code><i>start</i></code> and <code><i>end</i></code> 1016 are <code>0</code> and the length of the string. The default 1017 for <code><i>external-format</i></code> is <code>:LATIN1</code>. 1018 <p> 1019 In spite of the name, <code><i>string</i></code> can be any sequence of characters, but 1020 the function is optimized for strings. 1021 </blockquote> 1022 1023 <p><br>[Function] 1024 <br><a class=none name="octets-to-string"><b>octets-to-string</b> <i>sequence <tt>&key</tt> external-format start end</i> => <i>string</i></a> 1025 1026 <blockquote><br> Converts the Lisp 1027 sequence <code><i>sequence</i></code> of <a href="#octet">octets</a> 1028 from <code><i>start</i></code> to <code><i>end</i></code> to a string 1029 using the <a href="#external-formats">external format</a> designated 1030 by <code><i>external-format</i></code>. The defaults for 1031 <code><i>start</i></code> and <code><i>end</i></code> 1032 are <code>0</code> and the length of the sequence. The default 1033 for <code><i>external-format</i></code> is <code>:LATIN1</code>. 1034 <p> 1035 This function is optimized for the case 1036 of <code><i>sequence</i></code> being 1037 a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_vector.htm">vector</a>. 1038 Don't use lists if you are in hurry. 1039 </blockquote> 1040 1041 <p><br>[Function] 1042 <br><a class=none name="octet-length"><b>octet-length</b> <i>string <tt>&key</tt> external-format start end</i> => <i>length</i></a> 1043 1044 <blockquote><br> 1045 1046 Returns the length of the subsequence of <code><i>string</i></code> from <code><i>start</i></code> to <code><i>end</i></code> in 1047 <a href="#octet">octets</a> if encoded using 1048 the <a href="#external-formats">external format</a> designated 1049 by <code><i>external-format</i></code>. 1050 The defaults for 1051 <code><i>start</i></code> and <code><i>end</i></code> 1052 are <code>0</code> and the length of <code><i>string</i></code>. The default 1053 for <code><i>external-format</i></code> is <code>:LATIN1</code>. 1054 <p> 1055 In spite of the name, <code><i>string</i></code> can be any sequence of characters, but 1056 the function is optimized for strings. 1057 </blockquote> 1058 1059 <p><br>[Function] 1060 <br><a class=none name="char-length"><b>char-length</b> <i>sequence <tt>&key</tt> external-format start end</i> => <i>length</i></a> 1061 1062 <blockquote><br> 1063 1064 Kind of the inverse of <a href="#octet-length"><code>OCTET-LENGTH</code></a>. 1065 Returns the length of the subsequence (of <a href="#octet">octets</a>) of <code><i>sequence</i></code> from <code><i>start</i></code> to <code><i>end</i></code> in 1066 characters if decoded using 1067 the <a href="#external-formats">external format</a> designated 1068 by <code><i>external-format</i></code>. 1069 The defaults for 1070 <code><i>start</i></code> and <code><i>end</i></code> 1071 are <code>0</code> and the length of the sequence. The default 1072 for <code><i>external-format</i></code> is <code>:LATIN1</code>. Note that this function doesn't check for the validity of the data in <code><i>sequence</i></code>. 1073 <p> 1074 This function is optimized for the case 1075 of <code><i>sequence</i></code> being 1076 a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_vector.htm">vector</a>. 1077 Don't use lists if you are in hurry. 1078 </blockquote> 1079 1080 <br> <br><h3><a class=none name="position">File positions</a></h3> 1081 1082 For <a href="#flexi-streams">flexi streams</a> as well 1083 as for <a href="#input-memory">in-memory 1084 streams</a>, <a 1085 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_file_p.htm">FILE-POSITION</a> 1086 will usually return <code>NIL</code> and do nothing when a second 1087 argument is supplied. This is correct 1088 w.r.t. the <a 1089 href="http://www.lispworks.com/documentation/HyperSpec/">ANSI 1090 standard</a>, but not very helpful. However, even 1091 with <a 1092 href="http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html">Gray 1093 streams</a> there is no <em>portable</em> way to implement a better 1094 behaviour. 1095 <p> 1096 For <a href="http://www.lispworks.com/">LispWorks</a> 1097 and <a href="http://clisp.sf.net/">CLISP</a>, 1098 <a 1099 href="http://www.lispworks.com/documentation/HyperSpec/Body/f_file_p.htm">FILE-POSITION</a> 1100 for <a href="#flexi-streams">flexi streams</a> will work as if the 1101 function had been applied to the underlying stream, and 1102 for <a href="#input-memory">in-memory streams</a> it will try to do 1103 something sensible if the underlying data structure is a vector 1104 (i.e. <em>not</em> a list). Patches for other Common Lisp 1105 implementations should be sent to 1106 the <a 1107 href="http://common-lisp.net/project/cl-plus-ssl/#trivial-gray-streams">trivial-gray-streams</a> 1108 maintainers. 1109 1110 <br> <br><h3><a class=none name="ack">Acknowledgements</a></h3> 1111 1112 Thanks to David Lichteblau for numerous portability patches. Thanks 1113 to Igor Plekhov for the KOI8-R code. Thanks to Anton Vodonosov for 1114 numerous patches and additions. Thanks 1115 to <a href="http://netzhansa.blogspot.com/">Hans Hübner</a> for 1116 his work on making FLEXI-STREAMS faster. 1117 1118 </body> 1119 </html>