-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
encoder.ts
54 lines (47 loc) · 1.32 KB
/
encoder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { Bencode, BencodeObject } from "./types.ts";
const textEncoder = new TextEncoder();
function encodeString(s: string): string {
return `${textEncoder.encode(s).length}:${s}`;
}
function encodeNumber(n: number): string {
const i = n > 0 ? Math.floor(n) : Math.ceil(n);
return `i${i}e`;
}
function encodeArray(arr: Bencode[]): string {
const encoded = arr.map((x: Bencode) => {
return encode(x);
});
return `l${encoded.join("")}e`;
}
function encodeObject(dict: BencodeObject): string {
const encoded = Object.entries(dict).map(([k, v]) => {
return encode(k) + encode(v);
});
return `d${encoded.join("")}e`;
}
export function encode(x: Bencode): string {
if (typeof x === "string") {
return encodeString(x);
} else if (typeof x === "number") {
return encodeNumber(x);
} else if (typeof x === "object") {
if (x == null) {
// c.f. https://github.com/nrepl/bencode/blob/v1.1.0/test/bencode/core_test.clj#L154
return encodeArray([]);
} else if (x instanceof Array) {
return encodeArray(x);
} else {
return encodeObject(x);
}
}
return "";
}
export class BencodeToStringStream extends TransformStream<Bencode, string> {
constructor() {
super({
transform: (chunk, controller) => {
controller.enqueue(encode(chunk));
},
});
}
}