node-pkware 3.0.0 → 3.0.2
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/dist/Explode.js +1 -1
- package/dist/Explode.js.map +1 -1
- package/dist/Implode.d.ts +0 -1
- package/dist/Implode.js +1 -1
- package/dist/Implode.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/ExpandingBuffer.ts +0 -148
- package/src/Explode.ts +0 -404
- package/src/Implode.ts +0 -368
- package/src/bin/explode.ts +0 -80
- package/src/bin/helpers.ts +0 -65
- package/src/bin/implode.ts +0 -116
- package/src/constants.ts +0 -120
- package/src/errors.ts +0 -47
- package/src/functions.ts +0 -73
- package/src/index.ts +0 -30
- package/src/stream.ts +0 -220
- package/src/types.ts +0 -26
package/src/constants.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compression types for implode
|
|
3
|
-
*/
|
|
4
|
-
export enum Compression {
|
|
5
|
-
Unknown = -1,
|
|
6
|
-
Binary = 0,
|
|
7
|
-
Ascii,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Dictionary sizes for implode, determines how well the file get compressed.
|
|
12
|
-
*
|
|
13
|
-
* Small dictionary size means less memory to lookback in data for repetitions, meaning it will be less effective, the file stays larger, less compressed.
|
|
14
|
-
* On the other hand, large compression allows more lookback allowing more effective compression, thus generating smaller, more compressed files.
|
|
15
|
-
*/
|
|
16
|
-
export enum DictionarySize {
|
|
17
|
-
Unknown = -1,
|
|
18
|
-
Small = 4,
|
|
19
|
-
Medium,
|
|
20
|
-
Large,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const EMPTY_BUFFER = Buffer.from([])
|
|
24
|
-
|
|
25
|
-
export const LONGEST_ALLOWED_REPETITION = 0x204
|
|
26
|
-
|
|
27
|
-
export const LITERAL_END_STREAM = 0x305
|
|
28
|
-
|
|
29
|
-
// prettier-ignore
|
|
30
|
-
export const DistCode = [
|
|
31
|
-
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
|
|
32
|
-
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
|
|
33
|
-
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
|
|
34
|
-
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
// prettier-ignore
|
|
38
|
-
export const DistBits = [
|
|
39
|
-
0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
|
40
|
-
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
|
41
|
-
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
|
42
|
-
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
|
43
|
-
]
|
|
44
|
-
|
|
45
|
-
// prettier-ignore
|
|
46
|
-
export const LenBits = [
|
|
47
|
-
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
// prettier-ignore
|
|
51
|
-
export const LenCode = [
|
|
52
|
-
0x05, 0x03, 0x01, 0x06, 0x0a, 0x02, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
// prettier-ignore
|
|
56
|
-
export const ExLenBits = [
|
|
57
|
-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
// prettier-ignore
|
|
61
|
-
export const LenBase = [
|
|
62
|
-
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
|
63
|
-
0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
// prettier-ignore
|
|
67
|
-
export const ChBitsAsc = [
|
|
68
|
-
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
|
|
69
|
-
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
|
70
|
-
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
|
|
71
|
-
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
|
|
72
|
-
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
|
|
73
|
-
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
|
|
74
|
-
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
|
|
75
|
-
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
|
|
76
|
-
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
|
77
|
-
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
|
78
|
-
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
|
79
|
-
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
|
80
|
-
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
|
81
|
-
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
|
82
|
-
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
|
|
83
|
-
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
|
|
84
|
-
]
|
|
85
|
-
|
|
86
|
-
// prettier-ignore
|
|
87
|
-
export const ChCodeAsc = [
|
|
88
|
-
0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
|
|
89
|
-
0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
|
|
90
|
-
0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
|
|
91
|
-
0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
|
|
92
|
-
0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
|
|
93
|
-
0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
|
|
94
|
-
0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
|
|
95
|
-
0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
|
|
96
|
-
0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
|
|
97
|
-
0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
|
|
98
|
-
0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
|
|
99
|
-
0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
|
|
100
|
-
0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
|
|
101
|
-
0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
|
|
102
|
-
0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
|
|
103
|
-
0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
|
|
104
|
-
0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
|
|
105
|
-
0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
|
|
106
|
-
0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
|
|
107
|
-
0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
|
|
108
|
-
0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
|
|
109
|
-
0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
|
|
110
|
-
0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
|
|
111
|
-
0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
|
|
112
|
-
0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
|
|
113
|
-
0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
|
|
114
|
-
0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
|
|
115
|
-
0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
|
|
116
|
-
0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
|
|
117
|
-
0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
|
|
118
|
-
0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
|
|
119
|
-
0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
|
|
120
|
-
]
|
package/src/errors.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thrown by
|
|
3
|
-
* - `implode` when invalid dictionary size was specified
|
|
4
|
-
* - `explode` when it encounters invalid data in the header section (the first 2 bytes of a compressed files)
|
|
5
|
-
*/
|
|
6
|
-
export class InvalidDictionarySizeError extends Error {
|
|
7
|
-
constructor() {
|
|
8
|
-
super('Invalid dictionary size')
|
|
9
|
-
this.name = 'InvalidDictionarySizeError'
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Thrown by
|
|
15
|
-
* - `implode` when invalid compression type was specified
|
|
16
|
-
* - `explode` when it encounters invalid data in the header section (the first 2 bytes of a compressed files)
|
|
17
|
-
*/
|
|
18
|
-
export class InvalidCompressionTypeError extends Error {
|
|
19
|
-
constructor() {
|
|
20
|
-
super('Invalid compression type')
|
|
21
|
-
this.name = 'InvalidCompressionTypeError'
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Thrown by
|
|
27
|
-
* - `explode`, when compressed data is less, than `5` bytes long
|
|
28
|
-
*
|
|
29
|
-
* Pkware compressed files have 2 bytes header followed by at lest 2 bytes of data and an end literal.
|
|
30
|
-
*/
|
|
31
|
-
export class InvalidDataError extends Error {
|
|
32
|
-
constructor() {
|
|
33
|
-
super('Invalid data')
|
|
34
|
-
this.name = 'InvalidDataError'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Thrown by
|
|
40
|
-
* - `explode` when compressed data ends without reaching the end literal or in mid decompression
|
|
41
|
-
*/
|
|
42
|
-
export class AbortedError extends Error {
|
|
43
|
-
constructor() {
|
|
44
|
-
super('Aborted')
|
|
45
|
-
this.name = 'AbortedError'
|
|
46
|
-
}
|
|
47
|
-
}
|
package/src/functions.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export const repeat = <T>(value: T, repetitions: number): T[] => {
|
|
2
|
-
return Array(repetitions).fill(value)
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const clamp = (min: number, max: number, n: number) => {
|
|
6
|
-
if (n < min) {
|
|
7
|
-
return min
|
|
8
|
-
}
|
|
9
|
-
if (n > max) {
|
|
10
|
-
return max
|
|
11
|
-
}
|
|
12
|
-
return n
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const clone = <T>(data: T): T => {
|
|
16
|
-
return JSON.parse(JSON.stringify(data))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const isFunction = (x: any): x is Function => {
|
|
20
|
-
return Object.prototype.toString.call(x) === '[object Function]'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const nBitsOfOnes = (numberOfBits: number) => {
|
|
24
|
-
if (!Number.isInteger(numberOfBits) || numberOfBits < 0) {
|
|
25
|
-
return 0
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return (1 << numberOfBits) - 1
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const getLowestNBits = (numberOfBits: number, number: number) => {
|
|
32
|
-
return number & nBitsOfOnes(numberOfBits)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const toHex = (num: number, digits: number = 0, withoutPrefix: boolean = false) => {
|
|
36
|
-
if (!Number.isInteger(num) || !Number.isInteger(digits) || digits < 0) {
|
|
37
|
-
return ''
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const prefix = withoutPrefix ? '' : '0x'
|
|
41
|
-
|
|
42
|
-
return `${prefix}${num.toString(16).padStart(digits, '0')}`
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const mergeSparseArrays = <T>(a: T[], b: T[]) => {
|
|
46
|
-
const result = [...b, ...(b.length < a.length ? repeat(undefined, a.length - b.length) : [])]
|
|
47
|
-
|
|
48
|
-
for (let i = 0; i < a.length; i++) {
|
|
49
|
-
if (typeof a[i] !== 'undefined') {
|
|
50
|
-
result[i] = a[i]
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return result
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const last = <T>(arr: T[]) => {
|
|
58
|
-
return arr[arr.length - 1]
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const unfold = <T, TResult>(fn: (seed: T) => [TResult, T] | false, seed: T): TResult[] => {
|
|
62
|
-
let pair = fn(seed)
|
|
63
|
-
const result: TResult[] = []
|
|
64
|
-
while (pair && pair.length) {
|
|
65
|
-
result[result.length] = pair[0]
|
|
66
|
-
pair = fn(pair[1])
|
|
67
|
-
}
|
|
68
|
-
return result
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export const evenAndRemainder = (divisor: number, n: number): [number, number] => {
|
|
72
|
-
return [Math.floor(n / divisor), n % divisor]
|
|
73
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Compression, DictionarySize } from './constants'
|
|
2
|
-
import { Explode } from './Explode'
|
|
3
|
-
import { Implode } from './Implode'
|
|
4
|
-
import { Config } from './types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Decompresses stream
|
|
8
|
-
* @returns a function that you can use as a `transform._transform` method.
|
|
9
|
-
*/
|
|
10
|
-
export const explode = (config: Config = {}) => {
|
|
11
|
-
const instance = new Explode(config)
|
|
12
|
-
return instance.getHandler()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Compresses stream
|
|
17
|
-
* @returns a function that you can use as a `transform._transform` method.
|
|
18
|
-
*/
|
|
19
|
-
export const implode = (compressionType: Compression, dictionarySize: DictionarySize, config: Config = {}) => {
|
|
20
|
-
const instance = new Implode(compressionType, dictionarySize, config)
|
|
21
|
-
return instance.getHandler()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { explode as decompress }
|
|
25
|
-
export { implode as compress }
|
|
26
|
-
|
|
27
|
-
export { Compression, DictionarySize } from './constants'
|
|
28
|
-
export * as errors from './errors'
|
|
29
|
-
export * as stream from './stream'
|
|
30
|
-
export type { Config } from './types'
|
package/src/stream.ts
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { Transform, Writable, TransformCallback } from 'node:stream'
|
|
2
|
-
import { promisify } from 'node:util'
|
|
3
|
-
import { isFunction } from './functions'
|
|
4
|
-
import { ExpandingBuffer } from './ExpandingBuffer'
|
|
5
|
-
import { EMPTY_BUFFER } from './constants'
|
|
6
|
-
|
|
7
|
-
class QuasiTransform {
|
|
8
|
-
#handler: (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) => void
|
|
9
|
-
_flush?: (callback: TransformCallback) => void
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
12
|
-
handler: (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) => void,
|
|
13
|
-
) {
|
|
14
|
-
this.#handler = handler
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
handle(chunk: Buffer, encoding: BufferEncoding): Promise<Buffer> {
|
|
18
|
-
return promisify(this.#handler).call(this, chunk, encoding)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Creates a "**predicate**" function, that awaits Buffers, keeps an internal counter of the bytes from them and splits the appropriate buffer at the given index.
|
|
24
|
-
* Splitting is done by returning an array with `[left: Buffer, right: Buffer, isLeftDone: bool]`.
|
|
25
|
-
* If you want to split data at the 100th byte and you keep feeding 60 byte long buffers to the function returned by `splitAt(100)`, then it will return arrays in the following manner:
|
|
26
|
-
* 1. `[inputBuffer, emptyBuffer, false]`
|
|
27
|
-
* 2. `[inputBuffer.slice(0, 40), inputBuffer.slice(40, 60), true]`
|
|
28
|
-
* 3. `[emptyBuffer, inputBuffer, true]`
|
|
29
|
-
* 4. `[emptyBuffer, inputBuffer, true]`
|
|
30
|
-
* 5. ... and so on
|
|
31
|
-
* @param index - a positive integer at which to split the buffer
|
|
32
|
-
*/
|
|
33
|
-
export const splitAt = (index: number) => {
|
|
34
|
-
let cntr = 0
|
|
35
|
-
|
|
36
|
-
return (chunk: Buffer) => {
|
|
37
|
-
let left: Buffer
|
|
38
|
-
let right: Buffer
|
|
39
|
-
let isLeftDone: boolean
|
|
40
|
-
|
|
41
|
-
if (index <= cntr) {
|
|
42
|
-
// index ..... cntr ..... chunk.length
|
|
43
|
-
left = EMPTY_BUFFER
|
|
44
|
-
right = chunk
|
|
45
|
-
isLeftDone = true
|
|
46
|
-
} else if (index >= cntr + chunk.length) {
|
|
47
|
-
// cntr ..... chunk.length ..... index
|
|
48
|
-
left = chunk
|
|
49
|
-
right = EMPTY_BUFFER
|
|
50
|
-
isLeftDone = index === cntr + chunk.length
|
|
51
|
-
} else {
|
|
52
|
-
// cntr ..... index ..... chunk.length
|
|
53
|
-
left = chunk.subarray(0, index - cntr)
|
|
54
|
-
right = chunk.subarray(index - cntr)
|
|
55
|
-
isLeftDone = true
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
cntr += chunk.length
|
|
59
|
-
|
|
60
|
-
return [left, right, isLeftDone] as [Buffer, Buffer, boolean]
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* A `transform._transform` type function, which lets the input chunks through without any changes
|
|
66
|
-
*/
|
|
67
|
-
export const transformIdentity = () => {
|
|
68
|
-
return function (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) {
|
|
69
|
-
callback(null, chunk)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* A `transform._transform` type function, which for every input chunk will output an empty buffer
|
|
75
|
-
*/
|
|
76
|
-
export const transformEmpty = () => {
|
|
77
|
-
return function (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) {
|
|
78
|
-
callback(null, EMPTY_BUFFER)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Takes a `transform._transform` type function and turns it into a Transform stream instance
|
|
84
|
-
* @param handler a `transform._transform` type function
|
|
85
|
-
* @returns a Transform stream instance
|
|
86
|
-
*/
|
|
87
|
-
export const through = (
|
|
88
|
-
handler: (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) => void,
|
|
89
|
-
) => {
|
|
90
|
-
return new Transform({
|
|
91
|
-
transform: handler,
|
|
92
|
-
})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Higher order function for introducing conditional logic to `transform._transform` functions.
|
|
97
|
-
* This is used internally to handle offsets for `explode()`.
|
|
98
|
-
* @returns a `transform._transform` type function
|
|
99
|
-
*/
|
|
100
|
-
export const transformSplitBy = (
|
|
101
|
-
predicate: (chunk: Buffer) => [Buffer, Buffer, boolean],
|
|
102
|
-
leftHandler: (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) => void,
|
|
103
|
-
rightHandler: (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) => void,
|
|
104
|
-
) => {
|
|
105
|
-
let isFirstChunk = true
|
|
106
|
-
let wasLeftFlushCalled = false
|
|
107
|
-
const damChunkSize = 0x10000
|
|
108
|
-
const dam = new ExpandingBuffer()
|
|
109
|
-
|
|
110
|
-
const leftTransform = new QuasiTransform(leftHandler)
|
|
111
|
-
const rightTransform = new QuasiTransform(rightHandler)
|
|
112
|
-
|
|
113
|
-
return function (this: Transform, chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) {
|
|
114
|
-
const [left, right, isLeftDone] = predicate(chunk)
|
|
115
|
-
|
|
116
|
-
const _left = leftTransform.handle(left, encoding)
|
|
117
|
-
const _right = rightTransform.handle(right, encoding)
|
|
118
|
-
|
|
119
|
-
if (isFirstChunk) {
|
|
120
|
-
isFirstChunk = false
|
|
121
|
-
this._flush = (flushCallback) => {
|
|
122
|
-
if (!dam.isEmpty()) {
|
|
123
|
-
this.push(dam.read())
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const leftFiller = new Promise((resolve, reject) => {
|
|
127
|
-
if (wasLeftFlushCalled || !isFunction(leftTransform._flush)) {
|
|
128
|
-
resolve(EMPTY_BUFFER)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
leftTransform._flush((err, data) => {
|
|
133
|
-
if (err) {
|
|
134
|
-
reject(err)
|
|
135
|
-
} else {
|
|
136
|
-
resolve(data)
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
const rightFiller = new Promise((resolve, reject) => {
|
|
142
|
-
if (!isFunction(rightTransform._flush)) {
|
|
143
|
-
resolve(EMPTY_BUFFER)
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
rightTransform._flush((err, data) => {
|
|
148
|
-
if (err) {
|
|
149
|
-
reject(err)
|
|
150
|
-
} else {
|
|
151
|
-
resolve(data)
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
Promise.all([leftFiller, rightFiller])
|
|
157
|
-
.then((buffers) => {
|
|
158
|
-
// TODO: TransformCallback assumes the returned data is any instead of Buffer
|
|
159
|
-
flushCallback(null, Buffer.concat(buffers as Buffer[]))
|
|
160
|
-
})
|
|
161
|
-
.catch((err) => {
|
|
162
|
-
flushCallback(err)
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const filler = new Promise((resolve, reject) => {
|
|
168
|
-
if (isLeftDone && !wasLeftFlushCalled && isFunction(leftTransform._flush)) {
|
|
169
|
-
wasLeftFlushCalled = true
|
|
170
|
-
leftTransform._flush((err, data) => {
|
|
171
|
-
if (err) {
|
|
172
|
-
reject(err)
|
|
173
|
-
} else {
|
|
174
|
-
resolve(data)
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
} else {
|
|
178
|
-
resolve(EMPTY_BUFFER)
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
Promise.all([_left, filler, _right])
|
|
183
|
-
.then((buffers) => {
|
|
184
|
-
// TODO: TransformCallback assumes the returned data is any instead of Buffer
|
|
185
|
-
dam.append(Buffer.concat(buffers as Buffer[]))
|
|
186
|
-
if (dam.size() > damChunkSize) {
|
|
187
|
-
const chunks = Math.floor(dam.size() / damChunkSize)
|
|
188
|
-
const data = Buffer.from(dam.read(0, chunks * damChunkSize))
|
|
189
|
-
dam.flushStart(chunks * damChunkSize)
|
|
190
|
-
for (let i = 0; i < chunks - 1; i++) {
|
|
191
|
-
this.push(data.subarray(i * damChunkSize, i * damChunkSize + damChunkSize))
|
|
192
|
-
}
|
|
193
|
-
callback(null, data.subarray((chunks - 1) * damChunkSize))
|
|
194
|
-
} else {
|
|
195
|
-
callback(null, EMPTY_BUFFER)
|
|
196
|
-
}
|
|
197
|
-
})
|
|
198
|
-
.catch((err) => {
|
|
199
|
-
callback(err)
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Data can be piped to the returned function from a stream and it will concatenate all chunks into a single buffer.
|
|
206
|
-
* @param done a callback function, which will receive the concatenated buffer as a parameter
|
|
207
|
-
*/
|
|
208
|
-
export const toBuffer = (done: (buffer: Buffer) => void) => {
|
|
209
|
-
const buffer = new ExpandingBuffer()
|
|
210
|
-
return new Writable({
|
|
211
|
-
write(chunk, encoding, callback) {
|
|
212
|
-
buffer.append(chunk)
|
|
213
|
-
callback()
|
|
214
|
-
},
|
|
215
|
-
final(callback) {
|
|
216
|
-
done(buffer.getHeap())
|
|
217
|
-
callback()
|
|
218
|
-
},
|
|
219
|
-
})
|
|
220
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration options for the implode & explode functions.
|
|
3
|
-
*/
|
|
4
|
-
export type Config = {
|
|
5
|
-
/**
|
|
6
|
-
* Whether the code should display extra messages on the console or not
|
|
7
|
-
* @default false
|
|
8
|
-
*/
|
|
9
|
-
verbose?: boolean
|
|
10
|
-
/**
|
|
11
|
-
* The starting size of the input buffer, may expand later as needed.
|
|
12
|
-
* Not having to expand may have positive performance impact.
|
|
13
|
-
* @default 0
|
|
14
|
-
*/
|
|
15
|
-
inputBufferSize?: number
|
|
16
|
-
/**
|
|
17
|
-
* The starting size of the output buffer, may expand later as needed.
|
|
18
|
-
* Not having to expand may have positive performance impact.
|
|
19
|
-
* @default 0
|
|
20
|
-
*/
|
|
21
|
-
outputBufferSize?: number
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type Stats = {
|
|
25
|
-
chunkCounter: number
|
|
26
|
-
}
|