nkunicki
nkunicki

Reputation: 59

Node.js and 64-bit varints

I'm in the process of writing a Node.js based application which talks via TCP to a C++ based server. The server speaks a binary protocol, quite similar to Protocol Buffers, but not exactly the same.

One data type the server returns is that of a unsigned 64-bit integer (uint64_t), serialized as a varint, where the most significant bit is used to indicate whether the next byte is also part of the int.

I am unable to parse this out in Javascript currently due to the 32-bit limitation on bitwise operations, and also the fact that JS doesn't do 64-bit ints natively. Does anyone have any suggestions on how I could do this?

My varint reading code is very similar to that shown here: https://github.com/chrisdickinson/varint/blob/master/decode.js

I thought I could use node-bignum to represent the number, but I'm unsure how to turn a Buffer consisting of varint bytes into this.

Cheers, Nathan

Upvotes: 1

Views: 556

Answers (1)

Ext3h
Ext3h

Reputation: 6393

Simply took the existing varint read module and modified it to yield a Bignum object instead of a regular number:

Bignum = require('bignum');
module.exports = read;

var MSB = 0x80
    , REST = 0x7F;

function read(buf, offset) {
    var res    = Bignum(0)
        , offset = offset || 0
        , counter = offset
        , b
        , shift  = 0
        , l = buf.length;

    do {
        if(counter >= l) {
            read.bytesRead = 0;
            return undefined
        }
        b = buf[counter++];
        res = res.add(Bignum(b & REST).shiftLeft(shift));
        shift += 7
    } while (b >= MSB);

    read.bytes = counter - offset;

    return res
}

Use it exactly the same way as you would have used the original decode module.

Upvotes: 1

Related Questions