Re: Sending floats over a client-server in Smalltalk



I did exactly this kind of thing to send arrays of different kinds of
numbers encoded as strings. The trick is knowing what to decode them
to. What I did was to encode the type of number in the first byte of
the string. Then encode the number in the remaining bytes. That way I
could encoded abitrary numbers and decode them without having to know
what they were.

For integers I implemented the following

Integer>>specialEncoding

| size value |
size := self digitLength + 1.
value := ByteString new: ( size ).
value at: 1 put: self code."the code for integers, should have one for
positive and another for negative values"
2 to: size do: [ :idx | value basicAt: idx put: ( self digitAt: idx -
1 ) ].
^value

To decode read the first byte to determine the type and decode
accordingly

For positive integers

| value |
value := LargePositiveInteger basicNew: self size - 1.
2 to: self size do: [ :idx | value digitAt: idx - 1 put: ( self
basicAt: idx ) ].
^value compressed "the compressed call will return a SmallInteger if it
can"

For negative integers just decode like a positive and multiply by -1

For Floats and Doubles you can take advantage of a couple primitives in
ByteArray. You can just re-implement in ByteString and call the same
primitive.

ByteString>>floatAt:put:
"Store a single-precision (32 bit)
floating point quantity
starting at the given byteIndex."

<primitive: 549>
^self primitiveFailed


ByteString>>floatAt: byteIndex
"Answer a single-precision (32 bit) floating point quantity
starting at the given byteIndex."

<primitive: 548>
^self primitiveFailed

Then to encode implement

Float>>specialEncoding
| value |
value := ByteString new: 5.
value at: 1 put: self code."the code for floats"
value floatAt: 2 put: self.
^value

There are analogous primitives for Doubles

ByteString>>doubleAt: byteIndex put: aDouble
"Store a double-precision (64 bit) floating point quantity
starting at the given byteIndex."

<primitive: 551>
^self primitiveFailed


ByteString>>doubleAt: byteIndex
"Answer a double-precision (64 bit) floating point quantity
starting at the given byteIndex."

<primitive: 550>
^self primitiveFailed

Then to encode implement

Double>>specialEncoding
| value |
value := ByteString new: 9.
value at: 1 put: self code."the code for doubles"
value doubleAt: 2 put: self.
^value

You just have to come up with a few codes to identify your number
types. I did this for Strings and Symbols too so I could polymorphicly
encode most of the "primitive data types" (sounds horrible to
smalltalkers) by sending specialEncoding. I could then take a string
and send it decode and it would look at the first byte, figure out what
it had inside and decode it properly.

Then to do this with collections I would put whole collections into one
big string (for sockets you could simply stream right onto them). I
would encode the length of the first encoded string in the first byte
of the big string then copy the small string in. Then put the next
length and the next string etc. To decode read the first byte for the
length, copy that many bytes then ready the next length.

I hope this makes sense and helps.

Mike

.



Relevant Pages

  • Re: URL filter and URL encoding problem
    ... will not encode chinese char. ... I am developing a tdi driver to filter a url.but if the url contains ... because that string is not UTF8-encoded. ... I am not aware of any Win32 APIs to decode URLs, so you may have to do ...
    (microsoft.public.development.device.drivers)
  • Re: utf8_encode(utf8_decode(string)) doesnt return same string
    ... > cause characters to go missing. ... I first encode an ISO string in UTF, ... It says you decode first, then encode. ...
    (comp.lang.php)
  • Re: How to display unicode with the CGI module?
    ... I am always confused as to which one to use: encode() or decode(); ... Unicode to ascii. ... like "unicode string" and you always need to think about when to ...
    (comp.lang.python)
  • Re: encode() question
    ... UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position ... happens when you convert a regular string to a unicode string. ... You are trying to encode a string. ...
    (comp.lang.python)
  • Re: TLV Objekte aus Datei lesen
    ... Weil STRING als OCTET STRING und IA5STRING vorkommen, das aber piepegal ist, schere ich die alle über einen Kamm und komme mit meinem STRING aus. ... Es gibt hier keinen Len-Parameter beim Decode. ... In meinen Daten haben die meisten der Arrays eine ein- oder zweibyteige Angabe der Anzahl der Records am Anfang. ... technischen Daten der Karte sofern sie in der Datei stehn). ...
    (de.comp.lang.delphi.misc)