Skip to content

Commit 6ce5ed5

Browse files
authored
Merge pull request #21 from Brooooooklyn/as-buffer
fix: missing asBuffer option in uncompress/uncompressSync
2 parents c20f65d + ac573f8 commit 6ce5ed5

File tree

4 files changed

+62
-14
lines changed

4 files changed

+62
-14
lines changed

__test__/index.spec.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,22 @@ test('compress should be async version of compressSync', async (t) => {
1212
t.deepEqual(await compress(fixture), compressSync(fixture))
1313
})
1414

15-
test('should be able to decompress sync', (t) => {
15+
test('should be able to uncompress sync', (t) => {
1616
const fixture = 'hello world 😂 🎧 🚀'
1717
t.deepEqual(uncompressSync(compressSync(fixture)), Buffer.from(fixture))
1818
})
1919

20-
test('should be able to decompress', async (t) => {
20+
test('should be able to uncompress sync into string', (t) => {
21+
const fixture = 'hello world 😂 🎧 🚀'
22+
t.deepEqual(uncompressSync(compressSync(fixture), { asBuffer: false }), fixture)
23+
})
24+
25+
test('should be able to uncompress', async (t) => {
2126
const fixture = 'hello world 😂 🎧 🚀'
2227
t.deepEqual(await uncompress(await compress(fixture)), Buffer.from(fixture))
2328
})
29+
30+
test('should be able to uncompress into string', async (t) => {
31+
const fixture = 'hello world 😂 🎧 🚀'
32+
t.deepEqual(await uncompress(await compress(fixture), { asBuffer: false }), fixture)
33+
})

index.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
export function compressSync(input: Buffer | string | ArrayBuffer | Uint8Array): Buffer
22
export function compress(input: Buffer | string | ArrayBuffer | Uint8Array): Promise<Buffer>
33
export function uncompressSync(compressed: Buffer): Buffer
4+
export function uncompressSync(compressed: Buffer, opt: { asBuffer: true }): Buffer
5+
export function uncompressSync(compressed: Buffer, opt: { asBuffer: false }): string
6+
export function uncompressSync(compressed: Buffer, opt?: { asBuffer: boolean }): string | Buffer
47
export function uncompress(compressed: Buffer): Promise<Buffer>
8+
export function uncompress(compressed: Buffer, opt: { asBuffer: true }): Promise<Buffer>
9+
export function uncompress(compressed: Buffer, opt: { asBuffer: false }): Promise<string>
10+
export function uncompress(compressed: Buffer, opt?: { asBuffer: boolean }): Promise<string | Buffer>

index.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ const { loadBinding } = require('@node-rs/helper')
33
const {
44
compressSync: _compressSync,
55
compress: _compress,
6-
uncompress,
7-
uncompressSync,
6+
uncompress: _uncompress,
7+
uncompressSync: _uncompressSync,
88
} = loadBinding(__dirname, 'snappy', '@napi-rs/snappy')
99

1010
module.exports = {
@@ -14,6 +14,10 @@ module.exports = {
1414
compress: function compress(input) {
1515
return _compress(Buffer.from(input))
1616
},
17-
uncompress,
18-
uncompressSync,
17+
uncompress: function uncompress(input, opt = { asBuffer: true }) {
18+
return _uncompress(input, Boolean(opt.asBuffer))
19+
},
20+
uncompressSync: function uncompressSync(input, opt = { asBuffer: true }) {
21+
return _uncompressSync(input, Boolean(opt.asBuffer))
22+
},
1923
}

src/lib.rs

+36-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
#[macro_use]
44
extern crate napi_derive;
55

6-
use napi::{CallContext, Env, Error, JsBuffer, JsBufferValue, JsObject, Ref, Result, Status, Task};
6+
use std::ffi::CString;
7+
8+
use napi::{
9+
CallContext, Env, Error, JsBoolean, JsBuffer, JsBufferValue, JsObject, JsUnknown, Ref, Result,
10+
Status, Task,
11+
};
712
use snap::raw::{Decoder, Encoder};
813

914
#[cfg(all(
@@ -48,11 +53,12 @@ impl Task for Enc {
4853
struct Dec {
4954
inner: Decoder,
5055
data: Ref<JsBufferValue>,
56+
as_buffer: bool,
5157
}
5258

5359
impl Task for Dec {
5460
type Output = Vec<u8>;
55-
type JsValue = JsBuffer;
61+
type JsValue = JsUnknown;
5662

5763
fn compute(&mut self) -> Result<Self::Output> {
5864
let data_ref: &[u8] = &self.data;
@@ -63,7 +69,15 @@ impl Task for Dec {
6369
}
6470

6571
fn resolve(self, env: Env, output: Self::Output) -> Result<Self::JsValue> {
66-
env.create_buffer_with_data(output).map(|b| b.into_raw())
72+
if self.as_buffer {
73+
env
74+
.create_buffer_with_data(output)
75+
.map(|b| b.into_raw().into_unknown())
76+
} else {
77+
let len = output.len();
78+
let c_string = CString::new(output)?;
79+
unsafe { env.create_string_from_c_char(c_string.as_ptr(), len) }.map(|v| v.into_unknown())
80+
}
6781
}
6882
}
6983

@@ -89,24 +103,38 @@ fn compress(ctx: CallContext) -> Result<JsObject> {
89103
ctx.env.spawn(encoder).map(|v| v.promise_object())
90104
}
91105

92-
#[js_function(1)]
93-
fn uncompress_sync(ctx: CallContext) -> Result<JsBuffer> {
106+
#[js_function(2)]
107+
fn uncompress_sync(ctx: CallContext) -> Result<JsUnknown> {
94108
let data = ctx.get::<JsBuffer>(0)?;
109+
let as_buffer = ctx.get::<JsBoolean>(1)?.get_value()?;
95110
let mut dec = Decoder::new();
96111
dec
97112
.decompress_vec(&data.into_value()?)
98113
.map_err(|e| Error::new(napi::Status::GenericFailure, format!("{}", e)))
99-
.and_then(|d| ctx.env.create_buffer_with_data(d))
100-
.map(|b| b.into_raw())
114+
.and_then(|d| {
115+
if as_buffer {
116+
ctx
117+
.env
118+
.create_buffer_with_data(d)
119+
.map(|b| b.into_raw().into_unknown())
120+
} else {
121+
let len = d.len();
122+
let c_string = CString::new(d)?;
123+
unsafe { ctx.env.create_string_from_c_char(c_string.as_ptr(), len) }
124+
.map(|v| v.into_unknown())
125+
}
126+
})
101127
}
102128

103-
#[js_function(1)]
129+
#[js_function(2)]
104130
fn uncompress(ctx: CallContext) -> Result<JsObject> {
105131
let data = ctx.get::<JsBuffer>(0)?;
132+
let as_buffer = ctx.get::<JsBoolean>(1)?.get_value()?;
106133
let dec = Decoder::new();
107134
let decoder = Dec {
108135
inner: dec,
109136
data: data.into_ref()?,
137+
as_buffer,
110138
};
111139
ctx.env.spawn(decoder).map(|v| v.promise_object())
112140
}

0 commit comments

Comments
 (0)