msgpack-lite icon indicating copy to clipboard operation
msgpack-lite copied to clipboard

Implement MessagePack timestamp extension

Open dchenk opened this issue 7 years ago • 4 comments

The MessagePack has for a while now had a built-in timestamp extension: https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type

Are there any plans to implement the timestamp format? I'd be especially excited about the 0xc7 version.

dchenk avatar Apr 15 '18 05:04 dchenk

Yes, I've been working for it. I'll retry to merge it in this month.

kawanet avatar Apr 24 '18 01:04 kawanet

I've just stumbled across this as well, in my very first experiments with this. It doesn't seem easy to decode that 30/34 bit structure in JavaScript without putting almost every bit manually where it belongs. Do you have any code public to have a look at it while I'm writing a workaround?

Update: This seems to work for 8-byte-values: (I have only checked it down to the seconds)

if (time.type === 255 && time.buffer.length === 8) {
    var ns = (message.data.time.buffer[0] << 22) +
        (message.data.time.buffer[1] << 14) +
        (message.data.time.buffer[2] << 6) +
        (message.data.time.buffer[3] >> 2);
    var sec = ((message.data.time.buffer[3] & 0x3) << 32) +
        (message.data.time.buffer[4] << 24) +
        (message.data.time.buffer[5] << 16) +
        (message.data.time.buffer[6] << 8) +
        message.data.time.buffer[7];
    time = new Date(sec * 1000 + ns / 1000000);
}

ygoe avatar May 09 '18 18:05 ygoe

Revisited this. Here's my code that should be able to decode all three timestamp formats. It only handles a single value deserialised from MessagePack. It needs to be integrated into the deserialiser to work transparently on all data.

JavaScript can be a beast when it comes to numeric data. Hence all the funny extra bitwise operators and DWORD pairs in there. Learned a thing or two today.

I'm currently writing my own little MessagePack codec in JavaScript. The encoder is complete as of today (incl. timestamp support) and has only 250 loc. The whole thing should reach 1/10th of the size of this library. I can't say anything about its performance yet though.

var data = msgpack.decode(array);
if (data.type === 255) {
    switch (data.buffer.length) {
        case 4:
            let sec = ((data.buffer[0] << 24) >>> 0) +
                ((data.buffer[1] << 16) >>> 0) +
                ((data.buffer[2] << 8) >>> 0) +
                data.buffer[3];
            console.log("sec", sec);
            data = new Date(sec * 1000);
            break;
        case 8:
            let ns = ((data.buffer[0] << 22) >>> 0) +
                ((data.buffer[1] << 14) >>> 0) +
                ((data.buffer[2] << 6) >>> 0) +
                (data.buffer[3] >>> 2);
            let pow32 = 0x100000000;   // 2^32
            let sec = ((data.buffer[3] & 0x3) * pow32) +
                ((data.buffer[4] << 24) >>> 0) +
                ((data.buffer[5] << 16) >>> 0) +
                ((data.buffer[6] << 8) >>> 0) +
                data.buffer[7];
            console.log("sec", sec, "ns", ns);
            data = new Date(sec * 1000 + ns / 1000000);
            break;
        case 12:
            let ns = ((data.buffer[0] << 24) >>> 0) +
                ((data.buffer[1] << 16) >>> 0) +
                ((data.buffer[2] << 8) >>> 0) +
                data.buffer[3];
            let pow32 = 0x100000000;   // 2^32
            let hi = ((data.buffer[4] << 24) >>> 0) +
                ((data.buffer[5] << 16) >>> 0) +
                ((data.buffer[6] << 8) >>> 0) +
                data.buffer[7];
            let lo = ((data.buffer[8] << 24) >>> 0) +
                ((data.buffer[9] << 16) >>> 0) +
                ((data.buffer[10] << 8) >>> 0) +
                data.buffer[11];
            let sec = hi * pow32 + lo;
            console.log("sec", sec, "ns", ns);
            data = new Date(sec * 1000 + ns / 1000000);
            break;
        default:
            throw "Unsupported timestamp data length.";
    }
}

(Warning: I have rearranged this code for showing it here. This exact code is untested.)

ygoe avatar Jun 11 '18 20:06 ygoe

Just for information and maybe a reference implementation, I have now published my MessagePack codec for JavaScript: https://github.com/ygoe/msgpack.js

ygoe avatar Jul 23 '18 09:07 ygoe