node-pkware 1.0.0-beta.4 → 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.
- package/README.md +2 -2
- package/bin/explode.js +5 -27
- package/bin/implode.js +1 -1
- package/package.json +11 -11
- package/src/explode.js +6 -6
- package/src/helpers/ExpandingBuffer.js +1 -0
- package/src/helpers/stream.js +27 -53
- package/src/helpers/testing.js +5 -0
- package/src/implode.js +38 -34
- package/types/helpers/ExpandingBuffer.d.ts +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Returns a function, that you can use as a [transform.\_transform](https://nodejs
|
|
|
64
64
|
|
|
65
65
|
Takes an optional config object, which has the following properties:
|
|
66
66
|
|
|
67
|
-
```
|
|
67
|
+
```js
|
|
68
68
|
{
|
|
69
69
|
debug: boolean, // whether the code should display debug messages on the console or not (default = false)
|
|
70
70
|
inputBufferSize: int, // the starting size of the input buffer, may expand later as needed. Not having to expand may have performance impact (default 0)
|
|
@@ -78,7 +78,7 @@ Takes an optional config object, which has the following properties:
|
|
|
78
78
|
|
|
79
79
|
Takes an optional config object, which has the following properties:
|
|
80
80
|
|
|
81
|
-
```
|
|
81
|
+
```js
|
|
82
82
|
{
|
|
83
83
|
debug: boolean, // whether the code should display debug messages on the console or not (default = false)
|
|
84
84
|
inputBufferSize: int, // the starting size of the input buffer, may expand later as needed. Not having to expand may have performance impact (default 0)
|
package/bin/explode.js
CHANGED
|
@@ -1,45 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
|
-
const minimist = require('minimist')
|
|
4
|
+
const minimist = require('minimist-lite')
|
|
5
5
|
const { getPackageVersion, parseNumberString, fileExists } = require('../src/helpers/functions.js')
|
|
6
6
|
const { transformEmpty, transformIdentity, transformSplitBy, splitAt, through } = require('../src/helpers/stream.js')
|
|
7
7
|
const { explode } = require('../src/explode.js')
|
|
8
|
-
// const {
|
|
9
|
-
// COMPRESSION_BINARY,
|
|
10
|
-
// COMPRESSION_ASCII,
|
|
11
|
-
// DICTIONARY_SIZE_SMALL,
|
|
12
|
-
// DICTIONARY_SIZE_MEDIUM,
|
|
13
|
-
// DICTIONARY_SIZE_LARGE
|
|
14
|
-
// } = require('../src/constants.js')
|
|
15
8
|
|
|
16
9
|
const args = minimist(process.argv.slice(2), {
|
|
17
10
|
string: ['output', 'offset', 'input-buffer-size', 'output-buffer-size'],
|
|
18
|
-
boolean: ['version', 'drop-before-offset', 'debug'
|
|
11
|
+
boolean: ['version', 'drop-before-offset', 'debug'],
|
|
19
12
|
alias: {
|
|
20
13
|
v: 'version'
|
|
21
14
|
}
|
|
22
15
|
})
|
|
23
16
|
|
|
24
|
-
const decompress = (input, output, offset,
|
|
17
|
+
const decompress = (input, output, offset, keepHeader, config) => {
|
|
25
18
|
const leftHandler = keepHeader ? transformIdentity() : transformEmpty()
|
|
26
19
|
const rightHandler = explode(config)
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// if (autoDetect) {
|
|
31
|
-
// const everyPkwareHeader = [
|
|
32
|
-
// Buffer.from([COMPRESSION_BINARY, DICTIONARY_SIZE_SMALL]),
|
|
33
|
-
// Buffer.from([COMPRESSION_BINARY, DICTIONARY_SIZE_MEDIUM]),
|
|
34
|
-
// Buffer.from([COMPRESSION_BINARY, DICTIONARY_SIZE_LARGE]),
|
|
35
|
-
// Buffer.from([COMPRESSION_ASCII, DICTIONARY_SIZE_SMALL]),
|
|
36
|
-
// Buffer.from([COMPRESSION_ASCII, DICTIONARY_SIZE_MEDIUM]),
|
|
37
|
-
// Buffer.from([COMPRESSION_ASCII, DICTIONARY_SIZE_LARGE])
|
|
38
|
-
// ]
|
|
39
|
-
// handler = transformSplitBy(splitAtMatch(everyPkwareHeader, offset, config.debug), leftHandler, rightHandler)
|
|
40
|
-
// } else if (offset > 0) {
|
|
41
|
-
handler = transformSplitBy(splitAt(offset), leftHandler, rightHandler)
|
|
42
|
-
// }
|
|
21
|
+
const handler = transformSplitBy(splitAt(offset), leftHandler, rightHandler)
|
|
43
22
|
|
|
44
23
|
return new Promise((resolve, reject) => {
|
|
45
24
|
input.pipe(through(handler).on('error', reject)).pipe(output).on('finish', resolve).on('error', reject)
|
|
@@ -79,7 +58,6 @@ const decompress = (input, output, offset, /* autoDetect, */ keepHeader, config)
|
|
|
79
58
|
}
|
|
80
59
|
|
|
81
60
|
const offset = parseNumberString(args.offset, 0)
|
|
82
|
-
// const autoDetect = args['auto-detect']
|
|
83
61
|
|
|
84
62
|
const keepHeader = !args['drop-before-offset']
|
|
85
63
|
const config = {
|
|
@@ -88,7 +66,7 @@ const decompress = (input, output, offset, /* autoDetect, */ keepHeader, config)
|
|
|
88
66
|
outputBufferSize: parseNumberString(args['output-buffer-size'], 0x40000)
|
|
89
67
|
}
|
|
90
68
|
|
|
91
|
-
decompress(input, output, offset,
|
|
69
|
+
decompress(input, output, offset, keepHeader, config)
|
|
92
70
|
.then(() => {
|
|
93
71
|
process.exit(0)
|
|
94
72
|
})
|
package/bin/implode.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-pkware",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "The nodejs implementation of StormLib's pkware compressor/de-compressor",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -28,28 +28,28 @@
|
|
|
28
28
|
"author": "Lajos Meszaros <m_lajos@hotmail.com>",
|
|
29
29
|
"license": "GPL-3.0-or-later",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"minimist": "^
|
|
31
|
+
"minimist-lite": "^2.0.0",
|
|
32
32
|
"ramda": "^0.27.1",
|
|
33
|
-
"ramda-adjunct": "^2.
|
|
33
|
+
"ramda-adjunct": "^2.35.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"arx-header-size": "^0.
|
|
36
|
+
"arx-header-size": "^0.6.1",
|
|
37
37
|
"binary-comparator": "^0.5.0",
|
|
38
|
-
"eslint": "^
|
|
38
|
+
"eslint": "^8.5.0",
|
|
39
39
|
"eslint-config-prettier": "^8.3.0",
|
|
40
40
|
"eslint-config-prettier-standard": "^4.0.1",
|
|
41
41
|
"eslint-config-standard": "^16.0.3",
|
|
42
|
-
"eslint-plugin-import": "^2.
|
|
42
|
+
"eslint-plugin-import": "^2.25.3",
|
|
43
43
|
"eslint-plugin-node": "^11.1.0",
|
|
44
44
|
"eslint-plugin-prettier": "^4.0.0",
|
|
45
|
-
"eslint-plugin-promise": "^
|
|
45
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
46
46
|
"eslint-plugin-ramda": "^2.5.1",
|
|
47
47
|
"eslint-plugin-standard": "^4.1.0",
|
|
48
|
-
"lint-staged": "^
|
|
49
|
-
"mocha": "^9.1.
|
|
50
|
-
"nodemon": "^2.0.
|
|
48
|
+
"lint-staged": "^12.1.3",
|
|
49
|
+
"mocha": "^9.1.3",
|
|
50
|
+
"nodemon": "^2.0.15",
|
|
51
51
|
"pre-commit": "^1.2.2",
|
|
52
|
-
"prettier": "^2.
|
|
52
|
+
"prettier": "^2.5.1",
|
|
53
53
|
"prettier-config-standard": "^4.0.0"
|
|
54
54
|
},
|
|
55
55
|
"pre-commit": [
|
package/src/explode.js
CHANGED
|
@@ -128,9 +128,9 @@ const parseInitialData = (state, debug = false) => {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
if (debug) {
|
|
131
|
-
console.log(`compression type: ${state.compressionType === COMPRESSION_BINARY ? 'binary' : 'ascii'}`)
|
|
131
|
+
console.log(`explode: compression type: ${state.compressionType === COMPRESSION_BINARY ? 'binary' : 'ascii'}`)
|
|
132
132
|
console.log(
|
|
133
|
-
`compression level: ${
|
|
133
|
+
`explode: compression level: ${
|
|
134
134
|
state.dictionarySizeBits === 4 ? 'small' : state.dictionarySizeBits === 5 ? 'medium' : 'large'
|
|
135
135
|
}`
|
|
136
136
|
)
|
|
@@ -331,7 +331,7 @@ const explode = (config = {}) => {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
if (debug) {
|
|
334
|
-
console.log(`reading ${toHex(chunk.length)} bytes from chunk #${state.stats.chunkCounter++}`)
|
|
334
|
+
console.log(`explode: reading ${toHex(chunk.length)} bytes from chunk #${state.stats.chunkCounter++}`)
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
processChunkData(state, debug)
|
|
@@ -369,9 +369,9 @@ const explode = (config = {}) => {
|
|
|
369
369
|
|
|
370
370
|
if (debug) {
|
|
371
371
|
console.log('---------------')
|
|
372
|
-
console.log('total number of chunks read:', state.stats.chunkCounter)
|
|
373
|
-
console.log('inputBuffer heap size', toHex(state.inputBuffer.heapSize()))
|
|
374
|
-
console.log('outputBuffer heap size', toHex(state.outputBuffer.heapSize()))
|
|
372
|
+
console.log('explode: total number of chunks read:', state.stats.chunkCounter)
|
|
373
|
+
console.log('explode: inputBuffer heap size', toHex(state.inputBuffer.heapSize()))
|
|
374
|
+
console.log('explode: outputBuffer heap size', toHex(state.outputBuffer.heapSize()))
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
if (state.needMoreInput) {
|
package/src/helpers/stream.js
CHANGED
|
@@ -3,6 +3,8 @@ const { promisify } = require('util')
|
|
|
3
3
|
const { isFunction } = require('ramda-adjunct')
|
|
4
4
|
const ExpandingBuffer = require('./ExpandingBuffer.js')
|
|
5
5
|
|
|
6
|
+
const emptyBuffer = Buffer.from([])
|
|
7
|
+
|
|
6
8
|
class QuasiTransform {
|
|
7
9
|
constructor(handler) {
|
|
8
10
|
this.handler = handler
|
|
@@ -33,12 +35,12 @@ const splitAt = index => {
|
|
|
33
35
|
|
|
34
36
|
if (index <= cntr) {
|
|
35
37
|
// index ..... cntr ..... chunk.length
|
|
36
|
-
left =
|
|
38
|
+
left = emptyBuffer
|
|
37
39
|
right = chunk
|
|
38
40
|
} else if (index >= cntr + chunk.length) {
|
|
39
41
|
// cntr ..... chunk.length ..... index
|
|
40
42
|
left = chunk
|
|
41
|
-
right =
|
|
43
|
+
right = emptyBuffer
|
|
42
44
|
isLeftDone = index === cntr + chunk.length
|
|
43
45
|
} else {
|
|
44
46
|
// cntr ..... index ..... chunk.length
|
|
@@ -60,7 +62,7 @@ const transformIdentity = () => {
|
|
|
60
62
|
|
|
61
63
|
const transformEmpty = () => {
|
|
62
64
|
return function (chunk, encoding, callback) {
|
|
63
|
-
callback(null,
|
|
65
|
+
callback(null, emptyBuffer)
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -73,6 +75,8 @@ const through = handler => {
|
|
|
73
75
|
const transformSplitBy = (predicate, leftHandler, rightHandler) => {
|
|
74
76
|
let isFirstChunk = true
|
|
75
77
|
let wasLeftFlushCalled = false
|
|
78
|
+
const damChunkSize = 0x10000
|
|
79
|
+
const dam = new ExpandingBuffer()
|
|
76
80
|
|
|
77
81
|
const leftTransform = new QuasiTransform(leftHandler)
|
|
78
82
|
const rightTransform = new QuasiTransform(rightHandler)
|
|
@@ -86,8 +90,12 @@ const transformSplitBy = (predicate, leftHandler, rightHandler) => {
|
|
|
86
90
|
if (isFirstChunk) {
|
|
87
91
|
isFirstChunk = false
|
|
88
92
|
this._flush = flushCallback => {
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
if (!dam.isEmpty()) {
|
|
94
|
+
this.push(dam.read())
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let leftFiller = Promise.resolve(emptyBuffer)
|
|
98
|
+
let rightFiller = Promise.resolve(emptyBuffer)
|
|
91
99
|
|
|
92
100
|
if (!wasLeftFlushCalled && isFunction(leftTransform._flush)) {
|
|
93
101
|
leftFiller = new Promise((resolve, reject) => {
|
|
@@ -123,7 +131,7 @@ const transformSplitBy = (predicate, leftHandler, rightHandler) => {
|
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
|
|
126
|
-
let filler = Promise.resolve(
|
|
134
|
+
let filler = Promise.resolve(emptyBuffer)
|
|
127
135
|
if (isLeftDone && !wasLeftFlushCalled && isFunction(leftTransform._flush)) {
|
|
128
136
|
wasLeftFlushCalled = true
|
|
129
137
|
filler = new Promise((resolve, reject) => {
|
|
@@ -139,7 +147,18 @@ const transformSplitBy = (predicate, leftHandler, rightHandler) => {
|
|
|
139
147
|
|
|
140
148
|
Promise.all([_left, filler, _right])
|
|
141
149
|
.then(buffers => {
|
|
142
|
-
|
|
150
|
+
dam.append(Buffer.concat(buffers))
|
|
151
|
+
if (dam.size() > damChunkSize) {
|
|
152
|
+
const chunks = Math.floor(dam.size() / damChunkSize)
|
|
153
|
+
const data = Buffer.from(dam.read(0, chunks * damChunkSize))
|
|
154
|
+
dam.flushStart(chunks * damChunkSize)
|
|
155
|
+
for (let i = 0; i < chunks - 1; i++) {
|
|
156
|
+
this.push(data.slice(i * damChunkSize, i * damChunkSize + damChunkSize))
|
|
157
|
+
}
|
|
158
|
+
callback(null, data.slice((chunks - 1) * damChunkSize))
|
|
159
|
+
} else {
|
|
160
|
+
callback(null, emptyBuffer)
|
|
161
|
+
}
|
|
143
162
|
})
|
|
144
163
|
.catch(err => {
|
|
145
164
|
callback(err)
|
|
@@ -161,56 +180,11 @@ const streamToBuffer = done => {
|
|
|
161
180
|
})
|
|
162
181
|
}
|
|
163
182
|
|
|
164
|
-
/*
|
|
165
|
-
export const splitAtMatch = (matches, skipBytes = 0, debug = false) => {
|
|
166
|
-
let alreadyMatched = false
|
|
167
|
-
const empty = Buffer.from([])
|
|
168
|
-
|
|
169
|
-
return (chunk, offset) => {
|
|
170
|
-
if (alreadyMatched) {
|
|
171
|
-
return {
|
|
172
|
-
left: empty,
|
|
173
|
-
right: chunk
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const idxs = matches
|
|
178
|
-
.map(bytes => chunk.indexOf(bytes))
|
|
179
|
-
.filter(idx => idx > -1)
|
|
180
|
-
.sort(subtract)
|
|
181
|
-
.filter(idx => idx + offset >= skipBytes)
|
|
182
|
-
|
|
183
|
-
if (idxs.length === 0) {
|
|
184
|
-
return {
|
|
185
|
-
left: empty,
|
|
186
|
-
right: chunk
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
alreadyMatched = true
|
|
191
|
-
if (debug) {
|
|
192
|
-
console.log(`found pkware header ${dumpBytes(chunk.slice(idxs[0], idxs[0] + 2))} at ${toHex(idxs[0])}`)
|
|
193
|
-
}
|
|
194
|
-
return splitAtIndex(idxs[0])(chunk, offset)
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
*/
|
|
198
|
-
|
|
199
|
-
const outputInChunks = (buffer, stream) => {
|
|
200
|
-
const chunks = Math.ceil(buffer.length / 1000)
|
|
201
|
-
for (let i = 0; i < chunks - 1; i++) {
|
|
202
|
-
stream.write(buffer.slice(i * 1000, (i + 1) * 1000))
|
|
203
|
-
}
|
|
204
|
-
stream.write(buffer.slice((chunks - 1) * 1000))
|
|
205
|
-
stream.end()
|
|
206
|
-
}
|
|
207
|
-
|
|
208
183
|
module.exports = {
|
|
209
184
|
splitAt,
|
|
210
185
|
transformIdentity,
|
|
211
186
|
transformEmpty,
|
|
212
187
|
through,
|
|
213
188
|
transformSplitBy,
|
|
214
|
-
streamToBuffer
|
|
215
|
-
outputInChunks
|
|
189
|
+
streamToBuffer
|
|
216
190
|
}
|
package/src/helpers/testing.js
CHANGED
|
@@ -54,6 +54,11 @@ const buffersShouldEqual = (expected, result, offset = 0, displayAsHex = false)
|
|
|
54
54
|
if (!Buffer.isBuffer(expected)) {
|
|
55
55
|
throw new Error('expected is not a Buffer')
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
if (!Buffer.isBuffer(result)) {
|
|
59
|
+
throw new Error('result is not a Buffer')
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
const diff = report(expected, result, compare(expected, result, offset), displayAsHex)
|
|
58
63
|
assert.ok(expected.equals(result), diff)
|
|
59
64
|
}
|
package/src/implode.js
CHANGED
|
@@ -114,7 +114,9 @@ const getSizeOfMatching = (inputBytes, a, b) => {
|
|
|
114
114
|
// us to store backward length in less amount of bits
|
|
115
115
|
// currently the code goes from the furthest point
|
|
116
116
|
const findRepetitions = (inputBytes, endOfLastMatch, cursor) => {
|
|
117
|
-
|
|
117
|
+
const notEnoughBytes = inputBytes.length - cursor < 2
|
|
118
|
+
const tooClose = cursor === endOfLastMatch || cursor - endOfLastMatch < 2
|
|
119
|
+
if (notEnoughBytes || tooClose) {
|
|
118
120
|
return { size: 0, distance: 0 }
|
|
119
121
|
}
|
|
120
122
|
|
|
@@ -191,41 +193,37 @@ const processChunkData = (state, debug = false) => {
|
|
|
191
193
|
|
|
192
194
|
/* eslint-disable prefer-const */
|
|
193
195
|
|
|
194
|
-
let endOfLastMatch = 0
|
|
196
|
+
let endOfLastMatch = 0 // used when searching for longer repetitions later
|
|
195
197
|
while (state.startIndex < state.inputBuffer.size()) {
|
|
196
198
|
let { size, distance } = findRepetitions(state.inputBuffer.read(endOfLastMatch), endOfLastMatch, state.startIndex)
|
|
197
199
|
|
|
198
|
-
|
|
200
|
+
let isFlushable = isRepetitionFlushable(size, distance, state.startIndex, state.inputBuffer.size())
|
|
199
201
|
|
|
200
202
|
if (isFlushable === false) {
|
|
201
203
|
const byte = state.inputBuffer.read(state.startIndex, 1)
|
|
202
204
|
outputBits(state, state.nChBits[byte], state.nChCodes[byte])
|
|
203
205
|
state.startIndex += 1
|
|
204
206
|
} else {
|
|
205
|
-
/*
|
|
206
207
|
if (isFlushable === null) {
|
|
208
|
+
/*
|
|
207
209
|
// Try to find better repetition 1 byte later.
|
|
208
210
|
// stormlib/implode.c L517
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
211
|
+
let cursor = state.startIndex
|
|
212
|
+
let newSize = size
|
|
213
|
+
let newDistance = distance
|
|
214
|
+
let currentSize
|
|
215
|
+
let currentDistance
|
|
216
|
+
while (newSize <= currentSize && isRepetitionFlushable(newSize, newDistance, state.startIndex, state.inputBuffer.size())) {
|
|
217
|
+
currentSize = newSize
|
|
218
|
+
currentDistance = newDistance
|
|
219
|
+
const reps = findRepetitions(state.inputBuffer.read(endOfLastMatch), endOfLastMatch, ++cursor)
|
|
220
|
+
newSize = reps.size
|
|
221
|
+
newDistance = reps.distance
|
|
222
|
+
}
|
|
223
|
+
size = newSize
|
|
224
|
+
distance = currentDistance
|
|
225
|
+
*/
|
|
224
226
|
}
|
|
225
|
-
*/
|
|
226
|
-
|
|
227
|
-
/*
|
|
228
|
-
endOfLastMatch = state.startIndex + size
|
|
229
227
|
|
|
230
228
|
const byte = size + 0xfe
|
|
231
229
|
outputBits(state, state.nChBits[byte], state.nChCodes[byte])
|
|
@@ -240,18 +238,24 @@ const processChunkData = (state, debug = false) => {
|
|
|
240
238
|
}
|
|
241
239
|
|
|
242
240
|
state.startIndex += size
|
|
243
|
-
*/
|
|
244
|
-
|
|
245
|
-
// TODO: temporarily write out data byte-by-byte here too, because above block with minimal repetition
|
|
246
|
-
// flushing breaks the compression self check tests
|
|
247
|
-
const byte = state.inputBuffer.read(state.startIndex, 1)
|
|
248
|
-
outputBits(state, state.nChBits[byte], state.nChCodes[byte])
|
|
249
|
-
state.startIndex += 1
|
|
250
241
|
}
|
|
251
242
|
|
|
243
|
+
/*
|
|
252
244
|
state.inputBuffer.dropStart(endOfLastMatch)
|
|
253
245
|
state.startIndex -= endOfLastMatch
|
|
254
246
|
endOfLastMatch = 0
|
|
247
|
+
*/
|
|
248
|
+
|
|
249
|
+
if (state.dictionarySizeBits === DICTIONARY_SIZE_SMALL && state.startIndex >= 0x400) {
|
|
250
|
+
state.inputBuffer.dropStart(0x400)
|
|
251
|
+
state.startIndex -= 0x400
|
|
252
|
+
} else if (state.dictionarySizeBits === DICTIONARY_SIZE_MEDIUM && state.startIndex >= 0x800) {
|
|
253
|
+
state.inputBuffer.dropStart(0x800)
|
|
254
|
+
state.startIndex -= 0x800
|
|
255
|
+
} else if (state.dictionarySizeBits === DICTIONARY_SIZE_LARGE && state.startIndex >= 0x1000) {
|
|
256
|
+
state.inputBuffer.dropStart(0x1000)
|
|
257
|
+
state.startIndex -= 0x1000
|
|
258
|
+
}
|
|
255
259
|
}
|
|
256
260
|
|
|
257
261
|
/* eslint-enable prefer-const */
|
|
@@ -286,7 +290,7 @@ const implode = (compressionType, dictionarySizeBits, config = {}) => {
|
|
|
286
290
|
}
|
|
287
291
|
|
|
288
292
|
if (debug) {
|
|
289
|
-
console.log(`reading ${toHex(chunk.length)} bytes from chunk #${state.stats.chunkCounter++}`)
|
|
293
|
+
console.log(`implode: reading ${toHex(chunk.length)} bytes from chunk #${state.stats.chunkCounter++}`)
|
|
290
294
|
}
|
|
291
295
|
|
|
292
296
|
processChunkData(state, debug)
|
|
@@ -331,9 +335,9 @@ const implode = (compressionType, dictionarySizeBits, config = {}) => {
|
|
|
331
335
|
|
|
332
336
|
if (debug) {
|
|
333
337
|
console.log('---------------')
|
|
334
|
-
console.log('total number of chunks read:', state.stats.chunkCounter)
|
|
335
|
-
console.log('inputBuffer heap size', toHex(state.inputBuffer.heapSize()))
|
|
336
|
-
console.log('outputBuffer heap size', toHex(state.outputBuffer.heapSize()))
|
|
338
|
+
console.log('implode: total number of chunks read:', state.stats.chunkCounter)
|
|
339
|
+
console.log('implode: inputBuffer heap size', toHex(state.inputBuffer.heapSize()))
|
|
340
|
+
console.log('implode: outputBuffer heap size', toHex(state.outputBuffer.heapSize()))
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
callback(null, state.outputBuffer.read())
|
|
@@ -13,7 +13,7 @@ declare class ExpandingBuffer {
|
|
|
13
13
|
isEmpty(): boolean
|
|
14
14
|
heapSize(): number
|
|
15
15
|
append(buffer: Buffer): void
|
|
16
|
-
read(offset
|
|
16
|
+
read(offset?: number, limit?: number): number | Buffer
|
|
17
17
|
flushStart(numberOfBytes: number): void
|
|
18
18
|
flushEnd(numberOfBytes: number): void
|
|
19
19
|
dropStart(numberOfBytes: number): void
|