228 lines
5.9 KiB
JavaScript
228 lines
5.9 KiB
JavaScript
// write-token.js
|
|
|
|
var ieee754 = require("ieee754");
|
|
var Int64Buffer = require("int64-buffer");
|
|
var Uint64BE = Int64Buffer.Uint64BE;
|
|
var Int64BE = Int64Buffer.Int64BE;
|
|
|
|
var uint8 = require("./write-uint8").uint8;
|
|
var Bufferish = require("./bufferish");
|
|
var Buffer = Bufferish.global;
|
|
var IS_BUFFER_SHIM = Bufferish.hasBuffer && ("TYPED_ARRAY_SUPPORT" in Buffer);
|
|
var NO_TYPED_ARRAY = IS_BUFFER_SHIM && !Buffer.TYPED_ARRAY_SUPPORT;
|
|
var Buffer_prototype = Bufferish.hasBuffer && Buffer.prototype || {};
|
|
|
|
exports.getWriteToken = getWriteToken;
|
|
|
|
function getWriteToken(options) {
|
|
if (options && options.uint8array) {
|
|
return init_uint8array();
|
|
} else if (NO_TYPED_ARRAY || (Bufferish.hasBuffer && options && options.safe)) {
|
|
return init_safe();
|
|
} else {
|
|
return init_token();
|
|
}
|
|
}
|
|
|
|
function init_uint8array() {
|
|
var token = init_token();
|
|
|
|
// float 32 -- 0xca
|
|
// float 64 -- 0xcb
|
|
token[0xca] = writeN(0xca, 4, writeFloatBE);
|
|
token[0xcb] = writeN(0xcb, 8, writeDoubleBE);
|
|
|
|
return token;
|
|
}
|
|
|
|
// Node.js and browsers with TypedArray
|
|
|
|
function init_token() {
|
|
// (immediate values)
|
|
// positive fixint -- 0x00 - 0x7f
|
|
// nil -- 0xc0
|
|
// false -- 0xc2
|
|
// true -- 0xc3
|
|
// negative fixint -- 0xe0 - 0xff
|
|
var token = uint8.slice();
|
|
|
|
// bin 8 -- 0xc4
|
|
// bin 16 -- 0xc5
|
|
// bin 32 -- 0xc6
|
|
token[0xc4] = write1(0xc4);
|
|
token[0xc5] = write2(0xc5);
|
|
token[0xc6] = write4(0xc6);
|
|
|
|
// ext 8 -- 0xc7
|
|
// ext 16 -- 0xc8
|
|
// ext 32 -- 0xc9
|
|
token[0xc7] = write1(0xc7);
|
|
token[0xc8] = write2(0xc8);
|
|
token[0xc9] = write4(0xc9);
|
|
|
|
// float 32 -- 0xca
|
|
// float 64 -- 0xcb
|
|
token[0xca] = writeN(0xca, 4, (Buffer_prototype.writeFloatBE || writeFloatBE), true);
|
|
token[0xcb] = writeN(0xcb, 8, (Buffer_prototype.writeDoubleBE || writeDoubleBE), true);
|
|
|
|
// uint 8 -- 0xcc
|
|
// uint 16 -- 0xcd
|
|
// uint 32 -- 0xce
|
|
// uint 64 -- 0xcf
|
|
token[0xcc] = write1(0xcc);
|
|
token[0xcd] = write2(0xcd);
|
|
token[0xce] = write4(0xce);
|
|
token[0xcf] = writeN(0xcf, 8, writeUInt64BE);
|
|
|
|
// int 8 -- 0xd0
|
|
// int 16 -- 0xd1
|
|
// int 32 -- 0xd2
|
|
// int 64 -- 0xd3
|
|
token[0xd0] = write1(0xd0);
|
|
token[0xd1] = write2(0xd1);
|
|
token[0xd2] = write4(0xd2);
|
|
token[0xd3] = writeN(0xd3, 8, writeInt64BE);
|
|
|
|
// str 8 -- 0xd9
|
|
// str 16 -- 0xda
|
|
// str 32 -- 0xdb
|
|
token[0xd9] = write1(0xd9);
|
|
token[0xda] = write2(0xda);
|
|
token[0xdb] = write4(0xdb);
|
|
|
|
// array 16 -- 0xdc
|
|
// array 32 -- 0xdd
|
|
token[0xdc] = write2(0xdc);
|
|
token[0xdd] = write4(0xdd);
|
|
|
|
// map 16 -- 0xde
|
|
// map 32 -- 0xdf
|
|
token[0xde] = write2(0xde);
|
|
token[0xdf] = write4(0xdf);
|
|
|
|
return token;
|
|
}
|
|
|
|
// safe mode: for old browsers and who needs asserts
|
|
|
|
function init_safe() {
|
|
// (immediate values)
|
|
// positive fixint -- 0x00 - 0x7f
|
|
// nil -- 0xc0
|
|
// false -- 0xc2
|
|
// true -- 0xc3
|
|
// negative fixint -- 0xe0 - 0xff
|
|
var token = uint8.slice();
|
|
|
|
// bin 8 -- 0xc4
|
|
// bin 16 -- 0xc5
|
|
// bin 32 -- 0xc6
|
|
token[0xc4] = writeN(0xc4, 1, Buffer.prototype.writeUInt8);
|
|
token[0xc5] = writeN(0xc5, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xc6] = writeN(0xc6, 4, Buffer.prototype.writeUInt32BE);
|
|
|
|
// ext 8 -- 0xc7
|
|
// ext 16 -- 0xc8
|
|
// ext 32 -- 0xc9
|
|
token[0xc7] = writeN(0xc7, 1, Buffer.prototype.writeUInt8);
|
|
token[0xc8] = writeN(0xc8, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xc9] = writeN(0xc9, 4, Buffer.prototype.writeUInt32BE);
|
|
|
|
// float 32 -- 0xca
|
|
// float 64 -- 0xcb
|
|
token[0xca] = writeN(0xca, 4, Buffer.prototype.writeFloatBE);
|
|
token[0xcb] = writeN(0xcb, 8, Buffer.prototype.writeDoubleBE);
|
|
|
|
// uint 8 -- 0xcc
|
|
// uint 16 -- 0xcd
|
|
// uint 32 -- 0xce
|
|
// uint 64 -- 0xcf
|
|
token[0xcc] = writeN(0xcc, 1, Buffer.prototype.writeUInt8);
|
|
token[0xcd] = writeN(0xcd, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xce] = writeN(0xce, 4, Buffer.prototype.writeUInt32BE);
|
|
token[0xcf] = writeN(0xcf, 8, writeUInt64BE);
|
|
|
|
// int 8 -- 0xd0
|
|
// int 16 -- 0xd1
|
|
// int 32 -- 0xd2
|
|
// int 64 -- 0xd3
|
|
token[0xd0] = writeN(0xd0, 1, Buffer.prototype.writeInt8);
|
|
token[0xd1] = writeN(0xd1, 2, Buffer.prototype.writeInt16BE);
|
|
token[0xd2] = writeN(0xd2, 4, Buffer.prototype.writeInt32BE);
|
|
token[0xd3] = writeN(0xd3, 8, writeInt64BE);
|
|
|
|
// str 8 -- 0xd9
|
|
// str 16 -- 0xda
|
|
// str 32 -- 0xdb
|
|
token[0xd9] = writeN(0xd9, 1, Buffer.prototype.writeUInt8);
|
|
token[0xda] = writeN(0xda, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xdb] = writeN(0xdb, 4, Buffer.prototype.writeUInt32BE);
|
|
|
|
// array 16 -- 0xdc
|
|
// array 32 -- 0xdd
|
|
token[0xdc] = writeN(0xdc, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xdd] = writeN(0xdd, 4, Buffer.prototype.writeUInt32BE);
|
|
|
|
// map 16 -- 0xde
|
|
// map 32 -- 0xdf
|
|
token[0xde] = writeN(0xde, 2, Buffer.prototype.writeUInt16BE);
|
|
token[0xdf] = writeN(0xdf, 4, Buffer.prototype.writeUInt32BE);
|
|
|
|
return token;
|
|
}
|
|
|
|
function write1(type) {
|
|
return function(encoder, value) {
|
|
var offset = encoder.reserve(2);
|
|
var buffer = encoder.buffer;
|
|
buffer[offset++] = type;
|
|
buffer[offset] = value;
|
|
};
|
|
}
|
|
|
|
function write2(type) {
|
|
return function(encoder, value) {
|
|
var offset = encoder.reserve(3);
|
|
var buffer = encoder.buffer;
|
|
buffer[offset++] = type;
|
|
buffer[offset++] = value >>> 8;
|
|
buffer[offset] = value;
|
|
};
|
|
}
|
|
|
|
function write4(type) {
|
|
return function(encoder, value) {
|
|
var offset = encoder.reserve(5);
|
|
var buffer = encoder.buffer;
|
|
buffer[offset++] = type;
|
|
buffer[offset++] = value >>> 24;
|
|
buffer[offset++] = value >>> 16;
|
|
buffer[offset++] = value >>> 8;
|
|
buffer[offset] = value;
|
|
};
|
|
}
|
|
|
|
function writeN(type, len, method, noAssert) {
|
|
return function(encoder, value) {
|
|
var offset = encoder.reserve(len + 1);
|
|
encoder.buffer[offset++] = type;
|
|
method.call(encoder.buffer, value, offset, noAssert);
|
|
};
|
|
}
|
|
|
|
function writeUInt64BE(value, offset) {
|
|
new Uint64BE(this, offset, value);
|
|
}
|
|
|
|
function writeInt64BE(value, offset) {
|
|
new Int64BE(this, offset, value);
|
|
}
|
|
|
|
function writeFloatBE(value, offset) {
|
|
ieee754.write(this, value, offset, false, 23, 4);
|
|
}
|
|
|
|
function writeDoubleBE(value, offset) {
|
|
ieee754.write(this, value, offset, false, 52, 8);
|
|
}
|