Re: Mixing text and binary data



nicolas.edel@xxxxxxxxx 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__
.



Relevant Pages

  • Re: String compression
    ... then you will have to encode the binary attachments as base 64, ... compressed, encoded, and wrapped in a call to another web service. ... > The best way of doing it would be create a ZIP and send the zip, now, I> don;t think that you can send a binary stream using a webservice, if not the> the zip stream should be converted and sent as text. ... If we can compress the> string into a string then we can speed up the task and make eveyone happy. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Sending floats over a client-server in Smalltalk
    ... The trick is knowing what to decode them ... Then encode the number in the remaining bytes. ... ByteString>>floatAt: byteIndex ... I could then take a string ...
    (comp.lang.smalltalk)
  • Re: CCertAdmin.SetCertificateExtension
    ... > You must determine how the extension should be encoded and perform that> encoding prior to setting varExt.bstrVal and calling> SetCertificateExtension -- and you must then specify PROPTYPE_BINARY, ... > http://wp.netscape.com/eng/security/cert-exts.html appears to describe the> expected encoding as IA5 string. ... > You can use CryptEncodeObject to encode IA5 strings. ...
    (microsoft.public.platformsdk.security)
  • Re: high and low bytes of a decimal
    ... If you're trying to fit integers into a bytestream I'm guessing ... you need to encode your integers into a string ... Chances are you're going to want to use big-endian order, ...
    (comp.lang.perl.misc)
  • Re: Base64 encoding/decoding in VB6
    ... > Does anyone know how I can encode binary data to produce a character string ... Private Declare Sub RtlMoveMemory Lib "kernel32.dll" _ ... 'Encode encodes the byte array Source() to a string using the BASE64 ...
    (microsoft.public.vb.general.discussion)