|
1 | 1 | const { getCount, sendCount, calcCount, PartialReadError } = require('../utils')
|
2 | 2 |
|
3 | 3 | module.exports = {
|
4 |
| - varint: [readVarInt, writeVarInt, sizeOfVarInt, require('../../ProtoDef/schemas/utils.json').varint], |
5 | 4 | bool: [readBool, writeBool, 1, require('../../ProtoDef/schemas/utils.json').bool],
|
6 | 5 | pstring: [readPString, writePString, sizeOfPString, require('../../ProtoDef/schemas/utils.json').pstring],
|
7 | 6 | buffer: [readBuffer, writeBuffer, sizeOfBuffer, require('../../ProtoDef/schemas/utils.json').buffer],
|
8 | 7 | void: [readVoid, writeVoid, 0, require('../../ProtoDef/schemas/utils.json').void],
|
9 | 8 | bitfield: [readBitField, writeBitField, sizeOfBitField, require('../../ProtoDef/schemas/utils.json').bitfield],
|
| 9 | + bitflags: [readBitflags, writeBitflags, sizeOfBitflags, require('../../ProtoDef/schemas/utils.json').bitflags], |
10 | 10 | cstring: [readCString, writeCString, sizeOfCString, require('../../ProtoDef/schemas/utils.json').cstring],
|
11 |
| - mapper: [readMapper, writeMapper, sizeOfMapper, require('../../ProtoDef/schemas/utils.json').mapper] |
| 11 | + mapper: [readMapper, writeMapper, sizeOfMapper, require('../../ProtoDef/schemas/utils.json').mapper], |
| 12 | + ...require('./varint') |
12 | 13 | }
|
13 | 14 |
|
14 | 15 | function mapperEquality (a, b) {
|
@@ -58,47 +59,6 @@ function sizeOfMapper (value, { type, mappings }, rootNode) {
|
58 | 59 | return this.sizeOf(mappedValue, type, rootNode)
|
59 | 60 | }
|
60 | 61 |
|
61 |
| -function readVarInt (buffer, offset) { |
62 |
| - let result = 0 |
63 |
| - let shift = 0 |
64 |
| - let cursor = offset |
65 |
| - |
66 |
| - while (true) { |
67 |
| - if (cursor + 1 > buffer.length) { throw new PartialReadError() } |
68 |
| - const b = buffer.readUInt8(cursor) |
69 |
| - result |= ((b & 0x7f) << shift) // Add the bits to our number, except MSB |
70 |
| - cursor++ |
71 |
| - if (!(b & 0x80)) { // If the MSB is not set, we return the number |
72 |
| - return { |
73 |
| - value: result, |
74 |
| - size: cursor - offset |
75 |
| - } |
76 |
| - } |
77 |
| - shift += 7 // we only have 7 bits, MSB being the return-trigger |
78 |
| - if (shift > 64) throw new PartialReadError(`varint is too big: ${shift}`) // Make sure our shift don't overflow. |
79 |
| - } |
80 |
| -} |
81 |
| - |
82 |
| -function sizeOfVarInt (value) { |
83 |
| - let cursor = 0 |
84 |
| - while (value & ~0x7F) { |
85 |
| - value >>>= 7 |
86 |
| - cursor++ |
87 |
| - } |
88 |
| - return cursor + 1 |
89 |
| -} |
90 |
| - |
91 |
| -function writeVarInt (value, buffer, offset) { |
92 |
| - let cursor = 0 |
93 |
| - while (value & ~0x7F) { |
94 |
| - buffer.writeUInt8((value & 0xFF) | 0x80, offset + cursor) |
95 |
| - cursor++ |
96 |
| - value >>>= 7 |
97 |
| - } |
98 |
| - buffer.writeUInt8(value, offset + cursor) |
99 |
| - return offset + cursor + 1 |
100 |
| -} |
101 |
| - |
102 | 62 | function readPString (buffer, offset, typeArgs, rootNode) {
|
103 | 63 | const { size, count } = getCount.call(this, buffer, offset, typeArgs, rootNode)
|
104 | 64 | const cursor = offset + size
|
@@ -258,3 +218,65 @@ function sizeOfCString (value) {
|
258 | 218 | const length = Buffer.byteLength(value, 'utf8')
|
259 | 219 | return length + 1
|
260 | 220 | }
|
| 221 | + |
| 222 | +function readBitflags (buffer, offset, { type, flags, shift, big }, rootNode) { |
| 223 | + const { size, value } = this.read(buffer, offset, type, rootNode) |
| 224 | + let f = {} |
| 225 | + if (Array.isArray(flags)) { |
| 226 | + for (const [k, v] of Object.entries(flags)) { |
| 227 | + f[v] = big ? (1n << BigInt(k)) : (1 << k) |
| 228 | + } |
| 229 | + } else if (shift) { |
| 230 | + for (const k in flags) { |
| 231 | + f[k] = big ? (1n << BigInt(flags[k])) : (1 << flags[k]) |
| 232 | + } |
| 233 | + } else { |
| 234 | + f = flags |
| 235 | + } |
| 236 | + const result = { _value: value } |
| 237 | + for (const key in f) { |
| 238 | + result[key] = (value & f[key]) === f[key] |
| 239 | + } |
| 240 | + return { value: result, size } |
| 241 | +} |
| 242 | + |
| 243 | +function writeBitflags (value, buffer, offset, { type, flags, shift, big }, rootNode) { |
| 244 | + let f = {} |
| 245 | + if (Array.isArray(flags)) { |
| 246 | + for (const [k, v] of Object.entries(flags)) { |
| 247 | + f[v] = big ? (1n << BigInt(k)) : (1 << k) |
| 248 | + } |
| 249 | + } else if (shift) { |
| 250 | + for (const k in flags) { |
| 251 | + f[k] = big ? (1n << BigInt(flags[k])) : (1 << flags[k]) |
| 252 | + } |
| 253 | + } else { |
| 254 | + f = flags |
| 255 | + } |
| 256 | + let val = value._value || (big ? 0n : 0) |
| 257 | + for (const key in f) { |
| 258 | + if (value[key]) val |= f[key] |
| 259 | + } |
| 260 | + return this.write(val, buffer, offset, type, rootNode) |
| 261 | +} |
| 262 | + |
| 263 | +function sizeOfBitflags (value, { type, flags, shift, big }, rootNode) { |
| 264 | + if (!value) throw new Error('Missing field') |
| 265 | + let f = {} |
| 266 | + if (Array.isArray(flags)) { |
| 267 | + for (const [k, v] of Object.entries(flags)) { |
| 268 | + f[v] = big ? (1n << BigInt(k)) : (1 << k) |
| 269 | + } |
| 270 | + } else if (shift) { |
| 271 | + for (const k in flags) { |
| 272 | + f[k] = big ? (1n << BigInt(flags[k])) : (1 << flags[k]) |
| 273 | + } |
| 274 | + } else { |
| 275 | + f = flags |
| 276 | + } |
| 277 | + let mappedValue = value._value || (big ? 0n : 0) |
| 278 | + for (const key in f) { |
| 279 | + if (value[key]) mappedValue |= f[key] |
| 280 | + } |
| 281 | + return this.sizeOf(mappedValue, type, rootNode) |
| 282 | +} |
0 commit comments