RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* filter_js.cc 00002 Jeremy Barnes, 30 May 2011 00003 Copyright (c) 2011 Datacratic. All rights reserved. 00004 00005 */ 00006 00007 #include "filter.h" 00008 #include "json_filter.h" 00009 #include "v8.h" 00010 #include "node.h" 00011 #include "soa/js/js_value.h" 00012 #include "soa/js/js_utils.h" 00013 #include "soa/js/js_wrapped.h" 00014 #include "soa/js/js_call.h" 00015 #include "soa/js/js_registry.h" 00016 #include "jml/arch/timers.h" 00017 #include "jml/utils/guard.h" 00018 #include "soa/sigslot/slot.h" 00019 #include "jml/utils/guard.h" 00020 #include "soa/sigslot/slot_js.h" 00021 #include "ace/Synch.h" 00022 #include "jml/utils/smart_ptr_utils.h" 00023 00024 using namespace std; 00025 using namespace v8; 00026 using namespace node; 00027 00028 00029 namespace Datacratic { 00030 namespace JS { 00031 00032 extern Registry registry; 00033 00034 extern const char * const loggerModule; 00035 00036 Direction from_js(const JSValue & value, Direction * = 0) 00037 { 00038 string str = cstr(value); 00039 if (str == "COMPRESS") 00040 return COMPRESS; 00041 else if (str == "DECOMPRESS") 00042 return DECOMPRESS; 00043 throw ML::Exception("couldn't convert JS value " + str + " to Direction"); 00044 } 00045 00046 void to_js(JSValue & value, const Direction & dir) 00047 { 00048 switch (dir) { 00049 case COMPRESS: 00050 value = String::NewSymbol("COMPRESS"); return; 00051 case DECOMPRESS: 00052 value = String::NewSymbol("DECOMPRESS"); return; 00053 default: 00054 throw ML::Exception("unknown Direction %d", dir); 00055 } 00056 } 00057 00058 FlushLevel from_js(const JSValue & value, FlushLevel * = 0) 00059 { 00060 string str = cstr(value); 00061 if (str == "FLUSH_NONE") 00062 return FLUSH_NONE; 00063 else if (str == "FLUSH_SYNC") 00064 return FLUSH_SYNC; 00065 else if (str == "FLUSH_FULL") 00066 return FLUSH_FULL; 00067 else if (str == "FLUSH_FINISH") 00068 return FLUSH_FINISH; 00069 throw ML::Exception("couldn't convert JS value " + str + " to FlushLevel"); 00070 } 00071 00072 void to_js(JSValue & value, const FlushLevel & level) 00073 { 00074 switch (level) { 00075 case FLUSH_NONE: value = String::NewSymbol("FLUSH_NONE"); return; 00076 case FLUSH_SYNC: value = String::NewSymbol("FLUSH_SYNC"); return; 00077 case FLUSH_FULL: value = String::NewSymbol("FLUSH_FULL"); return; 00078 case FLUSH_FINISH: value = String::NewSymbol("FLUSH_FINISH"); return; 00079 default: 00080 throw ML::Exception("Unknown FlushLevel %d", level); 00081 } 00082 } 00083 00084 00085 /*****************************************************************************/ 00086 /* FILTER JS */ 00087 /*****************************************************************************/ 00088 00089 const char * FilterName = "Filter"; 00090 00091 struct FilterJS 00092 : public JSWrapped2<Filter, FilterJS, FilterName, 00093 loggerModule, true> { 00094 00095 FilterJS() 00096 { 00097 } 00098 00099 FilterJS(const v8::Handle<v8::Object> & This, 00100 const std::shared_ptr<Filter> & handler 00101 = std::shared_ptr<Filter>()) 00102 { 00103 wrap(This, handler); 00104 } 00105 00106 ~FilterJS() 00107 { 00108 } 00109 00110 static Handle<v8::Value> 00111 New(const Arguments & args) 00112 { 00113 try { 00114 new FilterJS(args.This()); 00115 return args.This(); 00116 } HANDLE_JS_EXCEPTIONS; 00117 } 00118 00119 static void Initialize() 00120 { 00121 Persistent<FunctionTemplate> t = Register(New); 00122 00123 // Instance methods 00124 NODE_SET_PROTOTYPE_METHOD(t, "flush", flush); 00125 NODE_SET_PROTOTYPE_METHOD(t, "flushSync", flushSync); 00126 NODE_SET_PROTOTYPE_METHOD(t, "process", process); 00127 NODE_SET_PROTOTYPE_METHOD(t, "processSync", processSync); 00128 00129 // Members 00130 t->InstanceTemplate() 00131 ->SetAccessor(String::NewSymbol("onOutput"), onOutputGetter, 00132 onOutputSetter, v8::Handle<v8::Value>(), DEFAULT, 00133 PropertyAttribute(DontDelete)); 00134 00135 t->InstanceTemplate() 00136 ->SetAccessor(String::NewSymbol("onError"), onErrorGetter, 00137 onErrorSetter, v8::Handle<v8::Value>(), DEFAULT, 00138 PropertyAttribute(DontDelete)); 00139 00140 00141 // Class methods 00142 t->Set(String::NewSymbol("create"), 00143 FunctionTemplate::New(create)); 00144 00145 // Compress flags 00146 t->Set(String::NewSymbol("COMPRESS"), 00147 String::NewSymbol("COMPRESS")); 00148 t->Set(String::NewSymbol("DECOMPRESS"), 00149 String::NewSymbol("DECOMPRESS")); 00150 00151 // Flush flags 00152 t->Set(String::NewSymbol("FLUSH_NONE"), 00153 String::NewSymbol("FLUSH_NONE")); 00154 t->Set(String::NewSymbol("FLUSH_SYNC"), 00155 String::NewSymbol("FLUSH_SYNC")); 00156 t->Set(String::NewSymbol("FLUSH_FULL"), 00157 String::NewSymbol("FLUSH_FULL")); 00158 t->Set(String::NewSymbol("FLUSH_FINISH"), 00159 String::NewSymbol("FLUSH_FINISH")); 00160 } 00161 00162 static Handle<v8::Value> 00163 flush(const Arguments & args) 00164 { 00165 try { 00166 if (args[1]->IsUndefined() || args[1]->IsNull()) 00167 getShared(args)->flush(getArg(args, 0, "flushLevel")); 00168 else { 00169 // This callback may be called from another thread later on, which 00170 // will not be in the JS interpreter. 00171 // As a result, we need to do all of the manipulation of the function 00172 // now and arrange for it to be called from the right thread. 00173 00174 auto cb = createCrossThreadCallback(getArg(args, 1, "callback"), 00175 args.This()); 00176 00177 getShared(args)->flush(getArg(args, 0, "flushLevel"), 00178 cb); 00179 } 00180 return args.This(); 00181 } HANDLE_JS_EXCEPTIONS; 00182 } 00183 00184 static Handle<v8::Value> 00185 flushSync(const Arguments & args) 00186 { 00187 try { 00188 ACE_Semaphore sem(0); 00189 auto cb = [&] () { sem.release(); }; 00190 00191 getShared(args)->flush(getArg(args, 0, "flushLevel"), 00192 cb); 00193 00194 sem.acquire(); 00195 00196 return args.This(); 00197 } HANDLE_JS_EXCEPTIONS; 00198 } 00199 00200 static Handle<v8::Value> 00201 process(const Arguments & args) 00202 { 00203 try { 00204 if (args[2]->IsUndefined() || args[2]->IsNull()) 00205 getShared(args)->process(getArg<string>(args, 0, "buf"), 00206 getArg(args, 1, FLUSH_NONE, "flushLevel")); 00207 else { 00208 // This callback may be called from another thread later on, which 00209 // will not be in the JS interpreter. 00210 // As a result, we need to do all of the manipulation of the function 00211 // now and arrange for it to be called from the right thread. 00212 00213 auto cb = createCrossThreadCallback(getArg(args, 2, "callback"), 00214 args.This()); 00215 getShared(args)->process(getArg(args, 0, "buf"), 00216 getArg(args, 1, "flushLevel"), 00217 cb); 00218 } 00219 return args.This(); 00220 } HANDLE_JS_EXCEPTIONS; 00221 } 00222 00223 static Handle<v8::Value> 00224 processSync(const Arguments & args) 00225 { 00226 try { 00227 ACE_Semaphore sem(0); 00228 auto cb = [&] () { sem.release(); }; 00229 00230 getShared(args)->process(getArg(args, 0, "buf"), 00231 getArg(args, 1, FLUSH_NONE, "flushLevel"), 00232 cb); 00233 00234 sem.acquire(); 00235 00236 return args.This(); 00237 } HANDLE_JS_EXCEPTIONS; 00238 } 00239 00240 static Handle<v8::Value> 00241 create(const Arguments & args) 00242 { 00243 try { 00244 return registry.getWrapper 00245 (ML::make_std_sp 00246 (Filter::create(getArg(args, 0, "extension"), 00247 getArg(args, 1, COMPRESS, "direction")))); 00248 00249 } HANDLE_JS_EXCEPTIONS; 00250 } 00251 00252 static v8::Handle<v8::Value> 00253 onOutputGetter(v8::Local<v8::String> property, 00254 const v8::AccessorInfo & info) 00255 { 00256 try { 00257 return JS::toJS(Slot(getShared(info.This())->onOutput)); 00258 } HANDLE_JS_EXCEPTIONS; 00259 } 00260 00261 static void 00262 onOutputSetter(v8::Local<v8::String> property, 00263 v8::Local<v8::Value> value, 00264 const v8::AccessorInfo & info) 00265 { 00266 try { 00267 Slot slot = JS::fromJS(value); 00268 getShared(info.This())->onOutput = slot.as<Filter::OnOutputFn>(); 00269 } HANDLE_JS_EXCEPTIONS_SETTER; 00270 } 00271 00272 static v8::Handle<v8::Value> 00273 onErrorGetter(v8::Local<v8::String> property, 00274 const v8::AccessorInfo & info) 00275 { 00276 try { 00277 return JS::toJS(Slot(getShared(info.This())->onError)); 00278 } HANDLE_JS_EXCEPTIONS; 00279 } 00280 00281 static void 00282 onErrorSetter(v8::Local<v8::String> property, 00283 v8::Local<v8::Value> value, 00284 const v8::AccessorInfo & info) 00285 { 00286 try { 00287 Slot slot = JS::fromJS(value); 00288 getShared(info.This())->onError = slot.as<Filter::OnErrorFn>(); 00289 } HANDLE_JS_EXCEPTIONS_SETTER; 00290 } 00291 }; 00292 00293 std::shared_ptr<Filter> 00294 from_js(const JSValue & value, std::shared_ptr<Filter> *) 00295 { 00296 return FilterJS::fromJS(value); 00297 } 00298 00299 Filter * 00300 from_js(const JSValue & value, Filter **) 00301 { 00302 return FilterJS::fromJS(value).get(); 00303 } 00304 00305 struct OnOutputJsOps: public JS::JsOpsBase<OnOutputJsOps, Filter::OnOutputFn> { 00306 00307 static v8::Handle<v8::Value> 00308 callBoost(const Function & fn, 00309 const JS::JSArgs & args) 00310 { 00311 throw ML::Exception("callBoost onOutput"); 00312 #if 0 00313 Result result 00314 = JS::callfromjs<Function, Function::arity>::call(fn, args); 00315 00316 JS::JSValue jsresult; 00317 JS::to_js(jsresult, result); 00318 00319 return jsresult; 00320 #endif 00321 } 00322 00323 static Function 00324 asBoost(const v8::Handle<v8::Function> & fn, 00325 const v8::Handle<v8::Object> * This) 00326 { 00327 v8::Handle<v8::Object> This2; 00328 if (!This) 00329 This2 = v8::Object::New(); 00330 calltojsbase params(fn, This ? *This : This2); 00331 00332 auto result = [=] (const char * buf, size_t numChars, 00333 FlushLevel flush, boost::function<void ()> fn) 00334 { 00335 string str(buf, buf + numChars); 00336 00337 v8::HandleScope scope; 00338 v8::Handle<v8::Value> result; 00339 { 00340 v8::TryCatch tc; 00341 v8::Handle<v8::Value> argv[3]; 00342 argv[0] = JS::toJS(str); 00343 argv[1] = JS::toJS(flush); 00344 argv[2] = JS::toJS(Slot(fn)); 00345 00346 result = params.params->fn->Call(params.params->This, 3, argv); 00347 00348 if (result.IsEmpty()) { 00349 if(tc.HasCaught()) { 00350 tc.ReThrow(); 00351 throw JSPassException(); 00352 } 00353 } 00354 } 00355 }; 00356 00357 return result; 00358 } 00359 }; 00360 00361 00362 00363 RegisterJsOps<Filter::OnOutputFn> reg_onOutputFn(OnOutputJsOps::op); 00364 RegisterJsOps<Filter::OnErrorFn> reg_onErrorFn; 00365 RegisterJsOps<void ()> reg_plainCallback; 00366 00367 #if 0 00368 /*****************************************************************************/ 00369 /* JS OUTPUT */ 00370 /*****************************************************************************/ 00371 00372 class JSOutputJS; 00373 00376 struct JSOutput : public Filter { 00377 00378 JSOutput() 00379 : wrapper(0) 00380 { 00381 } 00382 00383 virtual ~JSOutput() 00384 { 00385 } 00386 00387 Slot logMessageSlot; 00388 JSOutputJS * wrapper; 00389 00390 struct CallbackData { 00391 JSOutput * ThisPtr; 00392 //v8::Persistent<v8::Object> ThisObj; // make sure we're not GCd 00393 std::string channel; 00394 std::string message; 00395 00396 ~CallbackData() 00397 { 00398 //if (!ThisObj.IsEmpty()) { 00399 // ThisObj.Dispose(); 00400 // ThisObj.Clear(); 00401 //} 00402 } 00403 }; 00404 00405 static int doNothing(eio_req * req) 00406 { 00407 // TODO: don't do this; find how to use libeio properly 00408 return 0; 00409 } 00410 00411 static int finishedCallback(eio_req * req) 00412 { 00413 HandleScope scope; 00414 00415 auto_ptr<CallbackData> data((CallbackData *)req->data); 00416 00417 TryCatch try_catch; 00418 00419 try { 00420 data->ThisPtr-> 00421 logMessageSlot.call<void (std::string, std::string)> 00422 (data->channel, data->message); 00423 } catch (const JSPassException & exc) { 00424 cerr << "got JSPassException" << endl; 00425 if (!try_catch.HasCaught()) { 00426 cerr << "handler returned passed exception " << endl; 00427 ML::backtrace(); 00428 abort(); 00429 } 00430 // Corner case... but probably shouldn't happen 00431 } catch (const std::exception & exc) { 00432 v8::Handle<v8::Value> result = translateCurrentException(); 00433 if (!try_catch.HasCaught()) { 00434 cerr << "handler returned exception: " << exc.what() << endl; 00435 ML::backtrace(); 00436 abort(); 00437 } 00438 } catch (...) { 00439 v8::Handle<v8::Value> result = translateCurrentException(); 00440 if (!try_catch.HasCaught()) { 00441 cerr << "handler returned exception " << endl; 00442 ML::backtrace(); 00443 abort(); 00444 } 00445 } 00446 00447 if (try_catch.HasCaught()) 00448 FatalException(try_catch); 00449 00450 return 0; 00451 } 00452 00453 virtual void logMessage(const std::string & channel, 00454 const std::string & message); 00455 }; 00456 00457 RegisterJsOps<void (std::string, std::string)> reg_logMessage; 00458 00459 /*****************************************************************************/ 00460 /* JS OUTPUT JS */ 00461 /*****************************************************************************/ 00462 00463 const char * JSOutputName = "JSOutput"; 00464 00465 struct JSOutputJS 00466 : public JSWrapped3<JSOutput, JSOutputJS, FilterJS, JSOutputName, 00467 loggerModule, true> { 00468 00469 JSOutputJS(const v8::Handle<v8::Object> & This, 00470 const std::shared_ptr<JSOutput> & output 00471 = std::shared_ptr<JSOutput>()) 00472 { 00473 wrap(This, output); 00474 getShared(This)->wrapper = this; 00475 } 00476 00477 ~JSOutputJS() 00478 { 00479 getShared(js_object_)->wrapper = 0; 00480 } 00481 00482 static Handle<v8::Value> 00483 New(const Arguments & args) 00484 { 00485 try { 00486 new JSOutputJS 00487 (args.This(), 00488 std::shared_ptr<JSOutput> 00489 (new JSOutput())); 00490 00491 return args.This(); 00492 } HANDLE_JS_EXCEPTIONS; 00493 } 00494 00495 static void Initialize() 00496 { 00497 Persistent<FunctionTemplate> t = Register(New); 00498 00499 RWPropertyHandler<JSOutputJS, JSOutput, Slot, &JSOutput::logMessageSlot> 00500 handleLogMessage(t, "logMessageFn"); 00501 } 00502 }; 00503 00504 00505 void 00506 JSOutput:: 00507 logMessage(const std::string & channel, 00508 const std::string & message) 00509 { 00510 // This is called from a thread that is probably not the right thread for 00511 // JS to be executed in. Here we arrange for the right thread to be called 00512 // back by libev once the JS engine is ready to do something. 00513 00514 auto_ptr<CallbackData> data(new CallbackData()); 00515 00516 data->channel = channel; 00517 data->message = message; 00518 data->ThisPtr = this; 00519 //data->ThisObj = v8::Persistent<v8::Object>::New(wrapper->js_object_); 00520 00521 eio_custom(doNothing, EIO_PRI_DEFAULT, finishedCallback, data.release()); 00522 } 00523 #endif 00524 00525 00526 /*****************************************************************************/ 00527 /* IDENTITY FILTER JS */ 00528 /*****************************************************************************/ 00529 00530 const char * IdentityFilterName = "IdentityFilter"; 00531 00532 struct IdentityFilterJS 00533 : public JSWrapped3<IdentityFilter, IdentityFilterJS, FilterJS, 00534 IdentityFilterName, loggerModule, true> { 00535 00536 IdentityFilterJS() 00537 { 00538 } 00539 00540 IdentityFilterJS(const v8::Handle<v8::Object> & This, 00541 const std::shared_ptr<IdentityFilter> & filter 00542 = std::shared_ptr<IdentityFilter>()) 00543 { 00544 wrap(This, filter); 00545 } 00546 00547 static Handle<v8::Value> 00548 New(const Arguments & args) 00549 { 00550 try { 00551 new IdentityFilterJS 00552 (args.This(), 00553 std::shared_ptr<IdentityFilter>(new IdentityFilter())); 00554 return args.This(); 00555 } HANDLE_JS_EXCEPTIONS; 00556 } 00557 00558 static void Initialize() 00559 { 00560 Persistent<FunctionTemplate> t = Register(New); 00561 } 00562 }; 00563 00564 std::shared_ptr<IdentityFilter> 00565 from_js(const JSValue & value, std::shared_ptr<IdentityFilter> *) 00566 { 00567 return IdentityFilterJS::fromJS(value); 00568 } 00569 00570 IdentityFilter * 00571 from_js(const JSValue & value, IdentityFilter **) 00572 { 00573 return IdentityFilterJS::fromJS(value).get(); 00574 } 00575 00576 00577 /*****************************************************************************/ 00578 /* ZLIB COMPRESSOR JS */ 00579 /*****************************************************************************/ 00580 00581 const char * ZlibCompressorName = "ZlibCompressor"; 00582 00583 struct ZlibCompressorJS 00584 : public JSWrapped3<ZlibCompressor, ZlibCompressorJS, FilterJS, 00585 ZlibCompressorName, loggerModule, true> { 00586 00587 ZlibCompressorJS() 00588 { 00589 } 00590 00591 ZlibCompressorJS(const v8::Handle<v8::Object> & This, 00592 const std::shared_ptr<ZlibCompressor> & filter 00593 = std::shared_ptr<ZlibCompressor>()) 00594 { 00595 wrap(This, filter); 00596 } 00597 00598 static Handle<v8::Value> 00599 New(const Arguments & args) 00600 { 00601 try { 00602 new ZlibCompressorJS 00603 (args.This(), 00604 std::shared_ptr<ZlibCompressor>(new ZlibCompressor())); 00605 return args.This(); 00606 } HANDLE_JS_EXCEPTIONS; 00607 } 00608 00609 static void Initialize() 00610 { 00611 Persistent<FunctionTemplate> t = Register(New); 00612 } 00613 }; 00614 00615 std::shared_ptr<ZlibCompressor> 00616 from_js(const JSValue & value, std::shared_ptr<ZlibCompressor> *) 00617 { 00618 return ZlibCompressorJS::fromJS(value); 00619 } 00620 00621 ZlibCompressor * 00622 from_js(const JSValue & value, ZlibCompressor **) 00623 { 00624 return ZlibCompressorJS::fromJS(value).get(); 00625 } 00626 00627 00628 /*****************************************************************************/ 00629 /* ZLIB DECOMPRESSOR JS */ 00630 /*****************************************************************************/ 00631 00632 const char * ZlibDecompressorName = "ZlibDecompressor"; 00633 00634 struct ZlibDecompressorJS 00635 : public JSWrapped3<ZlibDecompressor, ZlibDecompressorJS, FilterJS, 00636 ZlibDecompressorName, loggerModule, true> { 00637 00638 ZlibDecompressorJS() 00639 { 00640 } 00641 00642 ZlibDecompressorJS(const v8::Handle<v8::Object> & This, 00643 const std::shared_ptr<ZlibDecompressor> & filter 00644 = std::shared_ptr<ZlibDecompressor>()) 00645 { 00646 wrap(This, filter); 00647 } 00648 00649 static Handle<v8::Value> 00650 New(const Arguments & args) 00651 { 00652 try { 00653 new ZlibDecompressorJS 00654 (args.This(), 00655 std::shared_ptr<ZlibDecompressor>(new ZlibDecompressor())); 00656 return args.This(); 00657 } HANDLE_JS_EXCEPTIONS; 00658 } 00659 00660 static void Initialize() 00661 { 00662 Persistent<FunctionTemplate> t = Register(New); 00663 } 00664 }; 00665 00666 std::shared_ptr<ZlibDecompressor> 00667 from_js(const JSValue & value, std::shared_ptr<ZlibDecompressor> *) 00668 { 00669 return ZlibDecompressorJS::fromJS(value); 00670 } 00671 00672 ZlibDecompressor * 00673 from_js(const JSValue & value, ZlibDecompressor **) 00674 { 00675 return ZlibDecompressorJS::fromJS(value).get(); 00676 } 00677 00678 00679 /*****************************************************************************/ 00680 /* GZIP COMPRESSOR JS */ 00681 /*****************************************************************************/ 00682 00683 const char * GzipCompressorName = "GzipCompressor"; 00684 00685 struct GzipCompressorJS 00686 : public JSWrapped3<GzipCompressorFilter, GzipCompressorJS, FilterJS, 00687 GzipCompressorName, loggerModule, true> { 00688 00689 GzipCompressorJS() 00690 { 00691 } 00692 00693 GzipCompressorJS(const v8::Handle<v8::Object> & This, 00694 const std::shared_ptr<GzipCompressorFilter> & filter 00695 = std::shared_ptr<GzipCompressorFilter>()) 00696 { 00697 wrap(This, filter); 00698 } 00699 00700 static Handle<v8::Value> 00701 New(const Arguments & args) 00702 { 00703 try { 00704 new GzipCompressorJS 00705 (args.This(), 00706 std::shared_ptr<GzipCompressorFilter>(new GzipCompressorFilter())); 00707 return args.This(); 00708 } HANDLE_JS_EXCEPTIONS; 00709 } 00710 00711 static void Initialize() 00712 { 00713 Persistent<FunctionTemplate> t = Register(New); 00714 } 00715 }; 00716 00717 std::shared_ptr<GzipCompressorFilter> 00718 from_js(const JSValue & value, std::shared_ptr<GzipCompressorFilter> *) 00719 { 00720 return GzipCompressorJS::fromJS(value); 00721 } 00722 00723 GzipCompressorFilter * 00724 from_js(const JSValue & value, GzipCompressorFilter **) 00725 { 00726 return GzipCompressorJS::fromJS(value).get(); 00727 } 00728 00729 00730 /*****************************************************************************/ 00731 /* GZIP DECOMPRESSOR JS */ 00732 /*****************************************************************************/ 00733 00734 const char * GzipDecompressorName = "GzipDecompressor"; 00735 00736 struct GzipDecompressorJS 00737 : public JSWrapped3<GzipDecompressor, GzipDecompressorJS, FilterJS, 00738 GzipDecompressorName, loggerModule, true> { 00739 00740 GzipDecompressorJS() 00741 { 00742 } 00743 00744 GzipDecompressorJS(const v8::Handle<v8::Object> & This, 00745 const std::shared_ptr<GzipDecompressor> & filter 00746 = std::shared_ptr<GzipDecompressor>()) 00747 { 00748 wrap(This, filter); 00749 } 00750 00751 static Handle<v8::Value> 00752 New(const Arguments & args) 00753 { 00754 try { 00755 new GzipDecompressorJS 00756 (args.This(), 00757 std::shared_ptr<GzipDecompressor>(new GzipDecompressor())); 00758 return args.This(); 00759 } HANDLE_JS_EXCEPTIONS; 00760 } 00761 00762 static void Initialize() 00763 { 00764 Persistent<FunctionTemplate> t = Register(New); 00765 } 00766 }; 00767 00768 std::shared_ptr<GzipDecompressor> 00769 from_js(const JSValue & value, std::shared_ptr<GzipDecompressor> *) 00770 { 00771 return GzipDecompressorJS::fromJS(value); 00772 } 00773 00774 GzipDecompressor * 00775 from_js(const JSValue & value, GzipDecompressor **) 00776 { 00777 return GzipDecompressorJS::fromJS(value).get(); 00778 } 00779 00780 00781 /*****************************************************************************/ 00782 /* LZMA COMPRESSOR JS */ 00783 /*****************************************************************************/ 00784 00785 const char * LzmaCompressorName = "LzmaCompressor"; 00786 00787 struct LzmaCompressorJS 00788 : public JSWrapped3<LzmaCompressor, LzmaCompressorJS, FilterJS, 00789 LzmaCompressorName, loggerModule, true> { 00790 00791 LzmaCompressorJS() 00792 { 00793 } 00794 00795 LzmaCompressorJS(const v8::Handle<v8::Object> & This, 00796 const std::shared_ptr<LzmaCompressor> & filter 00797 = std::shared_ptr<LzmaCompressor>()) 00798 { 00799 wrap(This, filter); 00800 } 00801 00802 static Handle<v8::Value> 00803 New(const Arguments & args) 00804 { 00805 try { 00806 int level = getArg(args, 0, 6, "compressionLevel"); 00807 new LzmaCompressorJS 00808 (args.This(), 00809 std::shared_ptr<LzmaCompressor>(new LzmaCompressor(level))); 00810 return args.This(); 00811 } HANDLE_JS_EXCEPTIONS; 00812 } 00813 00814 static void Initialize() 00815 { 00816 Persistent<FunctionTemplate> t = Register(New); 00817 } 00818 }; 00819 00820 std::shared_ptr<LzmaCompressor> 00821 from_js(const JSValue & value, std::shared_ptr<LzmaCompressor> *) 00822 { 00823 return LzmaCompressorJS::fromJS(value); 00824 } 00825 00826 LzmaCompressor * 00827 from_js(const JSValue & value, LzmaCompressor **) 00828 { 00829 return LzmaCompressorJS::fromJS(value).get(); 00830 } 00831 00832 00833 /*****************************************************************************/ 00834 /* LZMA DECOMPRESSOR JS */ 00835 /*****************************************************************************/ 00836 00837 const char * LzmaDecompressorName = "LzmaDecompressor"; 00838 00839 struct LzmaDecompressorJS 00840 : public JSWrapped3<LzmaDecompressor, LzmaDecompressorJS, FilterJS, 00841 LzmaDecompressorName, loggerModule, true> { 00842 00843 LzmaDecompressorJS() 00844 { 00845 } 00846 00847 LzmaDecompressorJS(const v8::Handle<v8::Object> & This, 00848 const std::shared_ptr<LzmaDecompressor> & filter 00849 = std::shared_ptr<LzmaDecompressor>()) 00850 { 00851 wrap(This, filter); 00852 } 00853 00854 static Handle<v8::Value> 00855 New(const Arguments & args) 00856 { 00857 try { 00858 new LzmaDecompressorJS 00859 (args.This(), 00860 std::shared_ptr<LzmaDecompressor>(new LzmaDecompressor())); 00861 return args.This(); 00862 } HANDLE_JS_EXCEPTIONS; 00863 } 00864 00865 static void Initialize() 00866 { 00867 Persistent<FunctionTemplate> t = Register(New); 00868 } 00869 }; 00870 00871 std::shared_ptr<LzmaDecompressor> 00872 from_js(const JSValue & value, std::shared_ptr<LzmaDecompressor> *) 00873 { 00874 return LzmaDecompressorJS::fromJS(value); 00875 } 00876 00877 LzmaDecompressor * 00878 from_js(const JSValue & value, LzmaDecompressor **) 00879 { 00880 return LzmaDecompressorJS::fromJS(value).get(); 00881 } 00882 00883 00884 /*****************************************************************************/ 00885 /* BZIP2 COMPRESSOR JS */ 00886 /*****************************************************************************/ 00887 00888 const char * Bzip2CompressorName = "Bzip2Compressor"; 00889 00890 struct Bzip2CompressorJS 00891 : public JSWrapped3<Bzip2Compressor, Bzip2CompressorJS, FilterJS, 00892 Bzip2CompressorName, loggerModule, true> { 00893 00894 Bzip2CompressorJS() 00895 { 00896 } 00897 00898 Bzip2CompressorJS(const v8::Handle<v8::Object> & This, 00899 const std::shared_ptr<Bzip2Compressor> & filter 00900 = std::shared_ptr<Bzip2Compressor>()) 00901 { 00902 wrap(This, filter); 00903 } 00904 00905 static Handle<v8::Value> 00906 New(const Arguments & args) 00907 { 00908 try { 00909 new Bzip2CompressorJS 00910 (args.This(), 00911 std::shared_ptr<Bzip2Compressor>(new Bzip2Compressor())); 00912 return args.This(); 00913 } HANDLE_JS_EXCEPTIONS; 00914 } 00915 00916 static void Initialize() 00917 { 00918 Persistent<FunctionTemplate> t = Register(New); 00919 } 00920 }; 00921 00922 std::shared_ptr<Bzip2Compressor> 00923 from_js(const JSValue & value, std::shared_ptr<Bzip2Compressor> *) 00924 { 00925 return Bzip2CompressorJS::fromJS(value); 00926 } 00927 00928 Bzip2Compressor * 00929 from_js(const JSValue & value, Bzip2Compressor **) 00930 { 00931 return Bzip2CompressorJS::fromJS(value).get(); 00932 } 00933 00934 00935 /*****************************************************************************/ 00936 /* BZIP2 DECOMPRESSOR JS */ 00937 /*****************************************************************************/ 00938 00939 const char * Bzip2DecompressorName = "Bzip2Decompressor"; 00940 00941 struct Bzip2DecompressorJS 00942 : public JSWrapped3<Bzip2Decompressor, Bzip2DecompressorJS, FilterJS, 00943 Bzip2DecompressorName, loggerModule, true> { 00944 00945 Bzip2DecompressorJS() 00946 { 00947 } 00948 00949 Bzip2DecompressorJS(const v8::Handle<v8::Object> & This, 00950 const std::shared_ptr<Bzip2Decompressor> & filter 00951 = std::shared_ptr<Bzip2Decompressor>()) 00952 { 00953 wrap(This, filter); 00954 } 00955 00956 static Handle<v8::Value> 00957 New(const Arguments & args) 00958 { 00959 try { 00960 new Bzip2DecompressorJS 00961 (args.This(), 00962 std::shared_ptr<Bzip2Decompressor>(new Bzip2Decompressor())); 00963 return args.This(); 00964 } HANDLE_JS_EXCEPTIONS; 00965 } 00966 00967 static void Initialize() 00968 { 00969 Persistent<FunctionTemplate> t = Register(New); 00970 } 00971 }; 00972 00973 std::shared_ptr<Bzip2Decompressor> 00974 from_js(const JSValue & value, std::shared_ptr<Bzip2Decompressor> *) 00975 { 00976 return Bzip2DecompressorJS::fromJS(value); 00977 } 00978 00979 Bzip2Decompressor * 00980 from_js(const JSValue & value, Bzip2Decompressor **) 00981 { 00982 return Bzip2DecompressorJS::fromJS(value).get(); 00983 } 00984 00985 00986 /*****************************************************************************/ 00987 /* JSON COMPRESSOR JS */ 00988 /*****************************************************************************/ 00989 00990 const char * JsonCompressorName = "JsonCompressor"; 00991 00992 struct JsonCompressorJS 00993 : public JSWrapped3<JsonCompressor, JsonCompressorJS, FilterJS, 00994 JsonCompressorName, loggerModule, true> { 00995 00996 JsonCompressorJS() 00997 { 00998 } 00999 01000 JsonCompressorJS(const v8::Handle<v8::Object> & This, 01001 const std::shared_ptr<JsonCompressor> & filter 01002 = std::shared_ptr<JsonCompressor>()) 01003 { 01004 wrap(This, filter); 01005 } 01006 01007 static Handle<v8::Value> 01008 New(const Arguments & args) 01009 { 01010 try { 01011 new JsonCompressorJS 01012 (args.This(), 01013 std::shared_ptr<JsonCompressor>(new JsonCompressor())); 01014 return args.This(); 01015 } HANDLE_JS_EXCEPTIONS; 01016 } 01017 01018 static void Initialize() 01019 { 01020 Persistent<FunctionTemplate> t = Register(New); 01021 } 01022 }; 01023 01024 std::shared_ptr<JsonCompressor> 01025 from_js(const JSValue & value, std::shared_ptr<JsonCompressor> *) 01026 { 01027 return JsonCompressorJS::fromJS(value); 01028 } 01029 01030 JsonCompressor * 01031 from_js(const JSValue & value, JsonCompressor **) 01032 { 01033 return JsonCompressorJS::fromJS(value).get(); 01034 } 01035 01036 01037 /*****************************************************************************/ 01038 /* JSON DECOMPRESSOR JS */ 01039 /*****************************************************************************/ 01040 01041 const char * JsonDecompressorName = "JsonDecompressor"; 01042 01043 struct JsonDecompressorJS 01044 : public JSWrapped3<JsonDecompressor, JsonDecompressorJS, FilterJS, 01045 JsonDecompressorName, loggerModule, true> { 01046 01047 JsonDecompressorJS() 01048 { 01049 } 01050 01051 JsonDecompressorJS(const v8::Handle<v8::Object> & This, 01052 const std::shared_ptr<JsonDecompressor> & filter 01053 = std::shared_ptr<JsonDecompressor>()) 01054 { 01055 wrap(This, filter); 01056 } 01057 01058 static Handle<v8::Value> 01059 New(const Arguments & args) 01060 { 01061 try { 01062 new JsonDecompressorJS 01063 (args.This(), 01064 std::shared_ptr<JsonDecompressor>(new JsonDecompressor())); 01065 return args.This(); 01066 } HANDLE_JS_EXCEPTIONS; 01067 } 01068 01069 static void Initialize() 01070 { 01071 Persistent<FunctionTemplate> t = Register(New); 01072 } 01073 }; 01074 01075 std::shared_ptr<JsonDecompressor> 01076 from_js(const JSValue & value, std::shared_ptr<JsonDecompressor> *) 01077 { 01078 return JsonDecompressorJS::fromJS(value); 01079 } 01080 01081 JsonDecompressor * 01082 from_js(const JSValue & value, JsonDecompressor **) 01083 { 01084 return JsonDecompressorJS::fromJS(value).get(); 01085 } 01086 01087 } // namespace JS 01088 } // namespace Datacratic