Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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