Comparing version 1.14.0 to 1.15.0
# History | ||
## 1.15.0 | ||
* Fix 64-bit BigInt sign handling (@extremeheat) | ||
* Add string encoding option (@extremeheat) | ||
* Show BigInt instead of BigIntExtended when using console.log (@extremeheat) | ||
## 1.14.0 | ||
@@ -4,0 +10,0 @@ |
{ | ||
"name": "protodef", | ||
"version": "1.14.0", | ||
"version": "1.15.0", | ||
"description": "A simple yet powerful way to define binary protocols", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -11,6 +11,15 @@ ## Primitives | ||
### **cstring** ( ) | ||
Arguments: None | ||
Arguments: encoding | ||
Represents a null terminated string. Similar to strings in C. | ||
Assumes UTF-8 encoding by default | ||
Example: | ||
Example: A string length prefixed by a varint. | ||
```json | ||
[ | ||
"cstring", { "encoding": "utf-16" } | ||
] | ||
``` | ||
Example of value: `"my string"` | ||
@@ -17,0 +26,0 @@ |
@@ -77,2 +77,3 @@ ## Utils | ||
* count : optional (either count or countType), a reference to the field counting the elements, or a fixed size (an integer) | ||
* encoding: the encoding of the string, UTF-8 by default | ||
@@ -84,5 +85,5 @@ Represents a string. | ||
[ | ||
"pstring", { "countType": "varint" } | ||
"pstring", { "countType": "varint", "encoding": "utf-8" } | ||
] | ||
``` | ||
Example of value: `"my string"` | ||
Example of value: `"my string"` |
@@ -6,3 +6,18 @@ { | ||
"cstring": { | ||
"enum": ["cstring"] | ||
"items": [ | ||
{ | ||
"enum": ["cstring"] | ||
}, | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"encoding": { | ||
"type": "string" | ||
} | ||
}, | ||
"additionalProperties": false, | ||
"required": [] | ||
} | ||
], | ||
"additionalItems": false | ||
}, | ||
@@ -9,0 +24,0 @@ "void": { |
@@ -16,2 +16,5 @@ { | ||
"$ref": "dataType" | ||
}, | ||
"encoding": { | ||
"type": "string" | ||
} | ||
@@ -27,2 +30,5 @@ }, | ||
"$ref": "definitions#/definitions/dataTypeArgsCount" | ||
}, | ||
"encoding": { | ||
"type": "string" | ||
} | ||
@@ -29,0 +35,0 @@ }, |
@@ -17,3 +17,3 @@ module.exports = { | ||
code += '}\n' | ||
code += 'return { value: buffer.toString(\'utf8\', offset, offset + count), size: count + countSize }' | ||
code += `return { value: buffer.toString("${string.encoding || 'utf8'}", offset, offset + count), size: count + countSize }` | ||
return compiler.wrapCode(code) | ||
@@ -71,3 +71,3 @@ }], | ||
pstring: ['parametrizable', (compiler, string) => { | ||
let code = 'const length = Buffer.byteLength(value, \'utf8\')\n' | ||
let code = `const length = Buffer.byteLength(value, "${string.encoding || 'utf8'}")\n` | ||
if (string.countType) { | ||
@@ -78,3 +78,3 @@ code += 'offset = ' + compiler.callType('length', string.countType) + '\n' | ||
} | ||
code += 'buffer.write(value, offset, length, \'utf8\')\n' | ||
code += `buffer.write(value, offset, length, "${string.encoding || 'utf8'}")\n` | ||
code += 'return offset + length' | ||
@@ -131,3 +131,3 @@ return compiler.wrapCode(code) | ||
pstring: ['parametrizable', (compiler, string) => { | ||
let code = 'let size = Buffer.byteLength(value, \'utf8\')\n' | ||
let code = `let size = Buffer.byteLength(value, "${string.encoding || 'utf8'}")\n` | ||
if (string.countType) { | ||
@@ -134,0 +134,0 @@ code += 'size += ' + compiler.callType('size', string.countType) + '\n' |
const { PartialReadError } = require('../utils') | ||
class BigIntExtended extends Array { | ||
class SignedBigInt extends Array { | ||
valueOf () { return BigInt.asIntN(64, BigInt(this[0]) << 32n) | BigInt.asUintN(32, BigInt(this[1])) } | ||
toString () { return this.valueOf().toString() } | ||
[Symbol.for('nodejs.util.inspect.custom')] () { return this.valueOf() } | ||
} | ||
class UnsignedBigInt extends Array { | ||
valueOf () { return BigInt.asUintN(64, BigInt(this[0]) << 32n) | BigInt.asUintN(32, BigInt(this[1])) } | ||
toString () { return this.valueOf().toString() } | ||
[Symbol.for('nodejs.util.inspect.custom')] () { return this.valueOf() } | ||
} | ||
function readI64 (buffer, offset) { | ||
if (offset + 8 > buffer.length) { throw new PartialReadError() } | ||
return { | ||
value: new BigIntExtended(buffer.readInt32BE(offset), buffer.readInt32BE(offset + 4)), | ||
value: new SignedBigInt(buffer.readInt32BE(offset), buffer.readInt32BE(offset + 4)), | ||
size: 8 | ||
@@ -28,3 +36,3 @@ } | ||
return { | ||
value: new BigIntExtended(buffer.readInt32LE(offset + 4), buffer.readInt32LE(offset)), | ||
value: new SignedBigInt(buffer.readInt32LE(offset + 4), buffer.readInt32LE(offset)), | ||
size: 8 | ||
@@ -47,3 +55,3 @@ } | ||
return { | ||
value: new BigIntExtended(buffer.readUInt32BE(offset), buffer.readUInt32BE(offset + 4)), | ||
value: new UnsignedBigInt(buffer.readUInt32BE(offset), buffer.readUInt32BE(offset + 4)), | ||
size: 8 | ||
@@ -66,3 +74,3 @@ } | ||
return { | ||
value: new BigIntExtended(buffer.readUInt32LE(offset + 4), buffer.readUInt32LE(offset)), | ||
value: new UnsignedBigInt(buffer.readUInt32LE(offset + 4), buffer.readUInt32LE(offset)), | ||
size: 8 | ||
@@ -69,0 +77,0 @@ } |
@@ -114,3 +114,3 @@ const assert = require('assert') | ||
return { | ||
value: buffer.toString('utf8', cursor, strEnd), | ||
value: buffer.toString(typeArgs.encoding || 'utf8', cursor, strEnd), | ||
size: strEnd - offset | ||
@@ -123,3 +123,3 @@ } | ||
offset = sendCount.call(this, length, buffer, offset, typeArgs, rootNode) | ||
buffer.write(value, offset, length, 'utf8') | ||
buffer.write(value, offset, length, typeArgs.encoding || 'utf8') | ||
return offset + length | ||
@@ -129,3 +129,3 @@ } | ||
function sizeOfPString (value, typeArgs, rootNode) { | ||
const length = Buffer.byteLength(value, 'utf8') | ||
const length = Buffer.byteLength(value, typeArgs.encoding || 'utf8') | ||
const size = calcCount.call(this, length, typeArgs, rootNode) | ||
@@ -243,3 +243,3 @@ return size + length | ||
function readCString (buffer, offset) { | ||
function readCString (buffer, offset, typeArgs) { | ||
let size = 0 | ||
@@ -250,3 +250,3 @@ while (offset + size < buffer.length && buffer[offset + size] !== 0x00) { size++ } | ||
return { | ||
value: buffer.toString('utf8', offset, offset + size), | ||
value: buffer.toString(typeArgs?.encoding || 'utf8', offset, offset + size), | ||
size: size + 1 | ||
@@ -256,5 +256,5 @@ } | ||
function writeCString (value, buffer, offset) { | ||
const length = Buffer.byteLength(value, 'utf8') | ||
buffer.write(value, offset, length, 'utf8') | ||
function writeCString (value, buffer, offset, typeArgs) { | ||
const length = Buffer.byteLength(value, typeArgs?.encoding || 'utf8') | ||
buffer.write(value, offset, length, typeArgs?.encoding || 'utf8') | ||
offset += length | ||
@@ -261,0 +261,0 @@ buffer.writeInt8(0x00, offset) |
@@ -27,2 +27,13 @@ /* eslint-env mocha */ | ||
}) | ||
if (type === 'i64' || type === 'u64') { | ||
it('reads bigint correctly ' + type, function () { | ||
const [top, lower] = value.map(BigInt) | ||
const joined = type === 'i64' ? BigInt.asIntN(64, (top << 32n) | lower) : BigInt.asUintN(64, (top << 32n) | lower) | ||
// read | ||
const actualResult = proto.parsePacketBuffer(type, buffer) | ||
expect(actualResult.data.valueOf() === joined) | ||
expect(actualResult.metadata.size).to.deep.equal(buffer.length) | ||
}) | ||
} | ||
} | ||
@@ -29,0 +40,0 @@ |
168718
4636