123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.CompressionTable = void 0;
- const JsonPackExtension_1 = require("../JsonPackExtension");
- const isSafeInteger = Number.isSafeInteger;
- class CompressionTable {
- constructor() {
- this.integers = new Set();
- this.nonIntegers = new Set();
- this.table = [];
- this.map = new Map();
- }
- static create(value) {
- const table = new CompressionTable();
- table.walk(value);
- table.finalize();
- return table;
- }
- addInteger(int) {
- this.integers.add(int);
- }
- addLiteral(value) {
- if (isSafeInteger(value)) {
- this.addInteger(value);
- return;
- }
- this.nonIntegers.add(value);
- }
- walk(value) {
- switch (typeof value) {
- case 'object': {
- if (!value)
- return this.addLiteral(null);
- const constructor = value.constructor;
- switch (constructor) {
- case Object: {
- const obj = value;
- for (const key in obj) {
- this.addLiteral(key);
- this.walk(obj[key]);
- }
- break;
- }
- case Array: {
- const arr = value;
- const len = arr.length;
- for (let i = 0; i < len; i++)
- this.walk(arr[i]);
- break;
- }
- case Map: {
- const map = value;
- map.forEach((value, key) => {
- this.walk(key);
- this.walk(value);
- });
- break;
- }
- case Set: {
- const set = value;
- set.forEach((value) => {
- this.walk(value);
- });
- break;
- }
- case JsonPackExtension_1.JsonPackExtension: {
- const ext = value;
- this.addInteger(ext.tag);
- this.walk(ext.val);
- }
- }
- return;
- }
- default:
- return this.addLiteral(value);
- }
- }
- finalize() {
- const integers = Array.from(this.integers);
- integers.sort((a, b) => a - b);
- const len = integers.length;
- const table = this.table;
- const map = this.map;
- if (len > 0) {
- const first = integers[0];
- table.push(first);
- map.set(first, 0);
- let last = first;
- for (let i = 1; i < len; i++) {
- const int = integers[i];
- table.push(int - last);
- map.set(int, i);
- last = int;
- }
- }
- const nonIntegers = Array.from(this.nonIntegers);
- nonIntegers.sort();
- const lenNonIntegers = nonIntegers.length;
- for (let i = 0; i < lenNonIntegers; i++) {
- const value = nonIntegers[i];
- table.push(value);
- map.set(value, len + i);
- }
- this.integers.clear();
- this.nonIntegers.clear();
- }
- getIndex(value) {
- const index = this.map.get(value);
- if (index === undefined)
- throw new Error(`Value [${value}] not found in compression table.`);
- return index;
- }
- getTable() {
- return this.table;
- }
- compress(value) {
- switch (typeof value) {
- case 'object': {
- if (!value)
- return this.getIndex(null);
- const constructor = value.constructor;
- switch (constructor) {
- case Object: {
- const obj = value;
- const newObj = {};
- for (const key in obj)
- newObj[this.getIndex(key)] = this.compress(obj[key]);
- return newObj;
- }
- case Array: {
- const arr = value;
- const newArr = [];
- const len = arr.length;
- for (let i = 0; i < len; i++)
- newArr.push(this.compress(arr[i]));
- return newArr;
- }
- case Map: {
- const map = value;
- const newMap = new Map();
- map.forEach((value, key) => {
- newMap.set(this.compress(key), this.compress(value));
- });
- return newMap;
- }
- case Set: {
- const set = value;
- const newSet = new Set();
- set.forEach((value) => {
- newSet.add(this.compress(value));
- });
- break;
- }
- case JsonPackExtension_1.JsonPackExtension: {
- const ext = value;
- const newExt = new JsonPackExtension_1.JsonPackExtension(this.getIndex(ext.tag), this.compress(ext.val));
- return newExt;
- }
- }
- throw new Error('UNEXPECTED_OBJECT');
- }
- default: {
- return this.getIndex(value);
- }
- }
- }
- }
- exports.CompressionTable = CompressionTable;
- //# sourceMappingURL=CompressionTable.js.map
|