uri-decode-string in prcc added by sjamaan on Fri Dec 12 12:39:51 2014

;; Basic stuff: convert all %XX inlines to the codepoint
;; identified by the hex char XX. Other chars are kept
;; as-is.  Invalid (incomplete) %-prefixed sequences
;; cause parser failure (return #f)

(define (uri-decode-string str #!optional (char-set char-set:full))
  (let ((result '()))
    (with-output-to-string            ; Failure will report to port :(
     (lambda ()
       (set! result
         (parse-string
          str
          (seq (rep (sel
                     (ind (seq (char #\%)
                               (act (seq hex-char hex-char)
                                    (lambda (encoded)
                                      (let ((decoded (integer->char
                                                      (string->number
                                                       (string-concatenate encoded) 16))))
                                        (and (char-set-contains? char-set decoded)
                                             (string decoded)))))) 1)
                     (pred! (char #\%) any-char)))
               (eof))))))
    (and result (string-concatenate result))))