Common lispでURLエンコード、デコード

URLエンコード、デコードする関数。
sb-extを使ってるのでsbcl限定。

(make-array 0 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0)
可変長の配列

(vector-push-extend (read-octet strm) vec)
配列を拡張して追加

(peek-char t strm nil 'EOF)
一文字先読み

(read-from-string (format nil "#x~A~A" 
(read-char strm t)
(read-char strm t))))
文字列を数値に変換
(defun concate-char(str c)
  (concatenate 'string str (format nil "~A" c)))

(defun concate(str1 str2)
  (concatenate 'string str1 str2))

(defun urlencode(str encoding)
  (reduce #'(lambda (enc c)
          (cond ((char= #\  c)
             (concate-char enc #\+))
             ((or (and (char< #\A c)
                   (char> #\z c))
              (char= #\. c)
              (char= #\_ c)
              (char= #\- c))
              (concate-char enc c))
             (t
              (concate enc (encoding c encoding)))))
      str
      :initial-value ""))

(defun encoding(char encoding)
  (let* ((s (format nil "~A" char))
     (vec (sb-ext:string-to-octets s :external-format encoding :null-terminate nil)))
    (reduce #'(lambda (enc c)
        (concate enc (format nil "%~X" c)))
        vec
        :initial-value "")))

(defun urldecode(str encoding)
  (with-input-from-string (strm str)
              (let ((dec-str ""))
                (do ((c (peek-char t strm nil 'EOF)
                    (peek-char t strm nil 'EOF)))
                ((eql c 'EOF) dec-str)
                  (cond ((char= c #\+)
                     (read-char strm nil 'EOF)
                     (setf dec-str (concate-char dec-str #\ )))
                    ((char= c #\%)
                     (setf dec-str (concate dec-str (sb-ext:octets-to-string (read-octets strm) :external-format encoding))))
                    (t
                     (read-char strm nil 'EOF)
                     (setf dec-str (concate-char dec-str c))))))))
(defun read-octets(strm)
  (let ((vec (make-array 0 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0)))
    (do ((c (peek-char t strm nil 'EOF)
        (peek-char t strm nil 'EOF)))
    ((or (eql c 'EOF)
         (not (char= c #\%))) vec)
      (read-char strm nil 'EOF)
      (vector-push-extend (read-octet strm) vec))))
    
(defun read-octet(strm)
  (read-from-string (format nil "#x~A~A" 
                (read-char strm t)
                (read-char strm t))))

;; (defun urldecode(srcstr)
;;   (let ((decstr "")
;;     (vec nil))
;;     (with-input-from-string (strm srcstr)
;;                 (do ((c (peek-char strm nil 'EOF)
;;                     (peek-char strm nil 'EOF)))
;;                 ((eql c 'EOF) decstr)
;;                   (cond ((char= #\+ c)
;;                      (setf c (read-char strm nil 'EOF))
;;                      (setf decstr (concate-char decstr #\ )))
;;                     ((not (char= #\% c))
;;                      (setf c (read-char strm nil 'EOF))
;;                      (setf decstr (concate-char decstr c)))
;;                     (t
;;                      (setf c (read-char strm nil 'EOF))
;;                      (setf decstr (concate decstr "..."))))))))
                  

;; (defun read-encode-str(strm)
;;   (let ((fst (read-char strm nil 'EOF)))
;;     (if (eql fst 'EOF)
;;     ""
;;       (let ((scd (read-char strm nil 'EOF)))
;;     (if(eql scd 'EOF)
;;         ""
;;       (concatenate 'string (format nil "~A" fst) (format nil "~A" scd)))))))

;; (defun decode-string(strm encoding)
;;   (let ((vec (make-array 0 :element-type 'character :fill-pointer 0 :adjustable t)))
;;     (do ((c (peek-char t strm nil 'EOF)))
;;     ((eql 'EOF c) 
;;      (sb-ext:octets-to-string vec :external-format encoding))
;;       (cond ((char= 
       
;;                 (do ((c (read-char strm nil 'EOF)
;;                     (read-char strm nil 'EOF)))
;;                 ((eql c 'EOF) decstr)
;;                   (cond ((char= #\+ c)
;;                      (setf decstr (concate-char decstr #\ )))
;;                     ((not (char= #\% c))
;;                      (setf decstr (concate-char decstr c)))
;;                     (t
;;                      (setf decstr (concate decstr "..."))))))))


;; (defun urlencode(str encoding)
;;   (reduce #'(lambda (vec c)
;;           (cond ((char= #\  c)
;;              (vector-push-extend #\+ vec)
;;              vec)
;;              ((or (and (char< #\A c)
;;                    (char> #\z c))
;;               (char= #\. c)
;;               (char= #\_ c)
;;               (char= #\- c))
;;               (vector-push-extend c vec)
;;               vec)
;;              (t
;;               (concatenate 'string vec (encoding c encoding)))))
;;       str
;;       :initial-value (make-array 0 :element-type 'character :fill-pointer 0 :adjustable t)))

;; (defun encoding(char encoding)
;;   (let* ((s (format nil "~A" char))
;;      (vec (sb-ext:string-to-octets s :external-format encoding :null-terminate nil)))
;;     (reduce #'(lambda (vec c)
;;         (concatenate 'string vec (format nil "%~X" c)))
;;         vec
;;         :initial-value (make-array 0 :element-type 'character :fill-pointer 0 :adjustable t))))

;; (defun urldecode(srcstr)
;;   (with-input-from-string (strm srcstr)
;;               (pprint strm)))

;; (defun urldecode(srcstr)
;;   (let ((decstr ""))
;;     (do*  ((i 0 (1+ i))
;;        (s (subseq srcstr i (1+ i))))
;;     ((> i (length srcstr)))
;;       (cond ((or (and (string< "A" s)
;;               (string> "z" s))
;;          (string= "." s)
;;          (string= "_" s)
;;          (string= "-" s))
;;          (concatenate 'string s decstr))
;;         ((string= "+" s)
;;          (concatenate 'string " " decstr))
;;         ((string= "%" s)
;;          (setf i
;;            (do* ((j i (+ 2 j))
;;              (lst nil (cons (subseq srcstr j (+ 2 j)))))
;;                ((or (> (+ j 2) (length srcstr))
;;                 (not (string= "%" (subseq srcstr j (1+ j))))) j)))         

;; (defun convert-to-vec(lst)
;;   (make-array (length lst)


;;   (let ((lst nil))
;;     (do ((i 0 (1+ i)))
;;     ((<= (length str) i) lst)
;;       (let ((s (subseq str i (1+ i))))
;;     (cond ((or (and (string< "A" s)
;;             (string> "z" s))
;;            (string= "." s)
;;            (string= "_" s)
;;            (string= "-" s))
;;            (cons s lst))
;;           ((string= "+" s)
;;            (cons s lst))
;;           ((string= "%" s)
;;            (do ((j 0 (1+ j)))
;;            ((<= (length str) (+ j i)