Changeset 5319


Ignore:
Timestamp:
Oct 8, 2006, 7:28:31 PM (18 years ago)
Author:
Gary Byers
Message:

Yet another line-termination translation scheme; hopefully, the last for a
while. (More tedium before it's actually installed.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/level-1/l1-streams.lisp

    r5311 r5319  
    382382  (peek-char-function 'ioblock-no-char-input)
    383383  (native-byte-order t)
     384  (read-char-without-translation-while-locked-function 'ioblock-no-char-input)
     385  (write-char-without-translation-while-locked-function 'iblock-no-char-output)
     386  (sharing nil)
     387  (reserved0 nil)
     388  (reserved1 nil)
    384389  (reserved2 nil)
    385   (reserved3 nil)
    386   (reserved4 nil))
     390  (reserved3 nil))
    387391
    388392
     
    477481      (unless (%ioblock-advance ioblock t)
    478482        (return-from %ioblock-read-u8-byte :eof))
     483      (setq idx (io-buffer-idx buf)))
     484    (setf (io-buffer-idx buf) (the fixnum (1+ idx)))
     485    (aref (the (simple-array (unsigned-byte 8) (*))
     486            (io-buffer-buffer buf)) idx)))
     487
     488(declaim (inline %ioblock-read-u8-code-unit))
     489(defun %ioblock-read-u8-code-unit (ioblock)
     490  (declare (optimize (speed 3) (safety 0)))
     491  (let* ((buf (ioblock-inbuf ioblock))
     492         (idx (io-buffer-idx buf))
     493         (limit (io-buffer-count buf)))
     494    (declare (fixnum idx limit))
     495    (when (= idx limit)
     496      (unless (%ioblock-advance ioblock t)
     497        (return-from %ioblock-read-u8-code-unit :eof))
    479498      (setq idx (io-buffer-idx buf)
    480499            limit (io-buffer-count buf)))
    481500    (setf (io-buffer-idx buf) (the fixnum (1+ idx)))
    482501    (aref (the (simple-array (unsigned-byte 8) (*))
    483             (io-buffer-buffer buf)) idx)))
     502              (io-buffer-buffer buf)) idx)))             
    484503
    485504(declaim (inline %ioblock-read-s8-byte))
     
    10851104          (unless (%ioblock-advance ioblock t)
    10861105            (return-from %ioblock-tyi :eof))
    1087           (setq idx (io-buffer-idx buf)
    1088                 limit (io-buffer-count buf)))
     1106          (setq idx 0))
    10891107        (setf (io-buffer-idx buf) (the fixnum (1+ idx)))
    10901108        (%code-char (aref (the (simple-array (unsigned-byte 8) (*))
    1091                             (io-buffer-buffer buf)) idx))))))
     1109                                       (io-buffer-buffer buf)) idx))))))
    10921110
    10931111(defun %private-ioblock-tyi (ioblock)
     
    11091127      (prog1 ch
    11101128        (setf (ioblock-untyi-char ioblock) nil))
    1111       (let* ((1st-unit (%ioblock-read-u8-byte ioblock)))
     1129      (let* ((1st-unit (%ioblock-read-u8-code-unit ioblock)))
    11121130        (if (eq 1st-unit :eof)
    11131131          1st-unit
     
    11191137              (funcall (ioblock-decode-input-function ioblock)
    11201138                       1st-unit
    1121                        #'%ioblock-read-u8-byte
     1139                       #'%ioblock-read-u8-code-unit
    11221140                       ioblock))))))))
    11231141
     
    20602078
    20612079(defun %ioblock-unencoded-read-line (ioblock)
    2062   (let* ((string "")
    2063          (len 0)
    2064          (eof nil)
    2065          (inbuf (ioblock-inbuf ioblock))
    2066          (buf (io-buffer-buffer inbuf))
    2067          (newline (char-code #\newline)))
    2068     (let* ((ch (ioblock-untyi-char ioblock)))
    2069       (when ch
    2070         (setf (ioblock-untyi-char ioblock) nil)
    2071         (if (eql ch #\newline)
    2072           (return-from %ioblock-unencoded-read-line
    2073             (values string nil))
    2074           (progn
    2075             (setq string (make-string 1)
    2076                   len 1)
    2077             (setf (schar string 0) ch)))))
    2078     (loop
    2079       (let* ((more 0)
    2080              (idx (io-buffer-idx inbuf))
    2081              (count (io-buffer-count inbuf)))
    2082         (declare (fixnum idx count more))
    2083         (if (= idx count)
    2084           (if eof
    2085             (return (values string t))
    2086             (progn
    2087               (setq eof t)
    2088               (%ioblock-advance ioblock t)))
    2089           (progn
    2090             (setq eof nil)
    2091             (let* ((pos (position newline buf :start idx :end count)))
    2092               (when pos
    2093                 (locally (declare (fixnum pos))
    2094                   (setf (io-buffer-idx inbuf) (the fixnum (1+ pos)))
    2095                   (setq more (- pos idx))
    2096                   (unless (zerop more)
    2097                     (setq string
    2098                           (%extend-vector
    2099                            0 string (the fixnum (+ len more)))))
     2080  (let* ((inbuf (ioblock-inbuf ioblock)))
     2081    (if (io-buffer-translate inbuf)
     2082      (%ioblock-encoded-read-line ioblock)
     2083      (let* ((string "")
     2084             (len 0)
     2085             (eof nil)
     2086             (buf (io-buffer-buffer inbuf))
     2087             (newline (char-code #\newline)))
     2088        (let* ((ch (ioblock-untyi-char ioblock)))
     2089          (when ch
     2090            (setf (ioblock-untyi-char ioblock) nil)
     2091            (if (eql ch #\newline)
     2092              (return-from %ioblock-unencoded-read-line
     2093                (values string nil))
     2094              (progn
     2095                (setq string (make-string 1)
     2096                      len 1)
     2097                (setf (schar string 0) ch)))))
     2098        (loop
     2099          (let* ((more 0)
     2100                 (idx (io-buffer-idx inbuf))
     2101                 (count (io-buffer-count inbuf)))
     2102            (declare (fixnum idx count more))
     2103            (if (= idx count)
     2104              (if eof
     2105                (return (values string t))
     2106                (progn
     2107                  (setq eof t)
     2108                  (%ioblock-advance ioblock t)))
     2109              (progn
     2110                (setq eof nil)
     2111                (let* ((pos (position newline buf :start idx :end count)))
     2112                  (when pos
     2113                    (locally (declare (fixnum pos))
     2114                      (setf (io-buffer-idx inbuf) (the fixnum (1+ pos)))
     2115                      (setq more (- pos idx))
     2116                      (unless (zerop more)
     2117                        (setq string
     2118                              (%extend-vector
     2119                               0 string (the fixnum (+ len more)))))
     2120                      (%copy-u8-to-string
     2121                       buf idx string len more)
     2122                      (return (values string nil))))
     2123                  ;; No #\newline in the buffer.  Read everything that's
     2124                  ;; there into the string, and fill the buffer again.
     2125                  (setf (io-buffer-idx inbuf) count)
     2126                  (setq more (- count idx)
     2127                        string (%extend-vector
     2128                                0 string (the fixnum (+ len more))))
    21002129                  (%copy-u8-to-string
    21012130                   buf idx string len more)
    2102                   (return (values string nil))))
    2103               ;; No #\newline in the buffer.  Read everything that's
    2104               ;; there into the string, and fill the buffer again.
    2105               (setf (io-buffer-idx inbuf) count)
    2106               (setq more (- count idx)
    2107                     string (%extend-vector
    2108                             0 string (the fixnum (+ len more))))
    2109               (%copy-u8-to-string
    2110                buf idx string len more)
    2111               (incf len more))))))))
     2131                  (incf len more))))))))))
    21122132
    21132133;;; There are lots of ways of doing better here, but in the most general
     
    21252145         
    21262146(defun %ioblock-unencoded-character-read-vector (ioblock vector start end)
    2127   (do* ((i start)
    2128         (in (ioblock-inbuf ioblock))
    2129         (inbuf (io-buffer-buffer in))
    2130         (need (- end start)))
    2131        ((= i end) end)
    2132     (declare (fixnum i need))
    2133     (let* ((ch (%ioblock-tyi ioblock)))
    2134       (if (eq ch :eof)
    2135         (return i))
    2136       (setf (schar vector i) ch)
    2137       (incf i)
    2138       (decf need)
    2139       (let* ((idx (io-buffer-idx in))
    2140              (count (io-buffer-count in))
    2141              (avail (- count idx)))
    2142         (declare (fixnum idx count avail))
    2143         (unless (zerop avail)
    2144           (if (> avail need)
    2145             (setq avail need))
    2146           (%copy-u8-to-string inbuf idx vector i avail)
    2147           (setf (io-buffer-idx in) (+ idx avail))
    2148           (incf i avail)
    2149           (decf need avail))))))
     2147  (let* ((in (ioblock-inbuf ioblock)))
     2148    (if (io-buffer-translate in)
     2149      (%ioblock-encoded-character-read-vector ioblock vector start end)
     2150      (do* ((i start)
     2151            (inbuf (io-buffer-buffer in))
     2152            (need (- end start)))
     2153           ((= i end) end)
     2154        (declare (fixnum i need))
     2155        (let* ((ch (%ioblock-tyi ioblock)))
     2156          (if (eq ch :eof)
     2157            (return i))
     2158          (setf (schar vector i) ch)
     2159          (incf i)
     2160          (decf need)
     2161          (let* ((idx (io-buffer-idx in))
     2162                 (count (io-buffer-count in))
     2163                 (avail (- count idx)))
     2164            (declare (fixnum idx count avail))
     2165            (unless (zerop avail)
     2166              (if (> avail need)
     2167                (setq avail need))
     2168              (%copy-u8-to-string inbuf idx vector i avail)
     2169              (setf (io-buffer-idx in) (+ idx avail))
     2170              (incf i avail)
     2171              (decf need avail))))))))
    21502172
    21512173(defun %ioblock-encoded-character-read-vector (ioblock vector start end)
     
    22962318;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    22972319
    2298 
    2299 
    2300 (defun setup-ioblock-input (ioblock character-p element-type sharing encoding)
     2320;;; Character-at-a-time line-termination-translation functions.
     2321;;; It's not always possible to just blast through the buffer, blindly
     2322;;; replacing #xd with #xa (for example), and it's not always desirable
     2323;;; to do that (if we support changing encoding on open streams.)
     2324;;; This is done at a fairly high level; some cases could be done at
     2325;;; a lower level, and some cases are hard even at that lower level.
     2326;;; This approach doesn't slow down the simple case (when no line-termination
     2327;;; translation is used), and hopefully isn't -that- bad.
     2328
     2329(declaim (inline %ioblock-read-char-translating-cr-to-newline))
     2330(defun %ioblock-read-char-translating-cr-to-newline (ioblock)
     2331  (let* ((ch (funcall
     2332              (ioblock-read-char-without-translation-while-locked-function
     2333               ioblock)
     2334              ioblock)))
     2335    (if (eql ch #\Return)
     2336      #\Newline
     2337      ch)))
     2338
     2339(defun %private-ioblock-read-char-translating-cr-to-newline (ioblock)
     2340  (check-ioblock-owner ioblock)
     2341  (%ioblock-read-char-translating-cr-to-newline ioblock))
     2342
     2343(defun %locked-ioblock-read-char-translating-cr-to-newline (ioblock)
     2344  (with-ioblock-input-lock-grabbed (ioblock)
     2345    (%ioblock-read-char-translating-cr-to-newline ioblock)))
     2346
     2347(declaim (inline %ioblock-read-char-translating-crlf-to-newline))
     2348(defun %ioblock-read-char-translating-crlf-to-newline (ioblock)
     2349  (let* ((ch (funcall
     2350              (ioblock-read-char-without-translation-while-locked-function
     2351               ioblock)
     2352              ioblock)))
     2353    (if (eql ch #\Return)
     2354      (let* ((next (funcall
     2355                    (ioblock-read-char-without-translation-while-locked-function
     2356                     ioblock)
     2357                    ioblock)))
     2358        (if (eql next #\Linefeed)
     2359          next
     2360          (progn
     2361            (unless (eq next :eof)
     2362              (setf (ioblock-untyi-char ioblock) next))
     2363            ch)))
     2364      ch)))
     2365   
     2366(defun %private-ioblock-read-char-translating-crlf-to-newline (ioblock)
     2367  (check-ioblock-owner ioblock)
     2368  (%ioblock-read-char-translating-crlf-to-newline ioblock))
     2369
     2370(defun %locked-ioblock-read-char-translating-crlf-to-newline (ioblock)
     2371  (with-ioblock-input-lock-grabbed (ioblock)
     2372    (%ioblock-read-char-translating-crlf-to-newline ioblock)))
     2373
     2374(declaim (inline %ioblock-read-char-translating-line-separator-to-newline))
     2375(defun %ioblock-read-char-translating-line-separator-to-newline (ioblock)
     2376  (let* ((ch (funcall
     2377              (ioblock-read-char-without-translation-while-locked-function
     2378               ioblock)
     2379              ioblock)))
     2380    (if (eql ch #\Line_Separator)
     2381      #\Newline
     2382      ch)))
     2383
     2384(defun %private-ioblock-read-char-translating-line-separator-to-newline (ioblock)
     2385  (check-ioblock-owner ioblock)
     2386  (%ioblock-read-char-translating-line-separator-to-newline ioblock))
     2387
     2388(defun %locked-ioblock-read-char-translating-line-separator-to-newline (ioblock)
     2389  (with-ioblock-input-lock-grabbed (ioblock)
     2390    (%ioblock-read-char-translating-line-separator-to-newline ioblock)))
     2391
     2392(declaim (inline %ioblock-write-char-translating-newline-to-cr))
     2393(defun %ioblock-write-char-translating-newline-to-cr (ioblock char)
     2394  (funcall (ioblock-write-char-without-translation-while-locked-function
     2395            ioblock)
     2396           ioblock
     2397           (if (eql char #\Newline) #\Return char)))
     2398
     2399(defun %private-ioblock-write-char-translating-newline-to-cr (ioblock char)
     2400  (check-ioblock-owner ioblock)
     2401  (%ioblock-write-char-translating-newline-to-cr ioblock char))
     2402
     2403(defun %locked-ioblock-write-char-translating-newline-to-cr (ioblock char)
     2404  (with-ioblock-input-lock-grabbed (ioblock)
     2405    (%ioblock-write-char-translating-newline-to-cr ioblock char)))
     2406
     2407(declaim (inline %ioblock-write-char-translating-newline-to-crlf))
     2408(defun %ioblock-write-char-translating-newline-to-crlf (ioblock char)
     2409  (when (eql char #\Newline)
     2410    (funcall (ioblock-write-char-without-translation-while-locked-function
     2411              ioblock)
     2412             ioblock
     2413             #\Return))   
     2414  (funcall (ioblock-write-char-without-translation-while-locked-function
     2415            ioblock)
     2416           ioblock
     2417           char))
     2418
     2419(defun %private-ioblock-write-char-translating-newline-to-crlf (ioblock char)
     2420  (check-ioblock-owner ioblock)
     2421  (%ioblock-write-char-translating-newline-to-crlf ioblock char))
     2422
     2423(defun %locked-ioblock-write-char-translating-newline-to-crlf (ioblock char)
     2424  (with-ioblock-input-lock-grabbed (ioblock)
     2425    (%ioblock-write-char-translating-newline-to-crlf ioblock char)))
     2426
     2427(declaim (inline %ioblock-write-char-translating-newline-to-line-separator))
     2428(defun %ioblock-write-char-translating-newline-to-line-separator (ioblock char)
     2429  (funcall (ioblock-write-char-without-translation-while-locked-function
     2430            ioblock)
     2431           ioblock
     2432           (if (eql char #\Newline) #\Line_Separator char)))
     2433
     2434(defun %private-ioblock-write-char-translating-newline-to-line-separator (ioblock char)
     2435  (check-ioblock-owner ioblock)
     2436  (%ioblock-write-char-translating-newline-to-line-separator ioblock char))
     2437
     2438(defun %locked-ioblock-write-char-translating-newline-to-line-separator (ioblock char)
     2439  (with-ioblock-input-lock-grabbed (ioblock)
     2440    (%ioblock-write-char-translating-newline-to-line-separator ioblock char)))
     2441
     2442
     2443;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     2444
     2445(defun setup-ioblock-input (ioblock character-p element-type sharing encoding line-termination)
    23012446  (when character-p
    23022447    (if encoding
    23032448      (let* ((unit-size (character-encoding-code-unit-size encoding)))
     2449        (unless (eql unit-size 8)
     2450          (setq line-termination nil))
    23042451        (setf (ioblock-peek-char-function ioblock) '%encoded-ioblock-peek-char)
    23052452        (setf (ioblock-read-line-function ioblock)
     
    23462493              '%ioblock-unencoded-character-read-vector)
    23472494        (setf (ioblock-read-line-function ioblock)
    2348               '%ioblock-unencoded-read-line))))
     2495              '%ioblock-unencoded-read-line)))
     2496    (case line-termination
     2497      ((:cr :crlf)
     2498       (let* ((inbuf (ioblock-inbuf ioblock)))
     2499         (setf (io-buffer-translate inbuf) line-termination)))))
    23492500  (unless (or (eq element-type 'character)
    23502501              (subtypep element-type 'character))
     
    24262577                   '%general-ioblock-read-byte))))))
    24272578
    2428 (defun setup-ioblock-output (ioblock character-p element-type sharing encoding)
     2579(defun setup-ioblock-output (ioblock character-p element-type sharing encoding line-termination)
    24292580  (when character-p
    24302581    (if encoding
    24312582      (let* ((unit-size (character-encoding-code-unit-size encoding)))
     2583        (unless (eq unit-size 8)
     2584          (setq line-termination nil))
    24322585        (setf (ioblock-encode-output-function ioblock)
    24332586              (character-encoding-stream-encode-function encoding))
     
    24752628                (:private '%private-ioblock-write-char)
    24762629                (:lock '%locked-ioblock-write-char)
    2477                 (t '%ioblock-write-char))))))
     2630                (t '%ioblock-write-char)))))
     2631        (case line-termination
     2632          ((:cr :crlf)
     2633           (let* ((outbuf (ioblock-outbuf ioblock)))
     2634             (setf (io-buffer-translate outbuf) line-termination)))))
    24782635  (unless (or (eq element-type 'character)
    24792636              (subtypep element-type 'character))
     
    25782735                            character-p
    25792736                            encoding
     2737                            line-termination
    25802738                            &allow-other-keys)
    25812739  (declare (ignorable element-shift))
     
    26172775          (when (eq sharing :lock)
    26182776            (setf (ioblock-inbuf-lock ioblock) (make-lock)))
    2619           (setup-ioblock-input ioblock character-p element-type sharing encoding)
     2777          (setup-ioblock-input ioblock character-p element-type sharing encoding line-termination)
    26202778          (setf (ioblock-element-shift ioblock) (max 0 (ceiling (log  (/ in-size-in-octets insize) 2))))
    26212779          )))
     
    26452803            ))))
    26462804    (when (or share-buffers-p outsize)
    2647       (setup-ioblock-output ioblock character-p element-type sharing encoding))
     2805      (setup-ioblock-output ioblock character-p element-type sharing encoding line-termination))
    26482806    (when element-type
    26492807      (setf (ioblock-element-type ioblock) element-type))
     
    27652923
    27662924
     2925(defparameter *canonical-line-termination-conventions*
     2926  '((:unix . nil)
     2927    (:macos . :cr)
     2928    (:cr . :cr)
     2929    (:crlf . :crlf)
     2930    (:cp/m . :crlf)
     2931    (:msdos . :crlf)
     2932    (:windows . :crlf)
     2933    (:inferred . nil)))
     2934
     2935
     2936   
     2937
    27672938;;; Note that we can get "bivalent" streams by specifiying :character-p t
    27682939;;; with a reasonable element-type (e.g. (UNSIGNED-BYTE 8))
     
    27772948                                           (subtypep element-type 'character)))
    27782949                          (basic nil)
    2779                           encoding)
     2950                          encoding
     2951                          line-termination)
     2952  (when line-termination
     2953    (setq line-termination
     2954          (cdr (assoc line-termination *canonical-line-termination-conventions*))))
    27802955  (when basic
    27812956    (setq class (map-to-basic-stream-class-name class))
     
    28002975                         :sharing sharing
    28012976                         :character-p character-p
    2802                          :encoding encoding)))
     2977                         :encoding encoding
     2978                         :line-termination line-termination)))
    28032979 
    28042980;;;  Fundamental streams.
Note: See TracChangeset for help on using the changeset viewer.