UNPKG

protocol-buffers-encodings

Version:
288 lines (252 loc) 6.49 kB
var varint = require('varint') var svarint = require('signed-varint') var b4a = require('b4a') exports.make = encoder exports.name = function (enc) { var keys = Object.keys(exports) for (var i = 0; i < keys.length; i++) { if (exports[keys[i]] === enc) return keys[i] } return null } exports.skip = function (type, buffer, offset) { switch (type) { case 0: varint.decode(buffer, offset) return offset + varint.decode.bytes case 1: return offset + 8 case 2: var len = varint.decode(buffer, offset) return offset + varint.decode.bytes + len case 3: case 4: throw new Error('Groups are not supported') case 5: return offset + 4 } throw new Error('Unknown wire type: ' + type) } exports.bytes = encoder(2, function encode (val, buffer, offset) { var oldOffset = offset var len = bufferLength(val) varint.encode(len, buffer, offset) offset += varint.encode.bytes if (b4a.isBuffer(val)) b4a.copy(val, buffer, offset) else b4a.write(buffer, val, offset, len) offset += len encode.bytes = offset - oldOffset return buffer }, function decode (buffer, offset) { var oldOffset = offset var len = varint.decode(buffer, offset) offset += varint.decode.bytes var val = buffer.subarray(offset, offset + len) offset += val.length decode.bytes = offset - oldOffset return val }, function encodingLength (val) { var len = bufferLength(val) return varint.encodingLength(len) + len } ) exports.string = encoder(2, function encode (val, buffer, offset) { var oldOffset = offset var len = b4a.byteLength(val) varint.encode(len, buffer, offset, 'utf-8') offset += varint.encode.bytes b4a.write(buffer, val, offset, len) offset += len encode.bytes = offset - oldOffset return buffer }, function decode (buffer, offset) { var oldOffset = offset var len = varint.decode(buffer, offset) offset += varint.decode.bytes var val = b4a.toString(buffer, 'utf-8', offset, offset + len) offset += len decode.bytes = offset - oldOffset return val }, function encodingLength (val) { var len = b4a.byteLength(val) return varint.encodingLength(len) + len } ) exports.bool = encoder(0, function encode (val, buffer, offset) { buffer[offset] = val ? 1 : 0 encode.bytes = 1 return buffer }, function decode (buffer, offset) { var bool = buffer[offset] > 0 decode.bytes = 1 return bool }, function encodingLength () { return 1 } ) exports.int32 = encoder(0, function encode (val, buffer, offset) { varint.encode(val < 0 ? val + 4294967296 : val, buffer, offset) encode.bytes = varint.encode.bytes return buffer }, function decode (buffer, offset) { var val = varint.decode(buffer, offset) decode.bytes = varint.decode.bytes return val > 2147483647 ? val - 4294967296 : val }, function encodingLength (val) { return varint.encodingLength(val < 0 ? val + 4294967296 : val) } ) exports.int64 = encoder(0, function encode (val, buffer, offset) { if (val < 0) { var last = offset + 9 varint.encode(val * -1, buffer, offset) offset += varint.encode.bytes - 1 buffer[offset] = buffer[offset] | 0x80 while (offset < last - 1) { offset++ buffer[offset] = 0xff } buffer[last] = 0x01 encode.bytes = 10 } else { varint.encode(val, buffer, offset) encode.bytes = varint.encode.bytes } return buffer }, function decode (buffer, offset) { var val = varint.decode(buffer, offset) if (val >= Math.pow(2, 63)) { var limit = 9 while (buffer[offset + limit - 1] === 0xff) limit-- limit = limit || 9 var subset = b4a.allocUnsafe(limit) b4a.copy(buffer, subset, 0, offset, offset + limit) subset[limit - 1] = subset[limit - 1] & 0x7f val = -1 * varint.decode(subset, 0) decode.bytes = 10 } else { decode.bytes = varint.decode.bytes } return val }, function encodingLength (val) { return val < 0 ? 10 : varint.encodingLength(val) } ) exports.sint32 = exports.sint64 = encoder(0, svarint.encode, svarint.decode, svarint.encodingLength ) exports.uint32 = exports.uint64 = exports.enum = exports.varint = encoder(0, varint.encode, varint.decode, varint.encodingLength ) // we cannot represent these in javascript so we just use buffers exports.fixed64 = exports.sfixed64 = encoder(1, function encode (val, buffer, offset) { b4a.copy(val, buffer, offset) encode.bytes = 8 return buffer }, function decode (buffer, offset) { var val = buffer.subarray(offset, offset + 8) decode.bytes = 8 return val }, function encodingLength () { return 8 } ) exports.double = encoder(1, function encode (val, buffer, offset) { b4a.writeDoubleLE(buffer, val, offset) encode.bytes = 8 return buffer }, function decode (buffer, offset) { var val = b4a.readDoubleLE(buffer, offset) decode.bytes = 8 return val }, function encodingLength () { return 8 } ) exports.fixed32 = encoder(5, function encode (val, buffer, offset) { b4a.writeUInt32LE(buffer, val, offset) encode.bytes = 4 return buffer }, function decode (buffer, offset) { var val = b4a.readUInt32LE(buffer, offset) decode.bytes = 4 return val }, function encodingLength () { return 4 } ) exports.sfixed32 = encoder(5, function encode (val, buffer, offset) { b4a.writeInt32LE(buffer, val, offset) encode.bytes = 4 return buffer }, function decode (buffer, offset) { var val = b4a.readInt32LE(buffer, offset) decode.bytes = 4 return val }, function encodingLength () { return 4 } ) exports.float = encoder(5, function encode (val, buffer, offset) { b4a.writeFloatLE(buffer, val, offset) encode.bytes = 4 return buffer }, function decode (buffer, offset) { var val = b4a.readFloatLE(buffer, offset) decode.bytes = 4 return val }, function encodingLength () { return 4 } ) function encoder (type, encode, decode, encodingLength) { encode.bytes = decode.bytes = 0 return { type: type, encode: encode, decode: decode, encodingLength: encodingLength } } function bufferLength (val) { return b4a.isBuffer(val) ? val.length : b4a.byteLength(val) }