Re: Sending floats over a client-server in Smalltalk
- From: "Mike Hales" <knowledgescape@xxxxxxxxx>
- Date: 5 Apr 2006 17:55:03 -0700
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
.
- References:
- Sending floats over a client-server in Smalltalk
- From: enigmainorlando
- Sending floats over a client-server in Smalltalk
- Prev by Date: Re: What Smalltalk product/implementation would you use, and why?
- Next by Date: Re: What Smalltalk product/implementation would you use, and why?
- Previous by thread: Re: Sending floats over a client-server in Smalltalk
- Next by thread: Re: Sending floats over a client-server in Smalltalk
- Index(es):
Relevant Pages
|