You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

884 lines
30 KiB

  1. /**********************************************************************************
  2. * NAN - Native Abstractions for Node.js
  3. *
  4. * Copyright (c) 2013 NAN contributors:
  5. * - Rod Vagg <https://github.com/rvagg>
  6. * - Benjamin Byholm <https://github.com/kkoopa>
  7. * - Trevor Norris <https://github.com/trevnorris>
  8. *
  9. * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
  10. *
  11. * Version 0.3.2 (current Node unstable: 0.11.6, Node stable: 0.10.17)
  12. *
  13. * ChangeLog:
  14. * * 0.3.2 Aug 30 2013
  15. * - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent
  16. * in NanAsyncWorker
  17. *
  18. * * 0.3.1 Aug 20 2013
  19. * - fix "not all control paths return a value" compile warning on some platforms
  20. *
  21. * * 0.3.0 Aug 19 2013
  22. * - Made NAN work with NPM
  23. * - Lots of fixes to NanFromV8String, pulling in features from new Node core
  24. * - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API
  25. * - Added optional error number argument for NanThrowError()
  26. * - Added NanInitPersistent()
  27. * - Added NanReturnNull() and NanReturnEmptyString()
  28. * - Added NanLocker and NanUnlocker
  29. * - Added missing scopes
  30. * - Made sure to clear disposed Persistent handles
  31. * - Changed NanAsyncWorker to allocate error messages on the heap
  32. * - Changed NanThrowError(Local<Value>) to NanThrowError(Handle<Value>)
  33. * - Fixed leak in NanAsyncWorker when errmsg is used
  34. *
  35. * * 0.2.2 Aug 5 2013
  36. * - Fixed usage of undefined variable with node::BASE64 in NanFromV8String()
  37. *
  38. * * 0.2.1 Aug 5 2013
  39. * - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for
  40. * NanFromV8String()
  41. *
  42. * * 0.2.0 Aug 5 2013
  43. * - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR,
  44. * NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY
  45. * - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS,
  46. * _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS,
  47. * _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS,
  48. * _NAN_PROPERTY_QUERY_ARGS
  49. * - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer
  50. * - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT,
  51. * NAN_WEAK_CALLBACK_DATA, NanMakeWeak
  52. * - Renamed THROW_ERROR to _NAN_THROW_ERROR
  53. * - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*)
  54. * - Added NanBufferUse(char*, uint32_t)
  55. * - Added NanNewContextHandle(v8::ExtensionConfiguration*,
  56. * v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Value>)
  57. * - Fixed broken NanCallback#GetFunction()
  58. * - Added optional encoding and size arguments to NanFromV8String()
  59. * - Added NanGetPointerSafe() and NanSetPointerSafe()
  60. * - Added initial test suite (to be expanded)
  61. * - Allow NanUInt32OptionValue to convert any Number object
  62. *
  63. * * 0.1.0 Jul 21 2013
  64. * - Added `NAN_GETTER`, `NAN_SETTER`
  65. * - Added `NanThrowError` with single Local<Value> argument
  66. * - Added `NanNewBufferHandle` with single uint32_t argument
  67. * - Added `NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>)`
  68. * - Added `Local<Function> NanCallback#GetFunction()`
  69. * - Added `NanCallback#Call(int, Local<Value>[])`
  70. * - Deprecated `NanCallback#Run(int, Local<Value>[])` in favour of Call
  71. *
  72. * See https://github.com/rvagg/nan for the latest update to this file
  73. **********************************************************************************/
  74. #ifndef NAN_H
  75. #define NAN_H
  76. #include <node.h>
  77. #include <node_buffer.h>
  78. #include <string.h>
  79. // some generic helpers
  80. template<class T> static inline bool NanSetPointerSafe(T *var, T val) {
  81. if (var) {
  82. *var = val;
  83. return true;
  84. } else {
  85. return false;
  86. }
  87. }
  88. template<class T> static inline T NanGetPointerSafe(
  89. T *var,
  90. T fallback = reinterpret_cast<T>(0)) {
  91. if (var) {
  92. return *var;
  93. } else {
  94. return fallback;
  95. }
  96. }
  97. #define NanSymbol(value) v8::String::NewSymbol(value)
  98. static inline bool NanBooleanOptionValue(
  99. v8::Local<v8::Object> optionsObj
  100. , v8::Handle<v8::String> opt, bool def) {
  101. if (def) {
  102. return optionsObj.IsEmpty()
  103. || !optionsObj->Has(opt)
  104. || optionsObj->Get(opt)->BooleanValue();
  105. } else {
  106. return !optionsObj.IsEmpty()
  107. && optionsObj->Has(opt)
  108. && optionsObj->Get(opt)->BooleanValue();
  109. }
  110. }
  111. static inline bool NanBooleanOptionValue(
  112. v8::Local<v8::Object> optionsObj
  113. , v8::Handle<v8::String> opt) {
  114. return NanBooleanOptionValue(optionsObj, opt, false);
  115. }
  116. static inline uint32_t NanUInt32OptionValue(
  117. v8::Local<v8::Object> optionsObj
  118. , v8::Handle<v8::String> opt
  119. , uint32_t def) {
  120. return !optionsObj.IsEmpty()
  121. && optionsObj->Has(opt)
  122. && optionsObj->Get(opt)->IsNumber()
  123. ? optionsObj->Get(opt)->Uint32Value()
  124. : def;
  125. }
  126. #if (NODE_MODULE_VERSION > 0x000B)
  127. // Node 0.11+ (0.11.3 and below won't compile with these)
  128. static v8::Isolate* nan_isolate = v8::Isolate::GetCurrent();
  129. # define _NAN_METHOD_ARGS const v8::FunctionCallbackInfo<v8::Value>& args
  130. # define NAN_METHOD(name) void name(_NAN_METHOD_ARGS)
  131. # define _NAN_GETTER_ARGS const v8::PropertyCallbackInfo<v8::Value>& args
  132. # define NAN_GETTER(name) \
  133. void name(v8::Local<v8::String> property, _NAN_GETTER_ARGS)
  134. # define _NAN_SETTER_ARGS const v8::PropertyCallbackInfo<void>& args
  135. # define NAN_SETTER(name) \
  136. void name( \
  137. v8::Local<v8::String> property \
  138. , v8::Local<v8::Value> value \
  139. , _NAN_SETTER_ARGS)
  140. # define _NAN_PROPERTY_GETTER_ARGS \
  141. const v8::PropertyCallbackInfo<v8::Value>& args
  142. # define NAN_PROPERTY_GETTER(name) \
  143. void name(v8::Local<v8::String> property \
  144. , _NAN_PROPERTY_GETTER_ARGS)
  145. # define _NAN_PROPERTY_SETTER_ARGS \
  146. const v8::PropertyCallbackInfo<v8::Value>& args
  147. # define NAN_PROPERTY_SETTER(name) \
  148. void name(v8::Local<v8::String> property \
  149. , v8::Local<v8::Value> value \
  150. , _NAN_PROPERTY_SETTER_ARGS)
  151. # define _NAN_PROPERTY_ENUMERATOR_ARGS \
  152. const v8::PropertyCallbackInfo<v8::Array>& args
  153. # define NAN_PROPERTY_ENUMERATOR(name) \
  154. void name(_NAN_PROPERTY_ENUMERATOR_ARGS)
  155. # define _NAN_PROPERTY_DELETER_ARGS \
  156. const v8::PropertyCallbackInfo<v8::Boolean>& args
  157. # define NAN_PROPERTY_DELETER(name) \
  158. void name( \
  159. v8::Local<v8::String> property \
  160. , _NAN_PROPERTY_DELETER_ARGS)
  161. # define _NAN_PROPERTY_QUERY_ARGS \
  162. const v8::PropertyCallbackInfo<v8::Integer>& args
  163. # define NAN_PROPERTY_QUERY(name) \
  164. void name(v8::Local<v8::String> property, _NAN_PROPERTY_QUERY_ARGS)
  165. # define NanGetInternalFieldPointer(object, index) \
  166. object->GetAlignedPointerFromInternalField(index)
  167. # define NanSetInternalFieldPointer(object, index, value) \
  168. object->SetAlignedPointerInInternalField(index, value)
  169. # define NAN_WEAK_CALLBACK(type, name) \
  170. void name( \
  171. v8::Isolate* isolate, \
  172. v8::Persistent<v8::Object>* object, \
  173. type data)
  174. # define NAN_WEAK_CALLBACK_OBJECT (*object)
  175. # define NAN_WEAK_CALLBACK_DATA(type) ((type) data)
  176. # define NanScope() v8::HandleScope scope(nan_isolate)
  177. # define NanLocker() v8::Locker locker(nan_isolate)
  178. # define NanUnlocker() v8::Unlocker unlocker(nan_isolate)
  179. # define NanReturnValue(value) return args.GetReturnValue().Set(value)
  180. # define NanReturnUndefined() return
  181. # define NanReturnNull() return args.GetReturnValue().SetNull()
  182. # define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString()
  183. # define NanAssignPersistent(type, handle, obj) handle.Reset(nan_isolate, obj)
  184. # define NanInitPersistent(type, name, obj) \
  185. v8::Persistent<type> name(nan_isolate, obj)
  186. # define NanObjectWrapHandle(obj) obj->handle()
  187. # define NanMakeWeak(handle, parameter, callback) \
  188. handle.MakeWeak(nan_isolate, parameter, callback)
  189. # define _NAN_THROW_ERROR(fun, errmsg) \
  190. do { \
  191. NanScope(); \
  192. v8::ThrowException(fun(v8::String::New(errmsg))); \
  193. } while (0);
  194. inline static void NanThrowError(const char* errmsg) {
  195. _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
  196. }
  197. inline static void NanThrowError(v8::Handle<v8::Value> error) {
  198. NanScope();
  199. v8::ThrowException(error);
  200. }
  201. inline static void NanThrowError(const char *msg, const int errorNumber) {
  202. v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));
  203. v8::Local<v8::Object> obj = err.As<v8::Object>();
  204. obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));
  205. NanThrowError(err);
  206. }
  207. inline static void NanThrowTypeError(const char* errmsg) {
  208. _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
  209. }
  210. inline static void NanThrowRangeError(const char* errmsg) {
  211. _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
  212. }
  213. template<class T> static inline void NanDispose(v8::Persistent<T> &handle) {
  214. handle.Dispose(nan_isolate);
  215. handle.Clear();
  216. }
  217. static inline v8::Local<v8::Object> NanNewBufferHandle (
  218. char *data,
  219. size_t length,
  220. node::smalloc::FreeCallback callback,
  221. void *hint) {
  222. return node::Buffer::New(data, length, callback, hint);
  223. }
  224. static inline v8::Local<v8::Object> NanNewBufferHandle (
  225. char *data, uint32_t size) {
  226. return node::Buffer::New(data, size);
  227. }
  228. static inline v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
  229. return node::Buffer::New(size);
  230. }
  231. static inline v8::Local<v8::Object> NanBufferUse(char* data, uint32_t size) {
  232. return node::Buffer::Use(data, size);
  233. }
  234. template <class TypeName>
  235. inline v8::Local<TypeName> NanPersistentToLocal(
  236. const v8::Persistent<TypeName>& persistent) {
  237. if (persistent.IsWeak()) {
  238. return v8::Local<TypeName>::New(nan_isolate, persistent);
  239. } else {
  240. return *reinterpret_cast<v8::Local<TypeName>*>(
  241. const_cast<v8::Persistent<TypeName>*>(&persistent));
  242. }
  243. }
  244. inline bool NanHasInstance(
  245. v8::Persistent<v8::FunctionTemplate>& function_template
  246. , v8::Handle<v8::Value> value) {
  247. return NanPersistentToLocal(function_template)->HasInstance(value);
  248. }
  249. static inline v8::Local<v8::Context> NanNewContextHandle(
  250. v8::ExtensionConfiguration* extensions = NULL,
  251. v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>(),
  252. v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()) {
  253. return v8::Local<v8::Context>::New(nan_isolate, v8::Context::New(
  254. nan_isolate, extensions, tmpl, obj));
  255. }
  256. #else
  257. // Node 0.8 and 0.10
  258. # define _NAN_METHOD_ARGS const v8::Arguments& args
  259. # define NAN_METHOD(name) v8::Handle<v8::Value> name(_NAN_METHOD_ARGS)
  260. # define _NAN_GETTER_ARGS const v8::AccessorInfo &args
  261. # define NAN_GETTER(name) \
  262. v8::Handle<v8::Value> name(v8::Local<v8::String> property, _NAN_GETTER_ARGS)
  263. # define _NAN_SETTER_ARGS const v8::AccessorInfo &args
  264. # define NAN_SETTER(name) \
  265. void name( \
  266. v8::Local<v8::String> property \
  267. , v8::Local<v8::Value> value \
  268. , _NAN_SETTER_ARGS)
  269. # define _NAN_PROPERTY_GETTER_ARGS const v8::AccessorInfo& args
  270. # define NAN_PROPERTY_GETTER(name) \
  271. v8::Handle<v8::Value> name(v8::Local<v8::String> property \
  272. , _NAN_PROPERTY_GETTER_ARGS)
  273. # define _NAN_PROPERTY_SETTER_ARGS const v8::AccessorInfo& args
  274. # define NAN_PROPERTY_SETTER(name) \
  275. v8::Handle<v8::Value> name(v8::Local<v8::String> property \
  276. , v8::Local<v8::Value> value \
  277. , _NAN_PROPERTY_SETTER_ARGS)
  278. # define _NAN_PROPERTY_ENUMERATOR_ARGS const v8::AccessorInfo& args
  279. # define NAN_PROPERTY_ENUMERATOR(name) \
  280. v8::Handle<v8::Array> name(_NAN_PROPERTY_ENUMERATOR_ARGS)
  281. # define _NAN_PROPERTY_DELETER_ARGS const v8::AccessorInfo& args
  282. # define NAN_PROPERTY_DELETER(name) \
  283. v8::Handle<v8::Boolean> name( \
  284. v8::Local<v8::String> property \
  285. , _NAN_PROPERTY_DELETER_ARGS)
  286. # define _NAN_PROPERTY_QUERY_ARGS const v8::AccessorInfo& args
  287. # define NAN_PROPERTY_QUERY(name) \
  288. v8::Handle<v8::Integer> name( \
  289. v8::Local<v8::String> property \
  290. , _NAN_PROPERTY_QUERY_ARGS)
  291. # define NanGetInternalFieldPointer(object, index) \
  292. object->GetPointerFromInternalField(index)
  293. # define NanSetInternalFieldPointer(object, index, value) \
  294. object->SetPointerInInternalField(index, value)
  295. # define NAN_WEAK_CALLBACK(type, name) void name( \
  296. v8::Persistent<v8::Value> object, \
  297. void *data)
  298. # define NAN_WEAK_CALLBACK_OBJECT object
  299. # define NAN_WEAK_CALLBACK_DATA(type) ((type) data)
  300. # define NanScope() v8::HandleScope scope
  301. # define NanLocker() v8::Locker locker
  302. # define NanUnlocker() v8::Unlocker unlocker
  303. # define NanReturnValue(value) return scope.Close(value)
  304. # define NanReturnUndefined() return v8::Undefined()
  305. # define NanReturnNull() return v8::Null()
  306. # define NanReturnEmptyString() return v8::String::Empty()
  307. # define NanInitPersistent(type, name, obj) \
  308. v8::Persistent<type> name = v8::Persistent<type>::New(obj)
  309. # define NanAssignPersistent(type, handle, obj) \
  310. handle = v8::Persistent<type>::New(obj)
  311. # define NanObjectWrapHandle(obj) obj->handle_
  312. # define NanMakeWeak(handle, parameters, callback) \
  313. handle.MakeWeak(parameters, callback)
  314. # define _NAN_THROW_ERROR(fun, errmsg) \
  315. do { \
  316. NanScope(); \
  317. return v8::ThrowException(fun(v8::String::New(errmsg))); \
  318. } while (0);
  319. inline static v8::Handle<v8::Value> NanThrowError(const char* errmsg) {
  320. _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
  321. }
  322. inline static v8::Handle<v8::Value> NanThrowError(
  323. v8::Handle<v8::Value> error) {
  324. NanScope();
  325. return v8::ThrowException(error);
  326. }
  327. inline static v8::Handle<v8::Value> NanThrowError(
  328. const char *msg,
  329. const int errorNumber) {
  330. v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));
  331. v8::Local<v8::Object> obj = err.As<v8::Object>();
  332. obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));
  333. return NanThrowError(err);
  334. }
  335. inline static v8::Handle<v8::Value> NanThrowTypeError(const char* errmsg) {
  336. _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
  337. }
  338. inline static v8::Handle<v8::Value> NanThrowRangeError(const char* errmsg) {
  339. _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
  340. }
  341. template<class T> static inline void NanDispose(v8::Persistent<T> &handle) {
  342. handle.Dispose();
  343. handle.Clear();
  344. }
  345. static inline v8::Local<v8::Object> NanNewBufferHandle (
  346. char *data,
  347. size_t length,
  348. node::Buffer::free_callback callback,
  349. void *hint) {
  350. return v8::Local<v8::Object>::New(
  351. node::Buffer::New(data, length, callback, hint)->handle_);
  352. }
  353. static inline v8::Local<v8::Object> NanNewBufferHandle (
  354. char *data, uint32_t size) {
  355. return v8::Local<v8::Object>::New(node::Buffer::New(data, size)->handle_);
  356. }
  357. static inline v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
  358. return v8::Local<v8::Object>::New(node::Buffer::New(size)->handle_);
  359. }
  360. static inline void FreeData(char *data, void *hint) {
  361. delete[] data;
  362. }
  363. static inline v8::Local<v8::Object> NanBufferUse(char* data, uint32_t size) {
  364. return v8::Local<v8::Object>::New(
  365. node::Buffer::New(data, size, FreeData, NULL)->handle_);
  366. }
  367. template <class TypeName>
  368. inline v8::Local<TypeName> NanPersistentToLocal(
  369. const v8::Persistent<TypeName>& persistent) {
  370. if (persistent.IsWeak()) {
  371. return v8::Local<TypeName>::New(persistent);
  372. } else {
  373. return *reinterpret_cast<v8::Local<TypeName>*>(
  374. const_cast<v8::Persistent<TypeName>*>(&persistent));
  375. }
  376. }
  377. inline bool NanHasInstance(
  378. v8::Persistent<v8::FunctionTemplate>& function_template
  379. , v8::Handle<v8::Value> value) {
  380. return function_template->HasInstance(value);
  381. }
  382. static inline v8::Local<v8::Context> NanNewContextHandle(
  383. v8::ExtensionConfiguration* extensions = NULL
  384. , v8::Handle<v8::ObjectTemplate> tmpl =
  385. v8::Handle<v8::ObjectTemplate>()
  386. , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
  387. ) {
  388. v8::Persistent<v8::Context> ctx =
  389. v8::Context::New(extensions, tmpl, obj);
  390. v8::Local<v8::Context> lctx = v8::Local<v8::Context>::New(ctx);
  391. ctx.Dispose();
  392. return lctx;
  393. }
  394. #endif // node version
  395. class NanCallback {
  396. public:
  397. NanCallback(const v8::Local<v8::Function> &fn) {
  398. NanScope();
  399. v8::Local<v8::Object> obj = v8::Object::New();
  400. obj->Set(NanSymbol("callback"), fn);
  401. NanAssignPersistent(v8::Object, handle, obj);
  402. }
  403. ~NanCallback() {
  404. if (handle.IsEmpty()) return;
  405. handle.Dispose();
  406. handle.Clear();
  407. }
  408. inline v8::Local<v8::Function> GetFunction () {
  409. return NanPersistentToLocal(handle)->Get(NanSymbol("callback"))
  410. .As<v8::Function>();
  411. }
  412. // deprecated
  413. void Run(int argc, v8::Local<v8::Value> argv[]) {
  414. Call(argc, argv);
  415. }
  416. void Call(int argc, v8::Local<v8::Value> argv[]) {
  417. NanScope();
  418. v8::Local<v8::Function> callback = NanPersistentToLocal(handle)->
  419. Get(NanSymbol("callback")).As<v8::Function>();
  420. v8::TryCatch try_catch;
  421. callback->Call(v8::Context::GetCurrent()->Global(), argc, argv);
  422. if (try_catch.HasCaught()) {
  423. node::FatalException(try_catch);
  424. }
  425. }
  426. private:
  427. v8::Persistent<v8::Object> handle;
  428. };
  429. /* abstract */ class NanAsyncWorker {
  430. public:
  431. NanAsyncWorker (NanCallback *callback) : callback(callback) {
  432. request.data = this;
  433. errmsg = NULL;
  434. }
  435. virtual ~NanAsyncWorker () {
  436. NanScope();
  437. if (!persistentHandle.IsEmpty())
  438. NanDispose(persistentHandle);
  439. if (callback)
  440. delete callback;
  441. if (errmsg)
  442. delete errmsg;
  443. }
  444. virtual void WorkComplete () {
  445. NanScope();
  446. if (errmsg == NULL)
  447. HandleOKCallback();
  448. else
  449. HandleErrorCallback();
  450. delete callback;
  451. callback = NULL;
  452. }
  453. virtual void Execute () =0;
  454. uv_work_t request;
  455. protected:
  456. v8::Persistent<v8::Object> persistentHandle;
  457. NanCallback *callback;
  458. const char *errmsg;
  459. void SavePersistent(const char *key, v8::Local<v8::Object> &obj) {
  460. NanScope();
  461. v8::Local<v8::Object> handle = NanPersistentToLocal(persistentHandle);
  462. handle->Set(NanSymbol(key), obj);
  463. }
  464. v8::Local<v8::Object> GetFromPersistent(const char *key) {
  465. NanScope();
  466. v8::Local<v8::Object> handle = NanPersistentToLocal(persistentHandle);
  467. return handle->Get(NanSymbol(key)).As<v8::Object>();
  468. }
  469. virtual void HandleOKCallback () {
  470. NanScope();
  471. callback->Call(0, NULL);
  472. };
  473. virtual void HandleErrorCallback () {
  474. NanScope();
  475. v8::Local<v8::Value> argv[] = {
  476. v8::Exception::Error(v8::String::New(errmsg))
  477. };
  478. callback->Call(1, argv);
  479. }
  480. };
  481. inline void NanAsyncExecute (uv_work_t* req) {
  482. NanAsyncWorker *worker = static_cast<NanAsyncWorker*>(req->data);
  483. worker->Execute();
  484. }
  485. inline void NanAsyncExecuteComplete (uv_work_t* req) {
  486. NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(req->data);
  487. worker->WorkComplete();
  488. delete worker;
  489. }
  490. inline void NanAsyncQueueWorker (NanAsyncWorker* worker) {
  491. uv_queue_work(
  492. uv_default_loop()
  493. , &worker->request
  494. , NanAsyncExecute
  495. , (uv_after_work_cb)NanAsyncExecuteComplete
  496. );
  497. }
  498. //// Base 64 ////
  499. #define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4)
  500. // Doesn't check for padding at the end. Can be 1-2 bytes over.
  501. static inline size_t _nan_base64_decoded_size_fast(size_t size) {
  502. size_t remainder = size % 4;
  503. size = (size / 4) * 3;
  504. if (remainder) {
  505. if (size == 0 && remainder == 1) {
  506. // special case: 1-byte input cannot be decoded
  507. size = 0;
  508. } else {
  509. // non-padded input, add 1 or 2 extra bytes
  510. size += 1 + (remainder == 3);
  511. }
  512. }
  513. return size;
  514. }
  515. template <typename TypeName>
  516. static size_t _nan_base64_decoded_size(const TypeName* src, size_t size) {
  517. if (size == 0)
  518. return 0;
  519. if (src[size - 1] == '=')
  520. size--;
  521. if (size > 0 && src[size - 1] == '=')
  522. size--;
  523. return _nan_base64_decoded_size_fast(size);
  524. }
  525. // supports regular and URL-safe base64
  526. static const int _nan_unbase64_table[] =
  527. { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1,
  528. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  529. -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63,
  530. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  531. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  532. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
  533. -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  534. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
  535. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  536. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  537. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  538. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  539. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  540. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  541. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  542. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  543. };
  544. #define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)]
  545. template <typename TypeName>
  546. static size_t _nan_base64_decode(char* buf,
  547. size_t len,
  548. const TypeName* src,
  549. const size_t srcLen) {
  550. char a, b, c, d;
  551. char* dst = buf;
  552. char* dstEnd = buf + len;
  553. const TypeName* srcEnd = src + srcLen;
  554. while (src < srcEnd && dst < dstEnd) {
  555. int remaining = srcEnd - src;
  556. while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
  557. if (remaining == 0 || *src == '=') break;
  558. a = _nan_unbase64(*src++);
  559. while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
  560. if (remaining <= 1 || *src == '=') break;
  561. b = _nan_unbase64(*src++);
  562. *dst++ = (a << 2) | ((b & 0x30) >> 4);
  563. if (dst == dstEnd) break;
  564. while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
  565. if (remaining <= 2 || *src == '=') break;
  566. c = _nan_unbase64(*src++);
  567. *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2);
  568. if (dst == dstEnd) break;
  569. while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
  570. if (remaining <= 3 || *src == '=') break;
  571. d = _nan_unbase64(*src++);
  572. *dst++ = ((c & 0x03) << 6) | (d & 0x3F);
  573. }
  574. return dst - buf;
  575. }
  576. //// HEX ////
  577. template <typename TypeName>
  578. unsigned _nan_hex2bin(TypeName c) {
  579. if (c >= '0' && c <= '9') return c - '0';
  580. if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
  581. if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
  582. return static_cast<unsigned>(-1);
  583. }
  584. template <typename TypeName>
  585. static size_t _nan_hex_decode(char* buf,
  586. size_t len,
  587. const TypeName* src,
  588. const size_t srcLen) {
  589. size_t i;
  590. for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {
  591. unsigned a = _nan_hex2bin(src[i * 2 + 0]);
  592. unsigned b = _nan_hex2bin(src[i * 2 + 1]);
  593. if (!~a || !~b) return i;
  594. buf[i] = a * 16 + b;
  595. }
  596. return i;
  597. }
  598. static bool _NanGetExternalParts(
  599. v8::Handle<v8::Value> val
  600. , const char** data
  601. , size_t* len) {
  602. if (node::Buffer::HasInstance(val)) {
  603. *data = node::Buffer::Data(val.As<v8::Object>());
  604. *len = node::Buffer::Length(val.As<v8::Object>());
  605. return true;
  606. }
  607. assert(val->IsString());
  608. v8::Local<v8::String> str = v8::Local<v8::String>::New(val.As<v8::String>());
  609. if (str->IsExternalAscii()) {
  610. const v8::String::ExternalAsciiStringResource* ext;
  611. ext = str->GetExternalAsciiStringResource();
  612. *data = ext->data();
  613. *len = ext->length();
  614. return true;
  615. } else if (str->IsExternal()) {
  616. const v8::String::ExternalStringResource* ext;
  617. ext = str->GetExternalStringResource();
  618. *data = reinterpret_cast<const char*>(ext->data());
  619. *len = ext->length();
  620. return true;
  621. }
  622. return false;
  623. }
  624. namespace Nan {
  625. enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
  626. }
  627. static inline char* NanFromV8String(
  628. v8::Handle<v8::Value> from
  629. , enum Nan::Encoding encoding = Nan::UTF8
  630. , size_t *datalen = NULL
  631. , char *buf = NULL
  632. , size_t buflen = 0
  633. , int flags = v8::String::NO_NULL_TERMINATION
  634. | v8::String::HINT_MANY_WRITES_EXPECTED) {
  635. NanScope();
  636. size_t sz_;
  637. size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION);
  638. char *data = NULL;
  639. size_t len;
  640. bool is_extern = _NanGetExternalParts(
  641. from
  642. , const_cast<const char**>(&data)
  643. , &len);
  644. if (is_extern && !term_len) {
  645. NanSetPointerSafe(datalen, len);
  646. return data;
  647. }
  648. v8::Local<v8::String> toStr = from->ToString();
  649. char *to = buf;
  650. v8::String::AsciiValue value(toStr);
  651. switch(encoding) {
  652. case Nan::ASCII:
  653. #if NODE_MODULE_VERSION < 0x0C
  654. sz_ = toStr->Length();
  655. if (to == NULL) {
  656. to = new char[sz_ + term_len];
  657. } else {
  658. assert(buflen >= sz_ + term_len && "too small buffer");
  659. }
  660. NanSetPointerSafe<size_t>(
  661. datalen
  662. , toStr->WriteAscii(to, 0, sz_ + term_len, flags));
  663. return to;
  664. #endif
  665. case Nan::BINARY:
  666. case Nan::BUFFER:
  667. sz_ = toStr->Length();
  668. if (to == NULL) {
  669. to = new char[sz_ + term_len];
  670. } else {
  671. assert(buflen >= sz_ + term_len && "too small buffer");
  672. }
  673. #if NODE_MODULE_VERSION < 0x0C
  674. // TODO(isaacs): THIS IS AWFUL!!!
  675. // AGREE(kkoopa)
  676. {
  677. uint16_t* twobytebuf = new uint16_t[sz_ + term_len];
  678. size_t len = toStr->Write(twobytebuf, 0, sz_ + term_len, flags);
  679. for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) {
  680. unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
  681. to[i] = *b;
  682. }
  683. NanSetPointerSafe<size_t>(datalen, len);
  684. delete[] twobytebuf;
  685. return to;
  686. }
  687. #else
  688. NanSetPointerSafe<size_t>(
  689. datalen,
  690. toStr->WriteOneByte(
  691. reinterpret_cast<uint8_t *>(to)
  692. , 0
  693. , sz_ + term_len
  694. , flags));
  695. return to;
  696. #endif
  697. case Nan::UTF8:
  698. sz_ = toStr->Utf8Length();
  699. if (to == NULL) {
  700. to = new char[sz_ + term_len];
  701. } else {
  702. assert(buflen >= sz_ + term_len && "too small buffer");
  703. }
  704. NanSetPointerSafe<size_t>(
  705. datalen
  706. , toStr->WriteUtf8(to, sz_ + term_len, NULL, flags) - term_len);
  707. return to;
  708. case Nan::BASE64:
  709. sz_ = _nan_base64_decoded_size(*value, toStr->Length());
  710. if (to == NULL) {
  711. to = new char[sz_ + term_len];
  712. } else {
  713. assert(buflen >= sz_ + term_len);
  714. }
  715. NanSetPointerSafe<size_t>(
  716. datalen
  717. , _nan_base64_decode(to, sz_, *value, value.length()));
  718. if (term_len) {
  719. to[sz_] = '\0';
  720. }
  721. return to;
  722. case Nan::UCS2:
  723. {
  724. sz_ = toStr->Length();
  725. if (to == NULL) {
  726. to = new char[(sz_ + term_len) * 2];
  727. } else {
  728. assert(buflen >= (sz_ + term_len) * 2 && "too small buffer");
  729. }
  730. int bc = 2 * toStr->Write(
  731. reinterpret_cast<uint16_t *>(to)
  732. , 0
  733. , sz_ + term_len
  734. , flags);
  735. NanSetPointerSafe<size_t>(datalen, bc);
  736. return to;
  737. }
  738. case Nan::HEX:
  739. sz_ = toStr->Length();
  740. assert(!(sz_ & 1) && "bad hex data");
  741. if (to == NULL) {
  742. to = new char[sz_ / 2 + term_len];
  743. } else {
  744. assert(buflen >= sz_ / 2 + term_len && "too small buffer");
  745. }
  746. NanSetPointerSafe<size_t>(
  747. datalen
  748. , _nan_hex_decode(to, sz_ / 2, *value, value.length()));
  749. if (term_len) {
  750. to[sz_ / 2] = '\0';
  751. }
  752. return to;
  753. default:
  754. assert(0 && "unknown encoding");
  755. }
  756. return to;
  757. }
  758. #endif