|
29 | 29 |
|
30 | 30 | // The dictionary
|
31 | 31 | var dictionary = {
|
32 |
| - strings : [], |
33 |
| - integers : [], |
34 |
| - floats : [] |
| 32 | + strings : {}, |
| 33 | + integers : {}, |
| 34 | + floats : {}, |
| 35 | + stringsLen: 0, |
| 36 | + integersLen: 0, |
| 37 | + floatsLen: 0 |
35 | 38 | };
|
36 | 39 |
|
37 | 40 | verbose && console.log('Creating the AST');
|
|
110 | 113 |
|
111 | 114 | // Case 4: The item is String
|
112 | 115 | if (type === 'string') {
|
113 |
| - |
| 116 | + item = _encode(item); |
114 | 117 | // The index of that word in the dictionary
|
115 |
| - var index = _indexOf.call(dictionary.strings, item); |
116 |
| - |
117 |
| - // If not, add to the dictionary and actualize the index |
118 |
| - if (index == -1) { |
119 |
| - dictionary.strings.push(_encode(item)); |
120 |
| - index = dictionary.strings.length - 1; |
| 118 | + if (item in dictionary.strings) { |
| 119 | + // Return the token |
| 120 | + return { |
| 121 | + type : 'strings', |
| 122 | + index : dictionary.strings[item] |
| 123 | + } |
| 124 | + } else { |
| 125 | + // If not, add to the dictionary and actualize the index |
| 126 | + var index = dictionary.stringsLen; |
| 127 | + dictionary.strings[item] = index; |
| 128 | + dictionary.stringsLen += 1; |
| 129 | + // Return the token |
| 130 | + return { |
| 131 | + type : 'strings', |
| 132 | + index : index |
| 133 | + } |
121 | 134 | }
|
122 |
| - |
123 |
| - // Return the token |
124 |
| - return { |
125 |
| - type : 'strings', |
126 |
| - index : index |
127 |
| - }; |
128 | 135 | }
|
129 | 136 |
|
130 | 137 | // Case 5: The item is integer
|
131 | 138 | if (type === 'number' && item % 1 === 0) {
|
132 |
| - |
| 139 | + item = _base10To36(item); |
133 | 140 | // The index of that number in the dictionary
|
134 |
| - var index = _indexOf.call(dictionary.integers, item); |
135 |
| - |
136 |
| - // If not, add to the dictionary and actualize the index |
137 |
| - if (index == -1) { |
138 |
| - dictionary.integers.push(_base10To36(item)); |
139 |
| - index = dictionary.integers.length - 1; |
| 141 | + if(item in dictionary.integers) { |
| 142 | + // Return the token |
| 143 | + return { |
| 144 | + type : 'integers', |
| 145 | + index : dictionary.integers[item] |
| 146 | + }; |
| 147 | + } else { |
| 148 | + // If not, add to the dictionary and actualize the index |
| 149 | + var index = dictionary.integersLen; |
| 150 | + dictionary.integers[item] = index; |
| 151 | + dictionary.integersLen += 1; |
| 152 | + // Return the token |
| 153 | + return { |
| 154 | + type : 'integers', |
| 155 | + index : index |
| 156 | + }; |
140 | 157 | }
|
141 |
| - |
142 |
| - // Return the token |
143 |
| - return { |
144 |
| - type : 'integers', |
145 |
| - index : index |
146 |
| - }; |
147 | 158 | }
|
148 | 159 |
|
149 | 160 | // Case 6: The item is float
|
150 | 161 | if (type === 'number') {
|
151 | 162 | // The index of that number in the dictionary
|
152 |
| - var index = _indexOf.call(dictionary.floats, item); |
153 |
| - |
154 |
| - // If not, add to the dictionary and actualize the index |
155 |
| - if (index == -1) { |
156 |
| - // Float not use base 36 |
157 |
| - dictionary.floats.push(item); |
158 |
| - index = dictionary.floats.length - 1; |
| 163 | + if(item in dictionary.floats) { |
| 164 | + // Return the token |
| 165 | + return { |
| 166 | + type : 'floats', |
| 167 | + index : dictionary.floats[item] |
| 168 | + }; |
| 169 | + } else { |
| 170 | + // If not, add to the dictionary and actualize the index |
| 171 | + var index = dictionary.floatsLen; |
| 172 | + dictionary.floats[item] = index; |
| 173 | + dictionary.floatsLen += 1; |
| 174 | + // Return the token |
| 175 | + return { |
| 176 | + type : 'floats', |
| 177 | + index : index |
| 178 | + }; |
159 | 179 | }
|
160 |
| - |
161 |
| - // Return the token |
162 |
| - return { |
163 |
| - type : 'floats', |
164 |
| - index : index |
165 |
| - }; |
166 | 180 | }
|
167 | 181 |
|
168 | 182 | // Case 7: The item is boolean
|
|
179 | 193 | })(json);
|
180 | 194 |
|
181 | 195 | // A set of shorthands proxies for the length of the dictionaries
|
182 |
| - var stringLength = dictionary.strings.length; |
183 |
| - var integerLength = dictionary.integers.length; |
184 |
| - var floatLength = dictionary.floats.length; |
| 196 | + var stringLength = dictionary.stringsLen; |
| 197 | + var integerLength = dictionary.integersLen; |
| 198 | + var floatLength = dictionary.floatsLen; |
185 | 199 |
|
186 | 200 | verbose && console.log('Parsing the dictionary');
|
187 | 201 |
|
188 | 202 | // Create a raw dictionary
|
189 |
| - var packed = dictionary.strings.join('|'); |
190 |
| - packed += '^' + dictionary.integers.join('|'); |
191 |
| - packed += '^' + dictionary.floats.join('|'); |
| 203 | + var packed = _getSortedKeys(dictionary.strings, dictionary.stringsLen).join('|'); |
| 204 | + packed += '^' + _getSortedKeys(dictionary.integers, dictionary.integersLen).join('|'); |
| 205 | + packed += '^' + _getSortedKeys(dictionary.floats, dictionary.floatsLen).join('|'); |
192 | 206 |
|
193 | 207 | verbose && console.log('Parsing the structure');
|
194 | 208 |
|
|
442 | 456 | })();
|
443 | 457 |
|
444 | 458 | }
|
445 |
| - /** |
446 |
| - * Get the index value of the dictionary |
447 |
| - * @param {Object} dictionary a object that have two array attributes: 'string' and 'number' |
448 |
| - * @param {Object} data |
449 |
| - */ |
450 |
| - var _indexOfDictionary = function(dictionary, value) { |
451 |
| - |
452 |
| - // The type of the value |
453 |
| - var type = typeof value; |
454 |
| - |
455 |
| - // If is boolean, return a boolean token |
456 |
| - if (type === 'boolean') |
457 |
| - return value ? TOKEN_TRUE : TOKEN_FALSE; |
458 |
| - |
459 |
| - // If is null, return a... yes! the null token |
460 |
| - if (value === null) |
461 |
| - return TOKEN_NULL; |
462 |
| - |
463 |
| - //add undefined |
464 |
| - if (typeof value === 'undefined') |
465 |
| - return TOKEN_UNDEFINED; |
466 |
| - |
467 | 459 |
|
468 |
| - if (value === '') { |
469 |
| - return TOKEN_EMPTY_STRING; |
| 460 | + var _getSortedKeys = function(dict, len) { |
| 461 | + var arr = new Array(len); |
| 462 | + for (var key in dict) { |
| 463 | + arr[dict[key]] = key; |
470 | 464 | }
|
471 |
| - |
472 |
| - if (type === 'string') { |
473 |
| - value = _encode(value); |
474 |
| - var index = _indexOf.call(dictionary.strings, value); |
475 |
| - if (index === -1) { |
476 |
| - dictionary.strings.push(value); |
477 |
| - index = dictionary.strings.length - 1; |
478 |
| - } |
479 |
| - } |
480 |
| - |
481 |
| - // If has an invalid JSON type (example a function) |
482 |
| - if (type !== 'string' && type !== 'number') { |
483 |
| - throw new Error('The type is not a JSON type'); |
484 |
| - }; |
485 |
| - |
486 |
| - if (type === 'string') {// string |
487 |
| - value = _encode(value); |
488 |
| - } else if (value % 1 === 0) {// integer |
489 |
| - value = _base10To36(value); |
490 |
| - } else {// float |
491 |
| - |
492 |
| - } |
493 |
| - |
494 |
| - // If is number, "serialize" the value |
495 |
| - value = type === 'number' ? _base10To36(value) : _encode(value); |
496 |
| - |
497 |
| - // Retrieve the index of that value in the dictionary |
498 |
| - var index = _indexOf.call(dictionary[type], value); |
499 |
| - |
500 |
| - // If that value is not in the dictionary |
501 |
| - if (index === -1) { |
502 |
| - // Push the value |
503 |
| - dictionary[type].push(value); |
504 |
| - // And return their index |
505 |
| - index = dictionary[type].length - 1; |
506 |
| - } |
507 |
| - |
508 |
| - // If the type is a number, then add the '+' prefix character |
509 |
| - // to differentiate that they is a number index. If not, then |
510 |
| - // just return a 36-based representation of the index |
511 |
| - return type === 'number' ? '+' + index : index; |
512 |
| - |
513 |
| - }; |
| 465 | + return arr; |
| 466 | + } |
514 | 467 |
|
515 | 468 | var _encode = function(str) {
|
516 | 469 | if ( typeof str !== 'string')
|
|
550 | 503 | return parseInt(number, 36);
|
551 | 504 | };
|
552 | 505 |
|
553 |
| - var _indexOf = Array.prototype.indexOf || |
554 |
| - function(obj, start) { |
555 |
| - for (var i = (start || 0), j = this.length; i < j; i++) { |
556 |
| - if (this[i] === obj) { |
557 |
| - return i; |
558 |
| - } |
559 |
| - } |
560 |
| - return -1; |
561 |
| - }; |
562 |
| - |
563 | 506 | return {
|
564 | 507 | JSON : JSON,
|
565 | 508 | pack : pack,
|
|
0 commit comments