@thi.ng/bencode 2.1.46 → 2.1.48
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.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/decode.js +43 -21
- package/encode.js +32 -17
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/decode.js
CHANGED
|
@@ -3,6 +3,28 @@ import { isArray } from "@thi.ng/checks/is-array";
|
|
|
3
3
|
import { assert } from "@thi.ng/errors/assert";
|
|
4
4
|
import { illegalState } from "@thi.ng/errors/illegal-state";
|
|
5
5
|
import { utf8Decode } from "@thi.ng/transducers-binary/utf8";
|
|
6
|
+
var Type;
|
|
7
|
+
(function (Type) {
|
|
8
|
+
Type[Type["INT"] = 0] = "INT";
|
|
9
|
+
Type[Type["FLOAT"] = 1] = "FLOAT";
|
|
10
|
+
Type[Type["STR"] = 2] = "STR";
|
|
11
|
+
Type[Type["BINARY"] = 3] = "BINARY";
|
|
12
|
+
Type[Type["DICT"] = 4] = "DICT";
|
|
13
|
+
Type[Type["LIST"] = 5] = "LIST";
|
|
14
|
+
})(Type || (Type = {}));
|
|
15
|
+
var Lit;
|
|
16
|
+
(function (Lit) {
|
|
17
|
+
Lit[Lit["MINUS"] = 45] = "MINUS";
|
|
18
|
+
Lit[Lit["DOT"] = 46] = "DOT";
|
|
19
|
+
Lit[Lit["ZERO"] = 48] = "ZERO";
|
|
20
|
+
Lit[Lit["NINE"] = 57] = "NINE";
|
|
21
|
+
Lit[Lit["COLON"] = 58] = "COLON";
|
|
22
|
+
Lit[Lit["DICT"] = 100] = "DICT";
|
|
23
|
+
Lit[Lit["END"] = 101] = "END";
|
|
24
|
+
Lit[Lit["FLOAT"] = 102] = "FLOAT";
|
|
25
|
+
Lit[Lit["INT"] = 105] = "INT";
|
|
26
|
+
Lit[Lit["LIST"] = 108] = "LIST";
|
|
27
|
+
})(Lit || (Lit = {}));
|
|
6
28
|
export const decode = (buf, utf8 = true) => {
|
|
7
29
|
const iter = buf[Symbol.iterator]();
|
|
8
30
|
const stack = [];
|
|
@@ -11,35 +33,35 @@ export const decode = (buf, utf8 = true) => {
|
|
|
11
33
|
while (!(i = iter.next()).done) {
|
|
12
34
|
x = i.value;
|
|
13
35
|
switch (x) {
|
|
14
|
-
case
|
|
36
|
+
case Lit.DICT:
|
|
15
37
|
ensureNotKey(stack, "dict");
|
|
16
|
-
stack.push({ type:
|
|
38
|
+
stack.push({ type: Type.DICT, val: {} });
|
|
17
39
|
break;
|
|
18
|
-
case
|
|
40
|
+
case Lit.LIST:
|
|
19
41
|
ensureNotKey(stack, "list");
|
|
20
|
-
stack.push({ type:
|
|
42
|
+
stack.push({ type: Type.LIST, val: [] });
|
|
21
43
|
break;
|
|
22
|
-
case
|
|
44
|
+
case Lit.INT:
|
|
23
45
|
x = collect(stack, readInt(iter, 0));
|
|
24
46
|
if (x !== undefined) {
|
|
25
47
|
return x;
|
|
26
48
|
}
|
|
27
49
|
break;
|
|
28
|
-
case
|
|
50
|
+
case Lit.FLOAT:
|
|
29
51
|
x = collect(stack, readFloat(iter));
|
|
30
52
|
if (x !== undefined) {
|
|
31
53
|
return x;
|
|
32
54
|
}
|
|
33
55
|
break;
|
|
34
|
-
case
|
|
56
|
+
case Lit.END:
|
|
35
57
|
x = stack.pop();
|
|
36
58
|
if (x) {
|
|
37
59
|
const parent = peek(stack);
|
|
38
60
|
if (parent) {
|
|
39
|
-
if (parent.type ===
|
|
61
|
+
if (parent.type === Type.LIST) {
|
|
40
62
|
parent.val.push(x.val);
|
|
41
63
|
}
|
|
42
|
-
else if (parent.type ===
|
|
64
|
+
else if (parent.type === Type.DICT) {
|
|
43
65
|
parent.val[parent.key] = x.val;
|
|
44
66
|
parent.key = null;
|
|
45
67
|
}
|
|
@@ -53,8 +75,8 @@ export const decode = (buf, utf8 = true) => {
|
|
|
53
75
|
}
|
|
54
76
|
break;
|
|
55
77
|
default:
|
|
56
|
-
if (x >=
|
|
57
|
-
x = readBytes(iter, readInt(iter, x -
|
|
78
|
+
if (x >= Lit.ZERO && x <= Lit.NINE) {
|
|
79
|
+
x = readBytes(iter, readInt(iter, x - Lit.ZERO, Lit.COLON));
|
|
58
80
|
x = collect(stack, x, utf8);
|
|
59
81
|
if (x !== undefined) {
|
|
60
82
|
return x;
|
|
@@ -69,13 +91,13 @@ export const decode = (buf, utf8 = true) => {
|
|
|
69
91
|
};
|
|
70
92
|
const ensureNotKey = (stack, type) => {
|
|
71
93
|
const x = peek(stack);
|
|
72
|
-
assert(!x || x.type !==
|
|
94
|
+
assert(!x || x.type !== Type.DICT || x.key, type + " not supported as dict key");
|
|
73
95
|
};
|
|
74
96
|
const collect = (stack, x, utf8 = false) => {
|
|
75
97
|
const parent = peek(stack);
|
|
76
98
|
if (!parent)
|
|
77
99
|
return x;
|
|
78
|
-
if (parent.type ===
|
|
100
|
+
if (parent.type === Type.LIST) {
|
|
79
101
|
parent.val.push(utf8 && isArray(x) ? utf8Decode(x) : x);
|
|
80
102
|
}
|
|
81
103
|
else {
|
|
@@ -88,16 +110,16 @@ const collect = (stack, x, utf8 = false) => {
|
|
|
88
110
|
}
|
|
89
111
|
}
|
|
90
112
|
};
|
|
91
|
-
const readInt = (iter, acc, end =
|
|
113
|
+
const readInt = (iter, acc, end = Lit.END) => {
|
|
92
114
|
let i;
|
|
93
115
|
let x;
|
|
94
116
|
let isSigned = false;
|
|
95
117
|
while (!(i = iter.next()).done) {
|
|
96
118
|
x = i.value;
|
|
97
|
-
if (x >=
|
|
98
|
-
acc = acc * 10 + x -
|
|
119
|
+
if (x >= Lit.ZERO && x <= Lit.NINE) {
|
|
120
|
+
acc = acc * 10 + x - Lit.ZERO;
|
|
99
121
|
}
|
|
100
|
-
else if (x ===
|
|
122
|
+
else if (x === Lit.MINUS) {
|
|
101
123
|
assert(!isSigned, `invalid int literal`);
|
|
102
124
|
isSigned = true;
|
|
103
125
|
}
|
|
@@ -116,12 +138,12 @@ const readFloat = (iter) => {
|
|
|
116
138
|
let acc = "";
|
|
117
139
|
while (!(i = iter.next()).done) {
|
|
118
140
|
x = i.value;
|
|
119
|
-
if ((x >=
|
|
120
|
-
x ===
|
|
121
|
-
x ===
|
|
141
|
+
if ((x >= Lit.ZERO && x <= Lit.NINE) ||
|
|
142
|
+
x === Lit.DOT ||
|
|
143
|
+
x === Lit.MINUS) {
|
|
122
144
|
acc += String.fromCharCode(x);
|
|
123
145
|
}
|
|
124
|
-
else if (x ===
|
|
146
|
+
else if (x === Lit.END) {
|
|
125
147
|
return parseFloat(acc);
|
|
126
148
|
}
|
|
127
149
|
else {
|
package/encode.js
CHANGED
|
@@ -9,46 +9,61 @@ import { unsupported } from "@thi.ng/errors/unsupported";
|
|
|
9
9
|
import { bytes, str, u8, u8array } from "@thi.ng/transducers-binary/bytes";
|
|
10
10
|
import { utf8Length } from "@thi.ng/transducers-binary/utf8";
|
|
11
11
|
import { mapcat } from "@thi.ng/transducers/mapcat";
|
|
12
|
+
var Type;
|
|
13
|
+
(function (Type) {
|
|
14
|
+
Type[Type["INT"] = 0] = "INT";
|
|
15
|
+
Type[Type["FLOAT"] = 1] = "FLOAT";
|
|
16
|
+
Type[Type["STR"] = 2] = "STR";
|
|
17
|
+
Type[Type["BINARY"] = 3] = "BINARY";
|
|
18
|
+
Type[Type["DICT"] = 4] = "DICT";
|
|
19
|
+
Type[Type["LIST"] = 5] = "LIST";
|
|
20
|
+
})(Type || (Type = {}));
|
|
21
|
+
var Lit;
|
|
22
|
+
(function (Lit) {
|
|
23
|
+
Lit[Lit["DICT"] = 100] = "DICT";
|
|
24
|
+
Lit[Lit["END"] = 101] = "END";
|
|
25
|
+
Lit[Lit["LIST"] = 108] = "LIST";
|
|
26
|
+
})(Lit || (Lit = {}));
|
|
12
27
|
const FLOAT_RE = /^[0-9.-]+$/;
|
|
13
28
|
export const encode = (x, cap = 1024) => bytes(cap, encodeBin(x));
|
|
14
29
|
const encodeBin = defmulti((x) => isNumber(x)
|
|
15
30
|
? Math.floor(x) !== x
|
|
16
|
-
?
|
|
17
|
-
:
|
|
31
|
+
? Type.FLOAT
|
|
32
|
+
: Type.INT
|
|
18
33
|
: isBoolean(x)
|
|
19
|
-
?
|
|
34
|
+
? Type.INT
|
|
20
35
|
: isString(x)
|
|
21
|
-
?
|
|
36
|
+
? Type.STR
|
|
22
37
|
: x instanceof Uint8Array
|
|
23
|
-
?
|
|
38
|
+
? Type.BINARY
|
|
24
39
|
: isArrayLike(x)
|
|
25
|
-
?
|
|
40
|
+
? Type.LIST
|
|
26
41
|
: isPlainObject(x)
|
|
27
|
-
?
|
|
42
|
+
? Type.DICT
|
|
28
43
|
: unsupported(`unsupported data type: ${x}`), {}, {
|
|
29
|
-
[
|
|
44
|
+
[Type.INT]: (x) => {
|
|
30
45
|
__ensureValidNumber(x);
|
|
31
46
|
return [str(`i${Math.floor(x)}e`)];
|
|
32
47
|
},
|
|
33
|
-
[
|
|
48
|
+
[Type.FLOAT]: (x) => {
|
|
34
49
|
__ensureValidNumber(x);
|
|
35
50
|
assert(FLOAT_RE.test(x.toString()), `values requiring exponential notation not allowed (${x})`);
|
|
36
51
|
return [str(`f${x}e`)];
|
|
37
52
|
},
|
|
38
|
-
[
|
|
53
|
+
[Type.BINARY]: (buf) => [
|
|
39
54
|
str(buf.length + ":"),
|
|
40
55
|
u8array(buf),
|
|
41
56
|
],
|
|
42
|
-
[
|
|
43
|
-
[
|
|
44
|
-
u8(
|
|
57
|
+
[Type.STR]: (x) => [str(utf8Length(x) + ":" + x)],
|
|
58
|
+
[Type.LIST]: (x) => [
|
|
59
|
+
u8(Lit.LIST),
|
|
45
60
|
...mapcat(encodeBin, x),
|
|
46
|
-
u8(
|
|
61
|
+
u8(Lit.END),
|
|
47
62
|
],
|
|
48
|
-
[
|
|
49
|
-
u8(
|
|
63
|
+
[Type.DICT]: (x) => [
|
|
64
|
+
u8(Lit.DICT),
|
|
50
65
|
...mapcat((k) => encodeBin(k).concat(encodeBin(x[k])), Object.keys(x).sort()),
|
|
51
|
-
u8(
|
|
66
|
+
u8(Lit.END),
|
|
52
67
|
],
|
|
53
68
|
});
|
|
54
69
|
/** @internal */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/bencode",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.48",
|
|
4
4
|
"description": "Bencode binary encoder / decoder with optional UTF8 encoding & floating point support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -34,20 +34,20 @@
|
|
|
34
34
|
"test": "testament test"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@thi.ng/arrays": "^2.5.
|
|
38
|
-
"@thi.ng/checks": "^3.3.
|
|
39
|
-
"@thi.ng/defmulti": "^2.1.
|
|
40
|
-
"@thi.ng/errors": "^2.2.
|
|
41
|
-
"@thi.ng/transducers": "^8.4.
|
|
42
|
-
"@thi.ng/transducers-binary": "^2.1.
|
|
37
|
+
"@thi.ng/arrays": "^2.5.10",
|
|
38
|
+
"@thi.ng/checks": "^3.3.12",
|
|
39
|
+
"@thi.ng/defmulti": "^2.1.35",
|
|
40
|
+
"@thi.ng/errors": "^2.2.15",
|
|
41
|
+
"@thi.ng/transducers": "^8.4.2",
|
|
42
|
+
"@thi.ng/transducers-binary": "^2.1.46"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@microsoft/api-extractor": "^7.34.4",
|
|
46
|
-
"@thi.ng/testament": "^0.3.
|
|
47
|
-
"rimraf": "^4.4.
|
|
46
|
+
"@thi.ng/testament": "^0.3.15",
|
|
47
|
+
"rimraf": "^4.4.1",
|
|
48
48
|
"tools": "^0.0.1",
|
|
49
|
-
"typedoc": "^0.23.
|
|
50
|
-
"typescript": "^
|
|
49
|
+
"typedoc": "^0.23.28",
|
|
50
|
+
"typescript": "^5.0.4"
|
|
51
51
|
},
|
|
52
52
|
"keywords": [
|
|
53
53
|
"array",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"default": "./encode.js"
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "abcedd9e4e06a4b631f363610eec572f79b571c1\n"
|
|
83
83
|
}
|