From: ············@gmail.com
Subject: Mixing text and binary data
Date: 
Message-ID: <48a29ca4-610c-4996-8630-1fc07df42389@d21g2000prf.googlegroups.com>
I would like to read/write both text and binary data on sockets and
(*stdandard-input* *standard-output*).  Are there idioms in Lisp to
mix text and binary ?

From: Duane Rettig
Subject: Re: Mixing text and binary data
Date: 
Message-ID: <o0ve47cyq9.fsf@gemini.franz.com>
············@gmail.com writes:

> I would like to read/write both text and binary data on sockets and
> (*stdandard-input* *standard-output*).  Are there idioms in Lisp to
> mix text and binary ?

You already got two answers on this thread.  Another is to use
"simple-streams", which is available in Allegro CL, as well as some of
the free lisps (CMUCL, at least).  Documentation starts here:

http://www.franz.com/support/documentation/current/doc/streams.htm

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: ············@gmail.com
Subject: Re: Mixing text and binary data
Date: 
Message-ID: <1fc27b90-0706-49af-bff8-17ea439d7ec8@s37g2000prg.googlegroups.com>
On 29 fév, 21:08, Duane Rettig <·····@franz.com> wrote:
[...]
> You already got two answers on this thread.

Nice shot, indeed ;)
From: Maciej Katafiasz
Subject: Re: Mixing text and binary data
Date: 
Message-ID: <fq91nb$kb2$1@news.net.uni-c.dk>
Den Fri, 29 Feb 2008 04:40:50 -0800 skrev nicolas.edel:

> I would like to read/write both text and binary data on sockets and
> (*stdandard-input* *standard-output*).  Are there idioms in Lisp to mix
> text and binary ?

http://www.cliki.net/Flexi-streams for instance. In CL parlance, such 
streams are referred to as "bivalent". There are various mechanisms to 
implement them, usually implementation-dependent.

Cheers,
Maciej
From: Pascal J. Bourguignon
Subject: Re: Mixing text and binary data
Date: 
Message-ID: <7cejavyj6n.fsf@pbourguignon.anevia.com>
············@gmail.com writes:

> I would like to read/write both text and binary data on sockets and
> (*stdandard-input* *standard-output*).  Are there idioms in Lisp to
> mix text and binary ?

Use a binary stream and encode and decode explicitely.


(defconstant +ascii-code+ " !\"#$%&'()*+,-./0123456789:;<=>·@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
(defconstant +ascii-base+     32)
(defconstant +ascii-linefeed+ 10)

(defun ascii-encode (string)
  (map 'vector
       (lambda (ch) 
                 (if (char= ch #\newline)
                     +ascii-linefeed+
                     (let ((pos (position ch +ascii-code+)))
                       (if pos
                           (+ +ascii-base+ pos)
                           (error "Cannot encode in ASCII the character ~C" ch)))))
       string))


(defun ascii-decode (codes)
  (map 'string
       (lambda (code)
         (cond
           ((= +ascii-linefeed+ code) #\newline)
           ((<= +ascii-base+ code (+ +ascii-base+ (length +ascii-code+) -1))
            (aref +ascii-code+ (- code +ascii-base+)))
           ((< code 128) (error "The ASCII code ~D doesn't correspond to any character." code))
           (t            (error "The coed ~D is not an ASCII code." code))))))


Note that most functions you usually apply on strings are actually
defined on vectors or even sequences, so you can use them as well on
code vectors.

(read-sequence buffer)
(cond
  ((=  5 (mismatch #.(ascii-encode "HELO ")      buffer))  (process-helo      (subseq buffer  5)))
  ((= 10 (mismatch #.(ascii-encode "MAIL FROM ") buffer))  (process-mail-from (subseq buffer 10)))
  ...)


For more complex encoding, you could avoid implementing your own
unicode encode/decode using implementation dependant functions such as
#+clisp ext:convert-string-to-bytes, or dig for some 'portability'
sub-library (eg. there's something in arnesi).  But most protocol take
care to specify ASCII for the active strings.

-- 
__Pascal Bourguignon__
From: Rob Warnock
Subject: Re: Mixing text and binary data
Date: 
Message-ID: <58SdnbPCqL2RpFTanZ2dnUVZ_jCdnZ2d@speakeasy.net>
<············@gmail.com> wrote:
+---------------
| I would like to read/write both text and binary data on sockets and
| (*stdandard-input* *standard-output*).  Are there idioms in Lisp to
| mix text and binary ?
+---------------

You've already gotten good answers from others, but just in case
you're using CMUCL, the implementation-specific way there is to
add the :CLASS 'BINARY-TEXT-STREAM and :ELEMENT-TYPE :DEFAULT
optional args to the OPEN (or WITH-OPEN-FILE). That will let
you do both text (e.g., READ-CHAR) and binary (e.g. READ-BYTE)
operations on the resulting stream.

In particular, my CMUCL "-script" hack uses it to allow "#!"
scripts of both source files and FASLs, see:

    http://rpw3.org/hacks/lisp/site-switch-script.lisp


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607