Subject: [Fwd: Re: [clisp-list] VECTOR-PUSH-EXTEND [was ((SETF STREAM-ELEMENT-TYPE) new-element-type stream)]]

From: Adam Warner <[email-masked]>
Date: Sun Sep 8 03:53:02 2002

One more try. Please don't bounce this one Sourceforge.

-----Forwarded Message-----

From: Adam Warner <[email-masked]>
To: [email-masked]
Subject: Re: [clisp-list] VECTOR-PUSH-EXTEND [was ((SETF STREAM-ELEMENT-TYPE) new-element-type stream)]
Date: 08 Sep 2002 22:11:06 +1200

On Sun, 2002-09-08 at 12:43, Sam Steingold wrote:
> > * In message <1031440965.1510.43.camel@work>
> > * On the subject of "Re: [clisp-list] ((SETF STREAM-ELEMENT-TYPE) new-element-type stream)"
> > * Sent on 08 Sep 2002 11:22:44 +1200
> > * Honorable Adam Warner <[email-masked]> writes:
> >
> > The kludge is that I currently have to simulate a binary stream using
> > with-output-to-string, convert that to a vector and then convert that
> > to a UTF-8 encoded string. If I had a vector stream of (unsigned-byte
> > 8) I could bypass the conversion from the simulated binary stream to
> > the actual vector stream (plus writing to a vector stream should be
> > faster than a string stream).
> 
> why use streams at all?
> doesn't VECTOR-PUSH-EXTEND do what you want?

Here's the vector-push-extend version:

    (defun unescape-uri (string)
      (let ((input-string (substitute #\Newline #\+ string))
	    (start-pos 0)
	    (byte-vector (make-array 1000 :adjustable t :fill-pointer 0 :element-type '(unsigned-byte 8))))
	(loop for pos = (position #\% input-string :start start-pos) until (eq pos nil)
	      unless (= pos start-pos) do (map nil #'(lambda (x) (vector-push-extend (char-code x) byte-vector))
					       (subseq input-string start-pos pos))
	      do (vector-push-extend (parse-integer (subseq input-string (1+ pos) (+ pos 3)) :radix 16) byte-vector)
	      (setf start-pos (+ pos 3)))
	(map nil #'(lambda (x) (vector-push-extend (char-code x) byte-vector)) (subseq input-string start-pos))
	(convert-string-from-bytes byte-vector *terminal-encoding*)))

It's quite tidy in comparison. It uses map+anonymous functions to
efficiently push non-escaped sequences onto the byte-vector.

You can break it by supplying a broken string (e.g. supplying the %
without a two digit hex number).

Regards,
Adam

---

From: Sam Steingold <[email-masked]>
Date: Sun Sep 8 14:38:11 2002

> * In message <1031482631.4271.6.camel@work>
> * On the subject of "[Fwd: Re: [clisp-list] VECTOR-PUSH-EXTEND [was ((SETF STREAM-ELEMENT-TYPE) new-element-type stream)]]"
> * Sent on 08 Sep 2002 22:57:11 +1200

replacing 
	(map nil #'(lambda (x) (vector-push-extend (char-code x) byte-vector)) (subseq input-string start-pos pos))
with
        (loop for i from start-pos to pos do (vector-push-extend (char-code (aref input-string i)) byte-vector))
will save you consing SUBSEQ and LAMBDA.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.3 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
I may be getting older, but I refuse to grow up!