UNPKG

@tamgl/colyseus-schema

Version:

Binary state serializer with delta encoding for games

237 lines 6.73 kB
"use strict"; /** * Copyright (c) 2018 Endel Dreyer * Copyright (c) 2014 Ion Drive Software Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE */ Object.defineProperty(exports, "__esModule", { value: true }); exports.decode = void 0; exports.stringCheck = stringCheck; // force little endian to facilitate decoding on multiple implementations const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; const _convoBuffer = new ArrayBuffer(8); const _int32 = new Int32Array(_convoBuffer); const _float32 = new Float32Array(_convoBuffer); const _float64 = new Float64Array(_convoBuffer); const _uint64 = new BigUint64Array(_convoBuffer); const _int64 = new BigInt64Array(_convoBuffer); function utf8Read(bytes, it, length) { var string = '', chr = 0; for (var i = it.offset, end = it.offset + length; i < end; i++) { var byte = bytes[i]; if ((byte & 0x80) === 0x00) { string += String.fromCharCode(byte); continue; } if ((byte & 0xe0) === 0xc0) { string += String.fromCharCode(((byte & 0x1f) << 6) | (bytes[++i] & 0x3f)); continue; } if ((byte & 0xf0) === 0xe0) { string += String.fromCharCode(((byte & 0x0f) << 12) | ((bytes[++i] & 0x3f) << 6) | ((bytes[++i] & 0x3f) << 0)); continue; } if ((byte & 0xf8) === 0xf0) { chr = ((byte & 0x07) << 18) | ((bytes[++i] & 0x3f) << 12) | ((bytes[++i] & 0x3f) << 6) | ((bytes[++i] & 0x3f) << 0); if (chr >= 0x010000) { // surrogate pair chr -= 0x010000; string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00); } else { string += String.fromCharCode(chr); } continue; } console.error('Invalid byte ' + byte.toString(16)); // (do not throw error to avoid server/client from crashing due to hack attemps) // throw new Error('Invalid byte ' + byte.toString(16)); } it.offset += length; return string; } function int8(bytes, it) { return uint8(bytes, it) << 24 >> 24; } ; function uint8(bytes, it) { return bytes[it.offset++]; } ; function int16(bytes, it) { return uint16(bytes, it) << 16 >> 16; } ; function uint16(bytes, it) { return bytes[it.offset++] | bytes[it.offset++] << 8; } ; function int32(bytes, it) { return bytes[it.offset++] | bytes[it.offset++] << 8 | bytes[it.offset++] << 16 | bytes[it.offset++] << 24; } ; function uint32(bytes, it) { return int32(bytes, it) >>> 0; } ; function float32(bytes, it) { _int32[0] = int32(bytes, it); return _float32[0]; } ; function float64(bytes, it) { _int32[_isLittleEndian ? 0 : 1] = int32(bytes, it); _int32[_isLittleEndian ? 1 : 0] = int32(bytes, it); return _float64[0]; } ; function int64(bytes, it) { const low = uint32(bytes, it); const high = int32(bytes, it) * Math.pow(2, 32); return high + low; } ; function uint64(bytes, it) { const low = uint32(bytes, it); const high = uint32(bytes, it) * Math.pow(2, 32); return high + low; } ; function bigint64(bytes, it) { _int32[0] = int32(bytes, it); _int32[1] = int32(bytes, it); return _int64[0]; } function biguint64(bytes, it) { _int32[0] = int32(bytes, it); _int32[1] = int32(bytes, it); return _uint64[0]; } function boolean(bytes, it) { return uint8(bytes, it) > 0; } ; function string(bytes, it) { const prefix = bytes[it.offset++]; let length; if (prefix < 0xc0) { // fixstr length = prefix & 0x1f; } else if (prefix === 0xd9) { length = uint8(bytes, it); } else if (prefix === 0xda) { length = uint16(bytes, it); } else if (prefix === 0xdb) { length = uint32(bytes, it); } return utf8Read(bytes, it, length); } function number(bytes, it) { const prefix = bytes[it.offset++]; if (prefix < 0x80) { // positive fixint return prefix; } else if (prefix === 0xca) { // float 32 return float32(bytes, it); } else if (prefix === 0xcb) { // float 64 return float64(bytes, it); } else if (prefix === 0xcc) { // uint 8 return uint8(bytes, it); } else if (prefix === 0xcd) { // uint 16 return uint16(bytes, it); } else if (prefix === 0xce) { // uint 32 return uint32(bytes, it); } else if (prefix === 0xcf) { // uint 64 return uint64(bytes, it); } else if (prefix === 0xd0) { // int 8 return int8(bytes, it); } else if (prefix === 0xd1) { // int 16 return int16(bytes, it); } else if (prefix === 0xd2) { // int 32 return int32(bytes, it); } else if (prefix === 0xd3) { // int 64 return int64(bytes, it); } else if (prefix > 0xdf) { // negative fixint return (0xff - prefix + 1) * -1; } } ; function stringCheck(bytes, it) { const prefix = bytes[it.offset]; return ( // fixstr (prefix < 0xc0 && prefix > 0xa0) || // str 8 prefix === 0xd9 || // str 16 prefix === 0xda || // str 32 prefix === 0xdb); } exports.decode = { utf8Read, int8, uint8, int16, uint16, int32, uint32, float32, float64, int64, uint64, bigint64, biguint64, boolean, string, number, stringCheck, }; //# sourceMappingURL=decode.js.map