-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.js
40 lines (32 loc) · 1.07 KB
/
index.js
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
const snappy = require('snappyjs')
const XERIAL_HEADER = Buffer.from([130, 83, 78, 65, 80, 80, 89, 0])
const SIZE_BYTES = 4
const SIZE_OFFSET = 16
const isFrameFormat = buffer => buffer.slice(0, 8).equals(XERIAL_HEADER)
module.exports = () => ({
async compress(encoder) {
return snappy.compress(encoder.buffer)
},
// Based on https://github.com/eapache/go-xerial-snappy/blob/master/snappy.go#L110
async decompress(buffer) {
if (!isFrameFormat(buffer)) {
return snappy.uncompress(buffer)
}
const encoded = []
const maxBytes = Buffer.byteLength(buffer)
let offset = SIZE_OFFSET
while (offset + SIZE_BYTES <= maxBytes) {
const size = buffer.readUInt32BE(offset)
offset += SIZE_BYTES
encoded.push(buffer.slice(offset, offset + size))
offset += size
}
const decodedBuffers = await Promise.all(
encoded.map(async encodedBuffer => snappy.uncompress(encodedBuffer))
)
return decodedBuffers.reduce(
(result, decodedBuffer) => Buffer.concat([result, decodedBuffer]),
Buffer.alloc(0)
)
},
})