UNPKG

16.4 kBJavaScriptView Raw
1(function() {
2 var CND, _decode, _encode, _invert_buffer, badge, bytecount_date, bytecount_number, bytecount_singular, bytecount_typemarker, debug, grow_rbuffer, rbuffer, rbuffer_max_size, rbuffer_min_size, read_date, read_list, read_nnumber, read_pnumber, read_private, read_singular, read_text, release_extraneous_rbuffer_bytes, rpr, symbol_fallback, tm_date, tm_false, tm_hi, tm_list, tm_lo, tm_ninfinity, tm_nnumber, tm_null, tm_pinfinity, tm_pnumber, tm_private, tm_text, tm_true, warn, write, write_date, write_infinity, write_number, write_private, write_singular, write_text;
3
4 CND = require('cnd');
5
6 rpr = CND.rpr;
7
8 badge = 'HOLLERITH/CODEC';
9
10 debug = CND.get_logger('debug', badge);
11
12 warn = CND.get_logger('warn', badge);
13
14 CND.shim();
15
16 this['typemarkers'] = {};
17
18 tm_lo = this['typemarkers']['lo'] = 0x00;
19
20 tm_null = this['typemarkers']['null'] = 'B'.codePointAt(0);
21
22 tm_false = this['typemarkers']['false'] = 'C'.codePointAt(0);
23
24 tm_true = this['typemarkers']['true'] = 'D'.codePointAt(0);
25
26 tm_list = this['typemarkers']['list'] = 'E'.codePointAt(0);
27
28 tm_date = this['typemarkers']['date'] = 'G'.codePointAt(0);
29
30 tm_ninfinity = this['typemarkers']['ninfinity'] = 'J'.codePointAt(0);
31
32 tm_nnumber = this['typemarkers']['nnumber'] = 'K'.codePointAt(0);
33
34 tm_pnumber = this['typemarkers']['pnumber'] = 'L'.codePointAt(0);
35
36 tm_pinfinity = this['typemarkers']['pinfinity'] = 'M'.codePointAt(0);
37
38 tm_text = this['typemarkers']['text'] = 'T'.codePointAt(0);
39
40 tm_private = this['typemarkers']['private'] = 'Z'.codePointAt(0);
41
42 tm_hi = this['typemarkers']['hi'] = 0xff;
43
44 this['bytecounts'] = {};
45
46 bytecount_singular = this['bytecounts']['singular'] = 1;
47
48 bytecount_typemarker = this['bytecounts']['typemarker'] = 1;
49
50 bytecount_number = this['bytecounts']['number'] = 9;
51
52 bytecount_date = this['bytecounts']['date'] = bytecount_number + 1;
53
54 this['sentinels'] = {};
55
56
57 /* http://www.merlyn.demon.co.uk/js-datex.htm */
58
59 this['sentinels']['firstdate'] = new Date(-8640000000000000);
60
61 this['sentinels']['lastdate'] = new Date(+8640000000000000);
62
63 this['keys'] = {};
64
65 this['keys']['lo'] = new Buffer([this['typemarkers']['lo']]);
66
67 this['keys']['hi'] = new Buffer([this['typemarkers']['hi']]);
68
69 this['symbols'] = {};
70
71 symbol_fallback = this['fallback'] = Symbol('fallback');
72
73 rbuffer_min_size = 1024;
74
75 rbuffer_max_size = 65536;
76
77 rbuffer = new Buffer(rbuffer_min_size);
78
79 grow_rbuffer = function() {
80 var factor, new_result_buffer, new_size;
81 factor = 2;
82 new_size = Math.floor(rbuffer.length * factor + 0.5);
83 new_result_buffer = new Buffer(new_size);
84 rbuffer.copy(new_result_buffer);
85 rbuffer = new_result_buffer;
86 return null;
87 };
88
89 release_extraneous_rbuffer_bytes = function() {
90 if (rbuffer.length > rbuffer_max_size) {
91 rbuffer = new Buffer(rbuffer_max_size);
92 }
93 return null;
94 };
95
96 write_singular = function(idx, value) {
97 var typemarker;
98 while (!(rbuffer.length >= idx + bytecount_singular)) {
99 grow_rbuffer();
100 }
101 if (value === null) {
102 typemarker = tm_null;
103 } else if (value === false) {
104 typemarker = tm_false;
105 } else if (value === true) {
106 typemarker = tm_true;
107 } else {
108 throw new Error("unable to encode value of type " + (CND.type_of(value)));
109 }
110 rbuffer[idx] = typemarker;
111 return idx + bytecount_singular;
112 };
113
114 read_singular = function(buffer, idx) {
115 var typemarker, value;
116 switch (typemarker = buffer[idx]) {
117 case tm_null:
118 value = null;
119 break;
120 case tm_false:
121 value = false;
122 break;
123 case tm_true:
124 value = true;
125 break;
126 default:
127 throw new Error("unable to decode 0x" + (typemarker.toString(16)) + " at index " + idx + " (" + (rpr(buffer)) + ")");
128 }
129 return [idx + bytecount_singular, value];
130 };
131
132 write_private = function(idx, value, encoder) {
133 var encoded_value, ref, type, wrapped_value;
134 while (!(rbuffer.length >= idx + 3 * bytecount_typemarker)) {
135 grow_rbuffer();
136 }
137 rbuffer[idx] = tm_private;
138 idx += bytecount_typemarker;
139 rbuffer[idx] = tm_list;
140 idx += bytecount_typemarker;
141 type = (ref = value['type']) != null ? ref : 'private';
142 value = value['value'];
143 if (encoder != null) {
144 encoded_value = encoder(type, value, symbol_fallback);
145 if (encoded_value !== symbol_fallback) {
146 value = encoded_value;
147 }
148 }
149 wrapped_value = [type, value];
150 idx = _encode(wrapped_value, idx);
151 rbuffer[idx] = tm_lo;
152 idx += bytecount_typemarker;
153 return idx;
154 };
155
156 read_private = function(buffer, idx, decoder) {
157 var R, ref, ref1, type, value;
158 idx += bytecount_typemarker;
159 ref = read_list(buffer, idx), idx = ref[0], (ref1 = ref[1], type = ref1[0], value = ref1[1]);
160 if (decoder != null) {
161 R = decoder(type, value, symbol_fallback);
162 if (R === void 0) {
163 throw new Error("encountered illegal value `undefined` when reading private type");
164 }
165 }
166 if (R === symbol_fallback || (decoder == null)) {
167 R = {
168 type: type,
169 value: value
170 };
171 }
172 return [idx, R];
173 };
174
175 write_number = function(idx, number) {
176 var type;
177 while (!(rbuffer.length >= idx + bytecount_number)) {
178 grow_rbuffer();
179 }
180 if (number < 0) {
181 type = tm_nnumber;
182 number = -number;
183 } else {
184 type = tm_pnumber;
185 }
186 rbuffer[idx] = type;
187 rbuffer.writeDoubleBE(number, idx + 1);
188 if (type === tm_nnumber) {
189 _invert_buffer(rbuffer, idx);
190 }
191 return idx + bytecount_number;
192 };
193
194 write_infinity = function(idx, number) {
195 while (!(rbuffer.length >= idx + bytecount_singular)) {
196 grow_rbuffer();
197 }
198 rbuffer[idx] = number === -Infinity ? tm_ninfinity : tm_pinfinity;
199 return idx + bytecount_singular;
200 };
201
202 read_nnumber = function(buffer, idx) {
203 var copy;
204 if (buffer[idx] !== tm_nnumber) {
205 throw new Error("not a negative number at index " + idx);
206 }
207 copy = _invert_buffer(new Buffer(buffer.slice(idx, idx + bytecount_number)), 0);
208 return [idx + bytecount_number, -(copy.readDoubleBE(1))];
209 };
210
211 read_pnumber = function(buffer, idx) {
212 if (buffer[idx] !== tm_pnumber) {
213 throw new Error("not a positive number at index " + idx);
214 }
215 return [idx + bytecount_number, buffer.readDoubleBE(idx + 1)];
216 };
217
218 _invert_buffer = function(buffer, idx) {
219 var i, j, ref, ref1;
220 for (i = j = ref = idx + 1, ref1 = idx + 8; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) {
221 buffer[i] = ~buffer[i];
222 }
223 return buffer;
224 };
225
226 write_date = function(idx, date) {
227 var number;
228 while (!(rbuffer.length >= idx + bytecount_date)) {
229 grow_rbuffer();
230 }
231 number = +date;
232 rbuffer[idx] = tm_date;
233 return write_number(idx + 1, number);
234 };
235
236 read_date = function(buffer, idx) {
237 var ref, ref1, type, value;
238 if (buffer[idx] !== tm_date) {
239 throw new Error("not a date at index " + idx);
240 }
241 switch (type = buffer[idx + 1]) {
242 case tm_nnumber:
243 ref = read_nnumber(buffer, idx + 1), idx = ref[0], value = ref[1];
244 break;
245 case tm_pnumber:
246 ref1 = read_pnumber(buffer, idx + 1), idx = ref1[0], value = ref1[1];
247 break;
248 default:
249 throw new Error("unknown date type marker 0x" + (type.toString(16)) + " at index " + idx);
250 }
251 return [idx, new Date(value)];
252 };
253
254 write_text = function(idx, text) {
255 var bytecount_text;
256 text = text.replace(/\x01/g, '\x01\x02');
257 text = text.replace(/\x00/g, '\x01\x01');
258 bytecount_text = (Buffer.byteLength(text, 'utf-8')) + 2;
259 while (!(rbuffer.length >= idx + bytecount_text)) {
260 grow_rbuffer();
261 }
262 rbuffer[idx] = tm_text;
263 rbuffer.write(text, idx + 1);
264 rbuffer[idx + bytecount_text - 1] = tm_lo;
265 return idx + bytecount_text;
266 };
267
268 read_text = function(buffer, idx) {
269 var R, byte, stop_idx;
270 if (buffer[idx] !== tm_text) {
271 throw new Error("not a text at index " + idx);
272 }
273 stop_idx = idx;
274 while (true) {
275 stop_idx += +1;
276 if ((byte = buffer[stop_idx]) === tm_lo) {
277 break;
278 }
279 if (byte == null) {
280 throw new Error("runaway string at index " + idx);
281 }
282 }
283 R = buffer.toString('utf-8', idx + 1, stop_idx);
284 R = R.replace(/\x01\x01/g, '\x00');
285 R = R.replace(/\x01\x02/g, '\x01');
286 return [stop_idx + 1, R];
287 };
288
289 read_list = function(buffer, idx) {
290 var R, byte, ref, value;
291 if (buffer[idx] !== tm_list) {
292 throw new Error("not a list at index " + idx);
293 }
294 R = [];
295 idx += +1;
296 while (true) {
297 if ((byte = buffer[idx]) === tm_lo) {
298 break;
299 }
300 ref = _decode(buffer, idx, true), idx = ref[0], value = ref[1];
301 R.push(value[0]);
302 if (byte == null) {
303 throw new Error("runaway list at index " + idx);
304 }
305 }
306 return [idx + 1, R];
307 };
308
309 write = function(idx, value, encoder) {
310 var type;
311 switch (type = CND.type_of(value)) {
312 case 'text':
313 return write_text(idx, value);
314 case 'number':
315 return write_number(idx, value);
316 case 'jsinfinity':
317 return write_infinity(idx, value);
318 case 'jsdate':
319 return write_date(idx, value);
320 }
321 if (CND.isa_pod(value)) {
322 return write_private(idx, value, encoder);
323 }
324 return write_singular(idx, value);
325 };
326
327 this.encode = function(key, encoder) {
328 var R, idx, type;
329 rbuffer.fill(0x00);
330 if ((type = CND.type_of(key)) !== 'list') {
331 throw new Error("expected a list, got a " + type);
332 }
333 idx = _encode(key, 0, encoder);
334 R = new Buffer(idx);
335 rbuffer.copy(R, 0, 0, idx);
336 release_extraneous_rbuffer_bytes();
337 return R;
338 };
339
340 this.encode_plus_hi = function(key, encoder) {
341
342 /* TAINT code duplication */
343 var R, idx, type;
344 rbuffer.fill(0x00);
345 if ((type = CND.type_of(key)) !== 'list') {
346 throw new Error("expected a list, got a " + type);
347 }
348 idx = _encode(key, 0, encoder);
349 while (!(rbuffer.length >= idx + 1)) {
350 grow_rbuffer();
351 }
352 rbuffer[idx] = tm_hi;
353 idx += +1;
354 R = new Buffer(idx);
355 rbuffer.copy(R, 0, 0, idx);
356 release_extraneous_rbuffer_bytes();
357 return R;
358 };
359
360 _encode = function(key, idx, encoder) {
361 var element, element_idx, error, j, k, key_rpr, l, last_element_idx, len, len1, len2, sub_element;
362 last_element_idx = key.length - 1;
363 for (element_idx = j = 0, len = key.length; j < len; element_idx = ++j) {
364 element = key[element_idx];
365 try {
366 if (CND.isa_list(element)) {
367 rbuffer[idx] = tm_list;
368 idx += +1;
369 for (k = 0, len1 = element.length; k < len1; k++) {
370 sub_element = element[k];
371 idx = _encode([sub_element], idx, encoder);
372 }
373 rbuffer[idx] = tm_lo;
374 idx += +1;
375 } else {
376 idx = write(idx, element, encoder);
377 }
378 } catch (_error) {
379 error = _error;
380 key_rpr = [];
381 for (l = 0, len2 = key.length; l < len2; l++) {
382 element = key[l];
383 if (CND.isa_jsbuffer(element)) {
384 key_rpr.push("" + (this.rpr_of_buffer(null, key[2])));
385 } else {
386 key_rpr.push(rpr(element));
387 }
388 }
389 warn("detected problem with key [ " + (rpr(key_rpr.join(', '))) + " ]");
390 throw error;
391 }
392 }
393 return idx;
394 };
395
396 this.decode = function(buffer, decoder) {
397 return (_decode(buffer, 0, false, decoder))[1];
398 };
399
400 _decode = function(buffer, idx, single, decoder) {
401 var R, last_idx, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, type, value;
402 R = [];
403 last_idx = buffer.length - 1;
404 while (true) {
405 if (idx > last_idx) {
406 break;
407 }
408 switch (type = buffer[idx]) {
409 case tm_list:
410 ref = read_list(buffer, idx), idx = ref[0], value = ref[1];
411 break;
412 case tm_text:
413 ref1 = read_text(buffer, idx), idx = ref1[0], value = ref1[1];
414 break;
415 case tm_nnumber:
416 ref2 = read_nnumber(buffer, idx), idx = ref2[0], value = ref2[1];
417 break;
418 case tm_ninfinity:
419 ref3 = [idx + 1, -Infinity], idx = ref3[0], value = ref3[1];
420 break;
421 case tm_pnumber:
422 ref4 = read_pnumber(buffer, idx), idx = ref4[0], value = ref4[1];
423 break;
424 case tm_pinfinity:
425 ref5 = [idx + 1, +Infinity], idx = ref5[0], value = ref5[1];
426 break;
427 case tm_date:
428 ref6 = read_date(buffer, idx), idx = ref6[0], value = ref6[1];
429 break;
430 case tm_private:
431 ref7 = read_private(buffer, idx, decoder), idx = ref7[0], value = ref7[1];
432 break;
433 default:
434 ref8 = read_singular(buffer, idx), idx = ref8[0], value = ref8[1];
435 }
436 R.push(value);
437 if (single) {
438 break;
439 }
440 }
441 return [idx, R];
442 };
443
444 this.encodings = {
445 dbcs2: "⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛\n㉜!"#$%&'()*+,-./0123456789:;<=>?\n@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\n`abcdefghijklmnopqrstuvwxyz{|}~㉠\n㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝\n㋞㋟㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽\n㋾㊊㊋㊌㊍㊎㊏㊐㊑㊒㊓㊔㊕㊖㊗㊘㊙㊚㊛㊜㊝㊞㊟㊠㊡㊢㊣㊤㊥㊦㊧㊨\n㊩㊪㊫㊬㊭㊮㊯㊰㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㉈㉉㉊㉋㉌㉍㉎㉏⓵⓶⓷⓸⓹〓",
446 aleph: "БДИЛЦЧШЭЮƆƋƏƐƔƥƧƸψŐőŒœŊŁłЯɔɘɐɕəɞ\n␣!\"#$%&'()*+,-./0123456789:;<=>?\n@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\n`abcdefghijklmnopqrstuvwxyz{|}~ω\nΓΔΘΛΞΠΣΦΨΩαβγδεζηθικλμνξπρςστυφχ\nЖ¡¢£¤¥¦§¨©ª«¬Я®¯°±²³´µ¶·¸¹º»¼½¾¿\nÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß\nàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
447 rdctn: "∇≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡\n␣!\"#$%&'()*+,-./0123456789:;<=>?\n@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\n`abcdefghijklmnopqrstuvwxyz{|}~≡\n∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃∃\n∃∃¢£¤¥¦§¨©ª«¬Я®¯°±²³´µ¶·¸¹º»¼½¾¿\nÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß\nàáâãäåæçèéêëìíîïðñò≢≢≢≢≢≢≢≢≢≢≢≢Δ"
448 };
449
450 this.rpr_of_buffer = function(buffer, encoding) {
451 return (rpr(buffer)) + ' ' + this._encode_buffer(buffer, encoding);
452 };
453
454 this._encode_buffer = function(buffer, encoding) {
455 var idx;
456 if (encoding == null) {
457 encoding = 'rdctn';
458 }
459
460 /* TAINT use switch, emit error if `encoding` not list or known key */
461 if (!CND.isa_list(encoding)) {
462 encoding = this.encodings[encoding];
463 }
464 return ((function() {
465 var j, ref, results;
466 results = [];
467 for (idx = j = 0, ref = buffer.length; 0 <= ref ? j < ref : j > ref; idx = 0 <= ref ? ++j : --j) {
468 results.push(encoding[buffer[idx]]);
469 }
470 return results;
471 })()).join('');
472 };
473
474 this._compile_encodings = function() {
475 var chrs_of, encoding, length, name, ref;
476 chrs_of = function(text) {
477 var chr;
478 text = text.split(/([\ud800-\udbff].|.)/);
479 return (function() {
480 var j, len, results;
481 results = [];
482 for (j = 0, len = text.length; j < len; j++) {
483 chr = text[j];
484 if (chr !== '') {
485 results.push(chr);
486 }
487 }
488 return results;
489 })();
490 };
491 ref = this.encodings;
492 for (name in ref) {
493 encoding = ref[name];
494 encoding = chrs_of(encoding.replace(/\n+/g, ''));
495 if ((length = encoding.length) !== 256) {
496 throw new Error("expected 256 characters, found " + length + " in encoding " + (rpr(name)));
497 }
498 this.encodings[name] = encoding;
499 }
500 return null;
501 };
502
503 this._compile_encodings();
504
505}).call(this);
506
507//# sourceMappingURL=../sourcemaps/main.js.map
\No newline at end of file