Ticket #2: ,external-format-guessing.patch

File ,external-format-guessing.patch, 9.0 KB (added by afuchs, 18 years ago)

external format guessing patch

  • cl-irc.asd

    ? destructuring-irc-message.lisp
    ? test/package.fasl
    ? test/test-parse-message.fasl
    ? test/test-protocol.fasl
    RCS file: /project/cl-irc/cvsroot/cl-irc/cl-irc.asd,v
    retrieving revision 1.3
    diff -u -r1.3 cl-irc.asd
     
    1616    :version "0.5.2"
    1717    :licence "MIT"
    1818    :description "Common Lisp interface to the IRC protocol"
    19     :depends-on (:split-sequence :trivial-sockets)
     19    :depends-on (:split-sequence :trivial-sockets :flexi-streams)
    2020    :properties ((#:author-email . "cl-irc-devel@common-lisp.net")
    2121                 (#:date . "$Date: 2006/01/24 22:10:58 $")
    2222                 ((#:albert #:output-dir) . "doc/api-doc/")
  • command.lisp

    RCS file: /project/cl-irc/cvsroot/cl-irc/command.lisp,v
    retrieving revision 1.16
    diff -u -r1.16 command.lisp
     
    250250                     (logging-stream t))
    251251  "Connect to server and return a connection object."
    252252  (let* ((stream (socket-connect server port))
     253         (input-stream (flexi-streams:make-flexi-stream stream :element-type 'character :external-format '(:latin-1 :eol-style :crlf)))
    253254         (connection (make-connection :connection-type connection-type
    254255                                      :network-stream stream
     256                                      :input-stream input-stream
    255257                                      :client-stream logging-stream
    256258                                      :server-name server))
    257259         (user (make-user connection
  • event.lisp

    RCS file: /project/cl-irc/cvsroot/cl-irc/event.lisp,v
    retrieving revision 1.24
    diff -u -r1.24 event.lisp
  • protocol.lisp

    RCS file: /project/cl-irc/cvsroot/cl-irc/protocol.lisp,v
    retrieving revision 1.39
    diff -u -r1.39 protocol.lisp
     
    117117   (network-stream
    118118    :initarg :network-stream
    119119    :accessor network-stream
    120     :documentation "Stream used to talk to the IRC server.")
     120    :documentation "Stream used to talk binary to the IRC server.")
     121   (input-stream
     122    :initarg :input-stream
     123    :accessor input-stream
     124    :documentation "Stream used to receive messages from the IRC server.")
    121125   (server-capabilities
    122126    :initform *default-isupport-values*
    123127    :accessor server-capabilities
     
    183187(defgeneric re-apply-case-mapping (connection))
    184188
    185189(defun make-connection (&key (connection-type 'connection)
    186                              (user nil)
    187                              (server-name "")
    188                              (network-stream nil)
    189                              (client-stream t)
    190                              (hooks nil))
     190                        (user nil)
     191                        (server-name "")
     192                        (network-stream nil)
     193                        (output-stream nil)
     194                        (input-stream nil)
     195                        (client-stream t)
     196                        (hooks nil))
    191197  (let ((connection (make-instance connection-type
    192                                    :user user
    193                                    :server-name server-name
    194                                    :network-stream network-stream
    195                                    :client-stream client-stream)))
     198                       :user user
     199                       :server-name server-name
     200                       :network-stream network-stream
     201                       :input-stream input-stream
     202                       :client-stream client-stream)))
    196203    (dolist (hook hooks)
    197204      (add-hook connection (car hook) (cadr hook)))
    198205    connection))
     
    292299(defun read-message-loop (connection)
    293300  (loop while (read-message connection)))
    294301
     302(defun try-decode-line (line external-formats)
     303  (loop for external-format in external-formats
     304        for decoded = nil
     305        for error = nil
     306        do (multiple-value-setq (decoded error)
     307               (handler-case
     308                   (flexi-streams:with-input-from-sequence (in line)
     309                     (let ((flexi (flexi-streams:make-flexi-stream in :external-format external-format)))
     310                       (read-line flexi)))
     311                 (flexi-streams:flexi-stream-encoding-error ()
     312                   nil)))
     313        if decoded
     314          do (return decoded)))
     315
    295316(defmethod read-irc-message ((connection connection))
    296317  "Read and parse an IRC-message from the `connection'."
    297318  (handler-case
    298     (let ((message (create-irc-message
    299                     (read-line (network-stream connection) t))))
    300       (setf (connection message) connection)
    301       message)
     319      (let* ((line (read-line (input-stream connection) t))
     320             (message (create-irc-message
     321                       (concatenate 'string
     322                                    (try-decode-line (map 'vector #'char-code line)
     323                                                     *default-incoming-external-formats*)
     324                                    '(#\Return)))))
     325        (setf (connection message) connection)
     326        message)
    302327    (end-of-file ())))
    303328       ;; satisfy read-message-loop assumption of nil when no more messages
    304329
     
    306331                             &rest arguments)
    307332  "Turn the arguments into a valid IRC message and send it to the
    308333server, via the `connection'."
    309   (let ((raw-message (apply #'make-irc-message command arguments)))
    310     (write-sequence raw-message (network-stream connection))
    311     (force-output (network-stream connection))
     334  (let ((raw-message (apply #'make-irc-message command arguments))
     335        (output (flexi-streams:make-flexi-stream (network-stream connection) :element-type 'character
     336                                                 :external-format '(:latin-1 :eol-style :crlf))))
     337    (write-sequence raw-message output)
     338    (force-output output)
    312339    raw-message))
    313340
    314341(defmethod get-hooks ((connection connection) (class symbol))
     
    370397;;
    371398;; DCC Connection
    372399;;
    373 
     400;;; big TODO: flexi-streams
    374401(defclass dcc-connection ()
    375402  ((user
    376403    :initarg :user
  • utility.lisp

    RCS file: /project/cl-irc/cvsroot/cl-irc/utility.lisp,v
    retrieving revision 1.12
    diff -u -r1.12 utility.lisp
     
    5454parameters."
    5555  (let ((*print-circle* nil))
    5656    (format nil
    57             "~A~{ ~A~}~@[ :~A~]~A~A"
    58             command (butlast arguments) (car (last arguments))
    59             #\Return #\Linefeed)))
     57            "~A~{ ~A~}~@[ :~A~]~%"
     58            command (butlast arguments) (car (last arguments)))))
    6059
    6160(defun make-ctcp-message (string)
    6261  "Return a valid IRC CTCP message, as a string, composed by
     
    104103
    105104(defun socket-connect (server port)
    106105  "Create a socket connected to `server':`port' and return stream for it."
    107   (trivial-sockets:open-stream server port))
     106  (trivial-sockets:open-stream server port :element-type '(unsigned-byte 8)))
    108107
    109108
    110109(defun cut-between (string start-char end-chars &key (start 0) (cut-extra t))
    111   "If `start-char' is not nil, cut string between `start-char' and any
    112 of the `end-chars', from `start'.  If `start-char' is nil, cut from
    113 `start' until any of the `end-chars'.
     110  "If `start-char' is not nil, cut string between `start-char'
     111and any of the `end-chars', from `start'.  If `start-char' is
     112nil, cut from `start' until any of the `end-chars'.
    114113
    115114If `cut-extra' is t, we will cut from start + 1 instead of just
    116115`start'.
  • variable.lisp

    RCS file: /project/cl-irc/cvsroot/cl-irc/variable.lisp,v
    retrieving revision 1.7
    diff -u -r1.7 variable.lisp
     
    4141    ("PREFIX" ,*default-isupport-PREFIX*)
    4242    ("TARGMAX")))
    4343
     44(defparameter *default-outgoing-external-format* '(:latin-1 :eol-style :lf)
     45  "The external-format we use to encode outgoing messages. This
     46  should be an external format spec that flexi-streams accepts,
     47  with :eol-style :lf.")
     48
     49(defparameter *default-incoming-external-formats* '((:utf-8 :eol-style :lf)
     50                                                    (:latin-1 :eol-style :lf))
     51  "The external-formats we use to decode incoming messages. This
     52  should be a list of external format spec that flexi-streams accepts,
     53  with :eol-style :lf.
     54
     55The external formats are tried in order, until one decodes the
     56message without encoding errors. Note that the last external
     57format should be a single-byte one like latin-1.")
    4458
    4559(defvar *dcc-connections* nil)
    4660