2 Aug 2006 12:28
Re: BytePickle examples?
Philipp Haller <philipp.haller <at> epfl.ch>
2006-08-02 10:28:10 GMT
2006-08-02 10:28:10 GMT
>> This is a definition of a suitable pickler: >> val personPickler = wrap(p: Pair[String,int] => Person(p._1, p._2), >> p: Person => Pair(p.name, p.age), >> pair(string, int)) > > > Are you working with the same library version as me? This doesn't seem > to actually compile. It seems like int is missing; I had to use nat. Ah, yes. Sorry, it used to work with an earlier version of the library (I didn't compile it). Actually, I am thinking about renaming `nat' to `base128' because it encodes integers into base128. > The question I have is: How do I get an integer to always pickle as a 4 > byte, network order thing? I attached some code with a pickler that always pickles integers as 4 bytes. I don't know which order you need, though. If you think a pickler for integers as 4 bytes in "network order" is generally useful, we might add this to our pickler library. > As a side note, you might want to decrease the code density a bit for > the sake of those of us who aren't as familiar with Scala. It took me > more than a little hunting through the Scala reference to unwind your > sample pickler into something that gave enough error verbosity to figure > out what was wrong. OK, I'll try to be more verbose next time. Cheers, -- Philipp
import scala.io.BytePickle._
/**
A pickler for integers as 4 bytes.
Author: Philipp Haller <philipp.haller <at> epfl.ch>
*/
object Main {
def byteArrayToInt(b: Array[byte]): int = {
byteArrayToInt(b, 0)
}
def byteArrayToInt(b: Array[byte], offset: int): int = {
var value = 0
for (val i <- List.range(0, 4)) {
val shift = (4 - 1 - i) * 8
value = value + (b(i + offset) & 0x000000FF) << shift
}
value
}
def intToByteArray(value: int): Array[byte] = {
val b = new Array[byte](4)
for (val i <- List.range(0, 4)) {
val offset = (b.length - 1 - i) * 8
b(i) = ((value >>> offset) & 0xFF).asInstanceOf[byte]
}
b
}
def dumpBytes(bs: Array[byte]) = {
val buf = new StringBuffer(bs.length)
for (val i <- List.range(0, bs.length)) {
val hex: String = Integer.toHexString(0x0100 + (bs(i) & 0x00FF)).substring(1)
buf.append((if (hex.length() < 2) "0" else "") + hex)
}
buf.toString()
}
def int4: SPU[int] = new SPU[int] {
def appP(n: int, s: PicklerState): PicklerState = {
new PicklerState(Array.concat(s.stream, intToByteArray(n)), s.dict);
}
def appU(s: UnPicklerState): Pair[int,UnPicklerState] = {
Pair(byteArrayToInt(s.stream.subArray(0, 4)), new UnPicklerState(s.stream.subArray(4,
s.stream.length), s.dict))
}
}
def main(args: Array[String]) = {
Console.println(dumpBytes(intToByteArray(8)))
Console.println(dumpBytes(intToByteArray(10)))
Console.println(dumpBytes(intToByteArray(32)))
Console.println(dumpBytes(intToByteArray(100)))
Console.println(dumpBytes(intToByteArray(65535)))
val ba1 = pickle(int4, 8)
Console.println(dumpBytes(ba1))
Console.println(unpickle(int4, ba1))
val ba2 = pickle(int4, 10)
Console.println(dumpBytes(ba2))
Console.println(unpickle(int4, ba2))
val ba3 = pickle(int4, 32)
Console.println(dumpBytes(ba3))
Console.println(unpickle(int4, ba3))
val ba4 = pickle(int4, 65535)
Console.println(dumpBytes(ba4))
Console.println(unpickle(int4, ba4))
}
}
RSS Feed