@lumjs/encode 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ // UBJSON plugin
2
+ const UB = require('@shelacek/ubjson');
3
+ const WordArray = require('../crypto').WordArray;
4
+ const w2b = require('../util').wordArrayToUint8Array;
5
+
6
+ module.exports =
7
+ {
8
+ encode(data)
9
+ {
10
+ const buffer = UB.encode(data, this.ubEncOpts);
11
+ return WordArray.create(buffer);
12
+ },
13
+ decode(opts)
14
+ {
15
+ const wordArray = this.$decodeValue(opts, false);
16
+ const byteArray = w2b(wordArray);
17
+ //console.debug({wordArray,byteArray});
18
+ const arrayBuffer = byteArray.buffer;
19
+ const decoded = UB.decode(arrayBuffer, this.ubDecOpts);
20
+ return decoded;
21
+ }
22
+ }
23
+
package/lib/util.js ADDED
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Low-level encoding utilities
3
+ * @module @lumjs/encode/util
4
+ */
5
+ const {N} = require('@lumjs/core/types');
6
+
7
+ /**
8
+ * Return the ASCII/Unicode number for a character.
9
+ *
10
+ * Originally extracted from `phpjs`, which has been deprecated and replaced by
11
+ * [locutus](https://locutus.io/)
12
+ * which has a bunch of different programming language standard libraries.
13
+ * While I'd normally just add the library to the dependency list, I think
14
+ * including a `4.2 MB` library for a *single function* is overkill.
15
+ *
16
+ * @param {string} string
17
+ * @returns {number}
18
+ */
19
+ exports.ord = function (string)
20
+ {
21
+ // discuss at: https://locutus.io/php/ord/
22
+ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
23
+ // bugfixed by: Onno Marsman
24
+ // improved by: Brett Zamir (http://brett-zamir.me)
25
+ // input by: incidence
26
+ // example 1: ord('K');
27
+ // returns 1: 75
28
+ // example 2: ord('\uD800\uDC00'); // surrogate pair to create a single Unicode character
29
+ // returns 2: 65536
30
+
31
+ var str = string + '',
32
+ code = str.charCodeAt(0);
33
+ if (0xD800 <= code && code <= 0xDBFF)
34
+ {
35
+ // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
36
+ var hi = code;
37
+ if (str.length === 1)
38
+ {
39
+ // This is just a high surrogate with no following low surrogate, so we return its value;
40
+ return code;
41
+ // we could also throw an error as it is not a complete character, but someone may want to know
42
+ }
43
+ var low = str.charCodeAt(1);
44
+ return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
45
+ }
46
+ if (0xDC00 <= code && code <= 0xDFFF)
47
+ {
48
+ // Low surrogate
49
+ // This is just a low surrogate with no preceding high surrogate, so we return its value;
50
+ return code;
51
+ // we could also throw an error as it is not a complete character, but someone may want to know
52
+ }
53
+ return code;
54
+ }
55
+
56
+ /**
57
+ * Convert a numeric string into an array of byte values for encoding purposes.
58
+ *
59
+ * @param {string} numStr - The numeric string
60
+ * @param {(object|number)} [options] Options
61
+ *
62
+ * If this is a `number` then it's assumed to be `options.size`.
63
+ *
64
+ * @param {number} [options.size=2] The number of characters in each number.
65
+ *
66
+ * With the default `size` of `2` and the default `base` of `16`, this
67
+ * will turn the numeric string `0FD4` into `[15,212]`.
68
+ * If you change `len` to `1`, the same string would become `[0,15,13,4]`.
69
+ *
70
+ * @param {number} [options.base=16] The numeric base for the string.
71
+ *
72
+ * This defaults to `16` which is Hexadecimal.
73
+ *
74
+ * @param {boolean} [options.strict=false] Do not allow indivisible strings
75
+ *
76
+ * If this is `true` and the length of `numStr` is not divisible by
77
+ * `options.size`, then a `RangeError` will be thrown.
78
+ *
79
+ * This takes priority over the `options.pad` option.
80
+ *
81
+ * @param {boolean} [options.pad=false] Pad indivisible strings
82
+ *
83
+ * If this is `true` and the length of `numStr` is not divisible by
84
+ * `options.size`, then the string will be padded with leading `0`s
85
+ * to make it divisible.
86
+ *
87
+ * If both this and `options.strict` are `false` (the default),
88
+ * then the string will be extracted in bytes of `options.size` for
89
+ * as many blocks as it is cleanly divisible, then the remainder of
90
+ * the string will be parsed regardless of its length.
91
+ *
92
+ * @returns {Array} An array of integers.
93
+ */
94
+ exports.numByteArray = function (numStr, options={})
95
+ {
96
+ if (typeof options === N)
97
+ {
98
+ options = {size: options};
99
+ }
100
+
101
+ const numOpt = (name, defval, min, max) =>
102
+ {
103
+ const optval = options[name];
104
+ if (typeof optval !== N)
105
+ { // Was not a number, skip it.
106
+ return defval;
107
+ }
108
+ if (optval < min)
109
+ { // Value was lower than minimum.
110
+ throw new RangeError(`${name} value ${optval} is less than ${min}`);
111
+ }
112
+ if (max !== 0 && optval > max)
113
+ { // Value was higher than maximum.
114
+ throw new RangeError(`${name} value ${optval} is more than ${max}`);
115
+ }
116
+
117
+ return optval;
118
+ }
119
+
120
+ const len = numOpt('size', 2, 1, 0);
121
+ const base = numOpt('base', 16, 2, 36);
122
+
123
+ let strLen = numStr.length;
124
+ let remainder = strLen % len;
125
+
126
+ if (options.strict && remainder !== 0)
127
+ {
128
+ throw new RangeError(`string length ${strLen} is not divisible by ${len}`);
129
+ }
130
+ else if (options.pad && remainder !== 0)
131
+ {
132
+ const padSize = len - remainder;
133
+ numStr = numStr.padStart(strLen+padSize, '0');
134
+ strLen = numStr.length;
135
+ remainder = strLen % len;
136
+ if (remainder !== 0)
137
+ { // Something is wrong in the universe...
138
+ console.debug({numStr, strLen, len, remainder, arguments});
139
+ throw new Error("string has remainder after padding");
140
+ }
141
+ }
142
+
143
+ const endOf = strLen - (len-1);
144
+ const bytes = [];
145
+
146
+ const getBytes = (a,b) => bytes.push(parseInt(numStr.substring(a, b), base));
147
+
148
+ for(let i=0; i < endOf; i+=len)
149
+ {
150
+ getBytes(i, i+len);
151
+ }
152
+
153
+ if (remainder !== 0)
154
+ {
155
+ getBytes(strLen - remainder, strLen);
156
+ }
157
+
158
+ return bytes;
159
+ }
160
+
161
+ /**
162
+ * Convert a `WordArray` object into a Uint8Array
163
+ *
164
+ * @param {WordArray} wordArray
165
+ * @returns {Uint8Array}
166
+ */
167
+ exports.wordArrayToUint8Array = function(wordArray)
168
+ {
169
+ const l = wordArray.sigBytes;
170
+ const words = wordArray.words;
171
+ const result = new Uint8Array(l);
172
+ var i=0 /*dst*/, j=0 /*src*/;
173
+ while(true) {
174
+ // here i is a multiple of 4
175
+ if (i==l)
176
+ break;
177
+ var w = words[j++];
178
+ result[i++] = (w & 0xff000000) >>> 24;
179
+ if (i==l)
180
+ break;
181
+ result[i++] = (w & 0x00ff0000) >>> 16;
182
+ if (i==l)
183
+ break;
184
+ result[i++] = (w & 0x0000ff00) >>> 8;
185
+ if (i==l)
186
+ break;
187
+ result[i++] = (w & 0x000000ff);
188
+ }
189
+ return result;
190
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@lumjs/encode",
3
+ "version": "1.0.0",
4
+ "main": "lib/index.js",
5
+ "exports":
6
+ {
7
+ ".": "./lib/index.js",
8
+ "./base64": "./lib/base64.js",
9
+ "./base91": "./lib/base91.js",
10
+ "./crypto": "./lib/crypto/index.js",
11
+ "./crypto/load": "./lib/crypto/load.js",
12
+ "./hash": "./lib/hash.js",
13
+ "./safe64": "./lib/safe64/index.js",
14
+ "./safe64/header": "./lib/safe64/header.js",
15
+ "./util": "./lib/util.js",
16
+ "./package.json": "./package.json"
17
+ },
18
+ "license": "MIT",
19
+ "repository":
20
+ {
21
+ "type": "git",
22
+ "url": "https://github.com/supernovus/lum.encode.js.git"
23
+ },
24
+ "dependencies": {
25
+ "@lumjs/core": "^1.5.1",
26
+ "crypto-js": "^4.1.1",
27
+ "php-serialize": "^4.0.2",
28
+ "@shelacek/ubjson": "^1.1.1"
29
+ },
30
+ "devDependencies":
31
+ {
32
+ "@lumjs/tests": "^1.7.0"
33
+ },
34
+ "scripts":
35
+ {
36
+ "test": "node ./node_modules/@lumjs/tests/bin/lumtest.js",
37
+ "build-docs": "jsdoc -c ./jsdoc.json"
38
+ }
39
+ }
package/ub-dev.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ const UB = require('@shelacek/ubjson');
4
+
5
+ const data = {hello:["world","darkness my old friend"]};
6
+ const ubj = UB.encode(data);
7
+
8
+ console.log("Size:", ubj.byteLength);
9
+ const utf8 = new TextDecoder().decode(ubj);
10
+ console.log("UTF-8:", utf8);
11
+ console.log("JSON:", JSON.stringify(utf8));