Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 566 lines (450 sloc) 15.787 kb
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
23 #include "v8.h"
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
24 #include <errno.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <sys/types.h>
28
531eba1 @bnoordhuis zlib: fix include of zlib.h
bnoordhuis authored
29 #include "zlib.h"
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
30 #include "node.h"
31 #include "node_buffer.h"
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
32
33
34 namespace node {
35 using namespace v8;
36
37
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
38 static Persistent<String> callback_sym;
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
39 static Persistent<String> onerror_sym;
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
40
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
41 enum node_zlib_mode {
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
42 NONE,
43 DEFLATE,
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
44 INFLATE,
45 GZIP,
46 GUNZIP,
47 DEFLATERAW,
48 INFLATERAW,
49 UNZIP
50 };
51
52
53 void InitZlib(v8::Handle<v8::Object> target);
54
55
56 /**
57 * Deflate/Inflate
58 */
44eb279 zlib: don't use C++ templates
ssuda authored
59 class ZCtx : public ObjectWrap {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
60 public:
61
ef94521 @bnoordhuis zlib: fix assert on bad input
bnoordhuis authored
62 ZCtx(node_zlib_mode mode)
63 : ObjectWrap()
64 , init_done_(false)
65 , level_(0)
66 , windowBits_(0)
67 , memLevel_(0)
68 , strategy_(0)
69 , err_(0)
70 , dictionary_(NULL)
71 , dictionary_len_(0)
72 , flush_(0)
73 , chunk_size_(0)
74 , write_in_progress_(false)
75 , mode_(mode)
76 {
77 }
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
78
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
79
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
80 ~ZCtx() {
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
81 Close();
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
82 }
83
84
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
85 void Close() {
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
86 assert(!write_in_progress_ && "write in progress");
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
87 assert(init_done_ && "close before init");
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
88 assert(mode_ <= UNZIP);
89
44eb279 zlib: don't use C++ templates
ssuda authored
90 if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
91 (void)deflateEnd(&strm_);
a93424d @bnoordhuis zlib: pass object size hint to V8
bnoordhuis authored
92 V8::AdjustAmountOfExternalAllocatedMemory(-kDeflateContextSize);
bf539f9 @isaacs zlib: Call inflateEnd for UNZIP. Fixes memory leak.
isaacs authored
93 } else if (mode_ == INFLATE || mode_ == GUNZIP || mode_ == INFLATERAW ||
94 mode_ == UNZIP) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
95 (void)inflateEnd(&strm_);
a93424d @bnoordhuis zlib: pass object size hint to V8
bnoordhuis authored
96 V8::AdjustAmountOfExternalAllocatedMemory(-kInflateContextSize);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
97 }
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
98 mode_ = NONE;
99
100 if (dictionary_ != NULL) {
101 delete[] dictionary_;
102 dictionary_ = NULL;
103 }
104 }
105
e609195 @indutny [zlib] added dictionary support
indutny authored
106
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
107 static Handle<Value> Close(const Arguments& args) {
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
108 HandleScope scope;
109 ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
110 ctx->Close();
51f6e6a @bnoordhuis src, test: downgrade to v8 3.14 api
bnoordhuis authored
111 return scope.Close(Undefined());
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
112 }
113
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
114
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
115 // write(flush, in, in_off, in_len, out, out_off, out_len)
07701e7 @indutny zlib: C++ style fixes
indutny authored
116 static Handle<Value> Write(const Arguments& args) {
d104bfd @isaacs zlib: Fix test so that it's not trivially passing, then pass it.
isaacs authored
117 HandleScope scope;
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
118 assert(args.Length() == 7);
119
44eb279 zlib: don't use C++ templates
ssuda authored
120 ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
121 assert(ctx->init_done_ && "write before init");
570e4be @bnoordhuis zlib: reduce memory consumption, release early
bnoordhuis authored
122 assert(ctx->mode_ != NONE && "already finalized");
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
123
8cca30f @isaacs zlib binding cleanup
isaacs authored
124 assert(!ctx->write_in_progress_ && "write already in progress");
125 ctx->write_in_progress_ = true;
ef94521 @bnoordhuis zlib: fix assert on bad input
bnoordhuis authored
126 ctx->Ref();
8cca30f @isaacs zlib binding cleanup
isaacs authored
127
0e01d63 @isaacs zlib: streams2
isaacs authored
128 assert(!args[0]->IsUndefined() && "must provide flush value");
129
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
130 unsigned int flush = args[0]->Uint32Value();
0e01d63 @isaacs zlib: streams2
isaacs authored
131
132 if (flush != Z_NO_FLUSH &&
133 flush != Z_PARTIAL_FLUSH &&
134 flush != Z_SYNC_FLUSH &&
135 flush != Z_FULL_FLUSH &&
136 flush != Z_FINISH &&
137 flush != Z_BLOCK) {
138 assert(0 && "Invalid flush value");
139 }
140
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
141 Bytef *in;
142 Bytef *out;
143 size_t in_off, in_len, out_off, out_len;
144
145 if (args[1]->IsNull()) {
146 // just a flush
147 Bytef nada[1] = { 0 };
148 in = nada;
149 in_len = 0;
150 in_off = 0;
151 } else {
152 assert(Buffer::HasInstance(args[1]));
153 Local<Object> in_buf;
154 in_buf = args[1]->ToObject();
07701e7 @indutny zlib: C++ style fixes
indutny authored
155 in_off = args[2]->Uint32Value();
156 in_len = args[3]->Uint32Value();
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
157
158 assert(in_off + in_len <= Buffer::Length(in_buf));
159 in = reinterpret_cast<Bytef *>(Buffer::Data(in_buf) + in_off);
160 }
161
162 assert(Buffer::HasInstance(args[4]));
163 Local<Object> out_buf = args[4]->ToObject();
07701e7 @indutny zlib: C++ style fixes
indutny authored
164 out_off = args[5]->Uint32Value();
165 out_len = args[6]->Uint32Value();
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
166 assert(out_off + out_len <= Buffer::Length(out_buf));
167 out = reinterpret_cast<Bytef *>(Buffer::Data(out_buf) + out_off);
168
8cca30f @isaacs zlib binding cleanup
isaacs authored
169 // build up the work request
170 uv_work_t* work_req = &(ctx->work_req_);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
171
172 ctx->strm_.avail_in = in_len;
07701e7 @indutny zlib: C++ style fixes
indutny authored
173 ctx->strm_.next_in = in;
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
174 ctx->strm_.avail_out = out_len;
175 ctx->strm_.next_out = out;
176 ctx->flush_ = flush;
177
178 // set this so that later on, I can easily tell how much was written.
179 ctx->chunk_size_ = out_len;
180
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
181 uv_queue_work(uv_default_loop(),
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
182 work_req,
44eb279 zlib: don't use C++ templates
ssuda authored
183 ZCtx::Process,
184 ZCtx::After);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
185
8cca30f @isaacs zlib binding cleanup
isaacs authored
186 return ctx->handle_;
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
187 }
188
189
190 // thread pool!
191 // This function may be called multiple times on the uv_work pool
192 // for a single write() call, until all of the input bytes have
193 // been consumed.
07701e7 @indutny zlib: C++ style fixes
indutny authored
194 static void Process(uv_work_t* work_req) {
44eb279 zlib: don't use C++ templates
ssuda authored
195 ZCtx *ctx = container_of(work_req, ZCtx, work_req_);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
196
197 // If the avail_out is left at 0, then it means that it ran out
198 // of room. If there was avail_out left over, then it means
199 // that all of the input was consumed.
44eb279 zlib: don't use C++ templates
ssuda authored
200 switch (ctx->mode_) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
201 case DEFLATE:
202 case GZIP:
203 case DEFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
204 ctx->err_ = deflate(&ctx->strm_, ctx->flush_);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
205 break;
206 case UNZIP:
207 case INFLATE:
208 case GUNZIP:
209 case INFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
210 ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
e609195 @indutny [zlib] added dictionary support
indutny authored
211
212 // If data was encoded with dictionary
1c32eb4 @bnoordhuis zlib: don't assert on missing dictionary
bnoordhuis authored
213 if (ctx->err_ == Z_NEED_DICT && ctx->dictionary_ != NULL) {
214
215 // Load it
216 ctx->err_ = inflateSetDictionary(&ctx->strm_,
217 ctx->dictionary_,
218 ctx->dictionary_len_);
219 if (ctx->err_ == Z_OK) {
220
221 // And try to decode again
222 ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
d7bf7ed @bnoordhuis zlib: don't assert on malformed dictionary
bnoordhuis authored
223 } else if (ctx->err_ == Z_DATA_ERROR) {
224
225 // Both inflateSetDictionary() and inflate() return Z_DATA_ERROR.
226 // Make it possible for After() to tell a bad dictionary from bad
227 // input.
228 ctx->err_ = Z_NEED_DICT;
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
229 }
e609195 @indutny [zlib] added dictionary support
indutny authored
230 }
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
231 break;
232 default:
233 assert(0 && "wtf?");
234 }
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
235
236 // pass any errors back to the main thread to deal with.
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
237
238 // now After will emit the output, and
239 // either schedule another call to Process,
240 // or shift the queue and call Process.
241 }
242
243 // v8 land!
6cf68ae @bnoordhuis deps: upgrade libuv to e079a99
bnoordhuis authored
244 static void After(uv_work_t* work_req, int status) {
245 assert(status == 0);
246
d104bfd @isaacs zlib: Fix test so that it's not trivially passing, then pass it.
isaacs authored
247 HandleScope scope;
44eb279 zlib: don't use C++ templates
ssuda authored
248 ZCtx *ctx = container_of(work_req, ZCtx, work_req_);
07701e7 @indutny zlib: C++ style fixes
indutny authored
249
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
250 // Acceptable error states depend on the type of zlib stream.
251 switch (ctx->err_) {
252 case Z_OK:
253 case Z_STREAM_END:
254 case Z_BUF_ERROR:
255 // normal statuses, not fatal
256 break;
1c32eb4 @bnoordhuis zlib: don't assert on missing dictionary
bnoordhuis authored
257 case Z_NEED_DICT:
d7bf7ed @bnoordhuis zlib: don't assert on malformed dictionary
bnoordhuis authored
258 if (ctx->dictionary_ == NULL) {
259 ZCtx::Error(ctx, "Missing dictionary");
260 } else {
261 ZCtx::Error(ctx, "Bad dictionary");
262 }
1c32eb4 @bnoordhuis zlib: don't assert on missing dictionary
bnoordhuis authored
263 return;
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
264 default:
265 // something else.
266 ZCtx::Error(ctx, "Zlib error");
267 return;
268 }
269
51f6e6a @bnoordhuis src, test: downgrade to v8 3.14 api
bnoordhuis authored
270 Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out);
271 Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
272
8cca30f @isaacs zlib binding cleanup
isaacs authored
273 ctx->write_in_progress_ = false;
274
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
275 // call the write() cb
8cca30f @isaacs zlib binding cleanup
isaacs authored
276 assert(ctx->handle_->Get(callback_sym)->IsFunction() &&
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
277 "Invalid callback");
278 Local<Value> args[2] = { avail_in, avail_out };
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
279 MakeCallback(ctx->handle_, callback_sym, ARRAY_SIZE(args), args);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
280
0ad2717 @bnoordhuis Make sure that zlib contexts are not garbage collected when busy
bnoordhuis authored
281 ctx->Unref();
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
282 }
283
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
284 static void Error(ZCtx *ctx, const char *msg_) {
285 const char *msg;
286 if (ctx->strm_.msg != NULL) {
287 msg = ctx->strm_.msg;
288 } else {
289 msg = msg_;
290 }
291
292 assert(ctx->handle_->Get(onerror_sym)->IsFunction() &&
293 "Invalid error handler");
294 HandleScope scope;
295 Local<Value> args[2] = { String::New(msg),
51f6e6a @bnoordhuis src, test: downgrade to v8 3.14 api
bnoordhuis authored
296 Local<Value>::New(Number::New(ctx->err_)) };
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
297 MakeCallback(ctx->handle_, onerror_sym, ARRAY_SIZE(args), args);
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
298
299 // no hope of rescue.
ef94521 @bnoordhuis zlib: fix assert on bad input
bnoordhuis authored
300 ctx->write_in_progress_ = false;
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
301 ctx->Unref();
302 }
303
07701e7 @indutny zlib: C++ style fixes
indutny authored
304 static Handle<Value> New(const Arguments& args) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
305 HandleScope scope;
44eb279 zlib: don't use C++ templates
ssuda authored
306 if (args.Length() < 1 || !args[0]->IsInt32()) {
307 return ThrowException(Exception::TypeError(String::New("Bad argument")));
308 }
309 node_zlib_mode mode = (node_zlib_mode) args[0]->Int32Value();
310
311 if (mode < DEFLATE || mode > UNZIP) {
312 return ThrowException(Exception::TypeError(String::New("Bad argument")));
313 }
314
315 ZCtx *ctx = new ZCtx(mode);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
316 ctx->Wrap(args.This());
317 return args.This();
318 }
319
320 // just pull the ints out of the args and call the other Init
07701e7 @indutny zlib: C++ style fixes
indutny authored
321 static Handle<Value> Init(const Arguments& args) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
322 HandleScope scope;
323
e609195 @indutny [zlib] added dictionary support
indutny authored
324 assert((args.Length() == 4 || args.Length() == 5) &&
325 "init(windowBits, level, memLevel, strategy, [dictionary])");
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
326
44eb279 zlib: don't use C++ templates
ssuda authored
327 ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
328
329 int windowBits = args[0]->Uint32Value();
330 assert((windowBits >= 8 && windowBits <= 15) && "invalid windowBits");
331
332 int level = args[1]->Uint32Value();
333 assert((level >= -1 && level <= 9) && "invalid compression level");
334
335 int memLevel = args[2]->Uint32Value();
336 assert((memLevel >= 1 && memLevel <= 9) && "invalid memlevel");
337
338 int strategy = args[3]->Uint32Value();
339 assert((strategy == Z_FILTERED ||
340 strategy == Z_HUFFMAN_ONLY ||
341 strategy == Z_RLE ||
342 strategy == Z_FIXED ||
343 strategy == Z_DEFAULT_STRATEGY) && "invalid strategy");
344
e609195 @indutny [zlib] added dictionary support
indutny authored
345 char* dictionary = NULL;
346 size_t dictionary_len = 0;
347 if (args.Length() >= 5 && Buffer::HasInstance(args[4])) {
348 Local<Object> dictionary_ = args[4]->ToObject();
349
350 dictionary_len = Buffer::Length(dictionary_);
351 dictionary = new char[dictionary_len];
352
353 memcpy(dictionary, Buffer::Data(dictionary_), dictionary_len);
354 }
355
356 Init(ctx, level, windowBits, memLevel, strategy,
357 dictionary, dictionary_len);
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
358 SetDictionary(ctx);
51f6e6a @bnoordhuis src, test: downgrade to v8 3.14 api
bnoordhuis authored
359 return Undefined();
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
360 }
361
362 static Handle<Value> Reset(const Arguments &args) {
363 HandleScope scope;
364
44eb279 zlib: don't use C++ templates
ssuda authored
365 ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
366
367 Reset(ctx);
368 SetDictionary(ctx);
51f6e6a @bnoordhuis src, test: downgrade to v8 3.14 api
bnoordhuis authored
369 return Undefined();
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
370 }
371
07701e7 @indutny zlib: C++ style fixes
indutny authored
372 static void Init(ZCtx *ctx, int level, int windowBits, int memLevel,
9e6957b @indutny Merge branch 'v0.6'
indutny authored
373 int strategy, char* dictionary, size_t dictionary_len) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
374 ctx->level_ = level;
375 ctx->windowBits_ = windowBits;
376 ctx->memLevel_ = memLevel;
377 ctx->strategy_ = strategy;
378
379 ctx->strm_.zalloc = Z_NULL;
380 ctx->strm_.zfree = Z_NULL;
381 ctx->strm_.opaque = Z_NULL;
382
383 ctx->flush_ = Z_NO_FLUSH;
384
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
385 ctx->err_ = Z_OK;
386
44eb279 zlib: don't use C++ templates
ssuda authored
387 if (ctx->mode_ == GZIP || ctx->mode_ == GUNZIP) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
388 ctx->windowBits_ += 16;
389 }
390
44eb279 zlib: don't use C++ templates
ssuda authored
391 if (ctx->mode_ == UNZIP) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
392 ctx->windowBits_ += 32;
393 }
394
44eb279 zlib: don't use C++ templates
ssuda authored
395 if (ctx->mode_ == DEFLATERAW || ctx->mode_ == INFLATERAW) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
396 ctx->windowBits_ *= -1;
397 }
398
44eb279 zlib: don't use C++ templates
ssuda authored
399 switch (ctx->mode_) {
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
400 case DEFLATE:
401 case GZIP:
402 case DEFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
403 ctx->err_ = deflateInit2(&ctx->strm_,
404 ctx->level_,
405 Z_DEFLATED,
406 ctx->windowBits_,
407 ctx->memLevel_,
408 ctx->strategy_);
a93424d @bnoordhuis zlib: pass object size hint to V8
bnoordhuis authored
409 V8::AdjustAmountOfExternalAllocatedMemory(kDeflateContextSize);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
410 break;
411 case INFLATE:
412 case GUNZIP:
413 case INFLATERAW:
414 case UNZIP:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
415 ctx->err_ = inflateInit2(&ctx->strm_, ctx->windowBits_);
a93424d @bnoordhuis zlib: pass object size hint to V8
bnoordhuis authored
416 V8::AdjustAmountOfExternalAllocatedMemory(kInflateContextSize);
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
417 break;
418 default:
419 assert(0 && "wtf?");
420 }
421
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
422 if (ctx->err_ != Z_OK) {
423 ZCtx::Error(ctx, "Init error");
424 }
425
e609195 @indutny [zlib] added dictionary support
indutny authored
426
427 ctx->dictionary_ = reinterpret_cast<Bytef *>(dictionary);
428 ctx->dictionary_len_ = dictionary_len;
429
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
430 ctx->write_in_progress_ = false;
431 ctx->init_done_ = true;
432 }
433
434 static void SetDictionary(ZCtx* ctx) {
435 if (ctx->dictionary_ == NULL) return;
e609195 @indutny [zlib] added dictionary support
indutny authored
436
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
437 ctx->err_ = Z_OK;
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
438
44eb279 zlib: don't use C++ templates
ssuda authored
439 switch (ctx->mode_) {
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
440 case DEFLATE:
441 case DEFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
442 ctx->err_ = deflateSetDictionary(&ctx->strm_,
443 ctx->dictionary_,
444 ctx->dictionary_len_);
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
445 break;
446 default:
447 break;
e609195 @indutny [zlib] added dictionary support
indutny authored
448 }
449
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
450 if (ctx->err_ != Z_OK) {
451 ZCtx::Error(ctx, "Failed to set dictionary");
452 }
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
453 }
454
455 static void Reset(ZCtx* ctx) {
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
456 ctx->err_ = Z_OK;
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
457
44eb279 zlib: don't use C++ templates
ssuda authored
458 switch (ctx->mode_) {
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
459 case DEFLATE:
460 case DEFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
461 ctx->err_ = deflateReset(&ctx->strm_);
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
462 break;
463 case INFLATE:
464 case INFLATERAW:
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
465 ctx->err_ = inflateReset(&ctx->strm_);
71ae175 @indutny zlib: reset() method for deflate/inflate streams
indutny authored
466 break;
467 default:
468 break;
469 }
470
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
471 if (ctx->err_ != Z_OK) {
472 ZCtx::Error(ctx, "Failed to reset stream");
473 }
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
474 }
475
476 private:
a93424d @bnoordhuis zlib: pass object size hint to V8
bnoordhuis authored
477 static const int kDeflateContextSize = 16384; // approximate
478 static const int kInflateContextSize = 10240; // approximate
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
479
480 bool init_done_;
481
482 z_stream strm_;
483 int level_;
484 int windowBits_;
485 int memLevel_;
486 int strategy_;
487
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
488 int err_;
489
e609195 @indutny [zlib] added dictionary support
indutny authored
490 Bytef* dictionary_;
491 size_t dictionary_len_;
492
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
493 int flush_;
494
495 int chunk_size_;
8cca30f @isaacs zlib binding cleanup
isaacs authored
496
497 bool write_in_progress_;
498
499 uv_work_t work_req_;
44eb279 zlib: don't use C++ templates
ssuda authored
500 node_zlib_mode mode_;
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
501 };
502
503
504 void InitZlib(Handle<Object> target) {
505 HandleScope scope;
506
44eb279 zlib: don't use C++ templates
ssuda authored
507 Local<FunctionTemplate> z = FunctionTemplate::New(ZCtx::New);
508
509 z->InstanceTemplate()->SetInternalFieldCount(1);
510
511 NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx::Write);
512 NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init);
07d3b21 @isaacs zlib: s/clear/close/ and match other close() semantics
isaacs authored
513 NODE_SET_PROTOTYPE_METHOD(z, "close", ZCtx::Close);
44eb279 zlib: don't use C++ templates
ssuda authored
514 NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
515
516 z->SetClassName(String::NewSymbol("Zlib"));
517 target->Set(String::NewSymbol("Zlib"), z->GetFunction());
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
518
519 callback_sym = NODE_PSYMBOL("callback");
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
520 onerror_sym = NODE_PSYMBOL("onerror");
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
521
0e01d63 @isaacs zlib: streams2
isaacs authored
522 // valid flush values.
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
523 NODE_DEFINE_CONSTANT(target, Z_NO_FLUSH);
524 NODE_DEFINE_CONSTANT(target, Z_PARTIAL_FLUSH);
525 NODE_DEFINE_CONSTANT(target, Z_SYNC_FLUSH);
526 NODE_DEFINE_CONSTANT(target, Z_FULL_FLUSH);
527 NODE_DEFINE_CONSTANT(target, Z_FINISH);
528 NODE_DEFINE_CONSTANT(target, Z_BLOCK);
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
529
530 // return/error codes
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
531 NODE_DEFINE_CONSTANT(target, Z_OK);
532 NODE_DEFINE_CONSTANT(target, Z_STREAM_END);
533 NODE_DEFINE_CONSTANT(target, Z_NEED_DICT);
534 NODE_DEFINE_CONSTANT(target, Z_ERRNO);
535 NODE_DEFINE_CONSTANT(target, Z_STREAM_ERROR);
536 NODE_DEFINE_CONSTANT(target, Z_DATA_ERROR);
537 NODE_DEFINE_CONSTANT(target, Z_MEM_ERROR);
538 NODE_DEFINE_CONSTANT(target, Z_BUF_ERROR);
539 NODE_DEFINE_CONSTANT(target, Z_VERSION_ERROR);
01d46f3 @isaacs Fix #3052 Handle errors properly in zlib
isaacs authored
540
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
541 NODE_DEFINE_CONSTANT(target, Z_NO_COMPRESSION);
542 NODE_DEFINE_CONSTANT(target, Z_BEST_SPEED);
543 NODE_DEFINE_CONSTANT(target, Z_BEST_COMPRESSION);
544 NODE_DEFINE_CONSTANT(target, Z_DEFAULT_COMPRESSION);
545 NODE_DEFINE_CONSTANT(target, Z_FILTERED);
546 NODE_DEFINE_CONSTANT(target, Z_HUFFMAN_ONLY);
547 NODE_DEFINE_CONSTANT(target, Z_RLE);
548 NODE_DEFINE_CONSTANT(target, Z_FIXED);
549 NODE_DEFINE_CONSTANT(target, Z_DEFAULT_STRATEGY);
550 NODE_DEFINE_CONSTANT(target, ZLIB_VERNUM);
551
44eb279 zlib: don't use C++ templates
ssuda authored
552 NODE_DEFINE_CONSTANT(target, DEFLATE);
553 NODE_DEFINE_CONSTANT(target, INFLATE);
554 NODE_DEFINE_CONSTANT(target, GZIP);
555 NODE_DEFINE_CONSTANT(target, GUNZIP);
556 NODE_DEFINE_CONSTANT(target, DEFLATERAW);
557 NODE_DEFINE_CONSTANT(target, INFLATERAW);
558 NODE_DEFINE_CONSTANT(target, UNZIP);
559
5b8e1da @isaacs Initial pass at zlib bindings
isaacs authored
560 target->Set(String::NewSymbol("ZLIB_VERSION"), String::New(ZLIB_VERSION));
561 }
562
563 } // namespace node
564
cdcb111 @bnoordhuis Remove stray NODE_MODULE() semi-colons.
bnoordhuis authored
565 NODE_MODULE(node_zlib, node::InitZlib)
Something went wrong with that request. Please try again.