Sujet : Re: what is wrong with this loop?
De : Nobody447095 (at) *nospam* here-nor-there.org (B. Pym)
Groupes : comp.lang.lisp comp.lang.schemeDate : 11. Jul 2025, 20:36:49
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <104rp4c$1ls3b$1@dont-email.me>
References : 1 2
User-Agent : XanaNews/1.18.1.6
B. Pym wrote:
B. Pym wrote:
Kenny Tilton wrote:
here are some test cases:
(decode-http-encoded "aaaa") ;; this works
(decode-http-encoded "aaaa%62ccc" ) ;; this dies because start is 0
;; and end is -3 (0 based index)
....
(defun decode-http-encoded( x )
(with-output-to-string(s)
(loop for start = 0 then (+ pct 3)
for pct = (position #\% x :start start)
while pct
do (princ (subseq x start pct) s )
(let ((is (subseq x (1+ pct) (+ pct 3))))
(princ (code-char (parse-integer is)) s))
The integer to be parsed is in hexadecimal, Kenny.
finally (princ (subseq x start) s))
s ))
Instead of CL (COBOL-Like), let's use a Lispy language.
Gauche Scheme:
The easy way.
(define (decode-http-encoded x)
(regexp-replace-all
#/%(..)/
x
(lambda (m) (integer->char (string->number (m 1) 16)))))
(decode-http-encoded "foo%20bar%20%41ct")
===>
"foo bar Act"
Harder.
(use gauche.sequence) ;; subseq size-of
(define (decode-http-encoded x)
(define (hex->c s) (integer->char (string->number s 16)))
(with-output-to-string
(lambda()
(do ((i 0 (+ i 1)))
((= i (size-of x)))
(let1 c (ref x i)
(when (equal? c #\%)
(set! c (hex->c (subseq x (+ i 1)(+ i 3))))
(inc! i 2))
(display c))))))
To make the processing easier, first convert the string
to a list of characters.
(define (decode-http-encoded x)
(define (hex->c s) (integer->char (string->number s 16)))
(let1 z (string->list x)
(with-output-to-string
(lambda()
(while (pair? z)
(let1 c (pop! z)
(and (eqv? c #\%)
(set! c (hex->c (string (pop! z) (pop! z)))))
(display c)))))))
Let's define a safe version of pop! that doesn't
raise an error if the list is empty.
(define-syntax pop~
(syntax-rules ()
[ (pop~ List)
(if (null? List)
#f
(pop! List)) ]))
(define (decode-http-encoded x)
(define (hex->c s) (integer->char (string->number s 16)))
(let1 z (string->list x)
(with-output-to-string
(lambda()
(while (pop~ z) => c
(and (eqv? c #\%)
(set! c (hex->c (string (pop! z) (pop! z)))))
(display c))))))