Chicken-NBT: A Minecraft NBT reader for Chicken Scheme

I didn’t see any Scheme code to read Minecraft NBT data files, so I made one. And in doing so, I see why there weren’t any NBT readers in Scheme. (Haskell programmers can use Adam Foltzer’s much cleaner Haskell version.)

When I found out that there was a gzip egg called z3, I thought my troubles were over. Not quite, because although z3 made it ridiculously easy to read compressed data, the only real procedure I had to read data from the gzip stream was read-byte. And not only did I have to read only one byte at a time, but they were all promoted to ints anyways, since there is no notion of different-width integers in Chicken (only fixnums).

To read a 32-bit int, I read in 4 bytes and reassembled them into a fixnum. To read floats, well…

(define (readFloat)
    (let ([c-read-float
            (foreign-lambda* float
              ((int i1)
               (int i2)
               (int i3)
               (int i4))
               "uint8_t b1 = (uint8_t) i1;
                uint8_t b2 = (uint8_t) i2;
                uint8_t b3 = (uint8_t) i3;
                uint8_t b4 = (uint8_t) i4;
 
                uint32_t i = 0;
 
                i = b1;
                i = (i << 8) | b2;
                i = (i << 8) | b3;
                i = (i << 8) | b4;
 
                float f = *(float*)&i;
 
                C_return(f);")])
        (let* ([i1 (read-byte)]
               [i2 (read-byte)]
               [i3 (read-byte)]
               [i4 (read-byte)])
          (c-read-float i1 i2 i3 i4))))

Not only that, but Chicken seems to compile internal defines incorrectly, and I haven’t been able to figure out if that’s documented anywhere.

Anyways, the code works (for certain values of “works”) now and is on Github: chicken-nbt. Time permitting, I may package it into an egg.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>