nan_json.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*********************************************************************
  2. * NAN - Native Abstractions for Node.js
  3. *
  4. * Copyright (c) 2017 NAN contributors
  5. *
  6. * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
  7. ********************************************************************/
  8. #ifndef NAN_JSON_H_
  9. #define NAN_JSON_H_
  10. #if NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION
  11. #define NAN_JSON_H_NEED_PARSE 1
  12. #else
  13. #define NAN_JSON_H_NEED_PARSE 0
  14. #endif // NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION
  15. #if NODE_MODULE_VERSION >= NODE_7_0_MODULE_VERSION
  16. #define NAN_JSON_H_NEED_STRINGIFY 0
  17. #else
  18. #define NAN_JSON_H_NEED_STRINGIFY 1
  19. #endif // NODE_MODULE_VERSION >= NODE_7_0_MODULE_VERSION
  20. class JSON {
  21. public:
  22. JSON() {
  23. #if NAN_JSON_H_NEED_PARSE + NAN_JSON_H_NEED_STRINGIFY
  24. Nan::HandleScope scope;
  25. Nan::MaybeLocal<v8::Value> maybe_global_json = Nan::Get(
  26. Nan::GetCurrentContext()->Global(),
  27. Nan::New("JSON").ToLocalChecked()
  28. );
  29. assert(!maybe_global_json.IsEmpty() && "global JSON is empty");
  30. v8::Local<v8::Value> val_global_json = maybe_global_json.ToLocalChecked();
  31. assert(val_global_json->IsObject() && "global JSON is not an object");
  32. Nan::MaybeLocal<v8::Object> maybe_obj_global_json =
  33. Nan::To<v8::Object>(val_global_json);
  34. assert(!maybe_obj_global_json.IsEmpty() && "global JSON object is empty");
  35. v8::Local<v8::Object> global_json = maybe_obj_global_json.ToLocalChecked();
  36. #if NAN_JSON_H_NEED_PARSE
  37. Nan::MaybeLocal<v8::Value> maybe_parse_method = Nan::Get(
  38. global_json, Nan::New("parse").ToLocalChecked()
  39. );
  40. assert(!maybe_parse_method.IsEmpty() && "JSON.parse is empty");
  41. v8::Local<v8::Value> parse_method = maybe_parse_method.ToLocalChecked();
  42. assert(parse_method->IsFunction() && "JSON.parse is not a function");
  43. parse_cb_.Reset(parse_method.As<v8::Function>());
  44. #endif // NAN_JSON_H_NEED_PARSE
  45. #if NAN_JSON_H_NEED_STRINGIFY
  46. Nan::MaybeLocal<v8::Value> maybe_stringify_method = Nan::Get(
  47. global_json, Nan::New("stringify").ToLocalChecked()
  48. );
  49. assert(!maybe_stringify_method.IsEmpty() && "JSON.stringify is empty");
  50. v8::Local<v8::Value> stringify_method =
  51. maybe_stringify_method.ToLocalChecked();
  52. assert(
  53. stringify_method->IsFunction() && "JSON.stringify is not a function"
  54. );
  55. stringify_cb_.Reset(stringify_method.As<v8::Function>());
  56. #endif // NAN_JSON_H_NEED_STRINGIFY
  57. #endif // NAN_JSON_H_NEED_PARSE + NAN_JSON_H_NEED_STRINGIFY
  58. }
  59. inline
  60. Nan::MaybeLocal<v8::Value> Parse(v8::Local<v8::String> json_string) {
  61. Nan::EscapableHandleScope scope;
  62. #if NAN_JSON_H_NEED_PARSE
  63. return scope.Escape(parse(json_string));
  64. #else
  65. Nan::MaybeLocal<v8::Value> result;
  66. #if NODE_MODULE_VERSION == NODE_0_12_MODULE_VERSION
  67. result = v8::JSON::Parse(json_string);
  68. #else
  69. #if NODE_MODULE_VERSION > NODE_6_0_MODULE_VERSION
  70. v8::Local<v8::Context> context_or_isolate = Nan::GetCurrentContext();
  71. #else
  72. v8::Isolate* context_or_isolate = v8::Isolate::GetCurrent();
  73. #endif // NODE_MODULE_VERSION > NODE_6_0_MODULE_VERSION
  74. result = v8::JSON::Parse(context_or_isolate, json_string);
  75. #endif // NODE_MODULE_VERSION == NODE_0_12_MODULE_VERSION
  76. if (result.IsEmpty()) return v8::Local<v8::Value>();
  77. return scope.Escape(result.ToLocalChecked());
  78. #endif // NAN_JSON_H_NEED_PARSE
  79. }
  80. inline
  81. Nan::MaybeLocal<v8::String> Stringify(v8::Local<v8::Object> json_object) {
  82. Nan::EscapableHandleScope scope;
  83. Nan::MaybeLocal<v8::String> result =
  84. #if NAN_JSON_H_NEED_STRINGIFY
  85. Nan::To<v8::String>(stringify(json_object));
  86. #else
  87. v8::JSON::Stringify(Nan::GetCurrentContext(), json_object);
  88. #endif // NAN_JSON_H_NEED_STRINGIFY
  89. if (result.IsEmpty()) return v8::Local<v8::String>();
  90. return scope.Escape(result.ToLocalChecked());
  91. }
  92. inline
  93. Nan::MaybeLocal<v8::String> Stringify(v8::Local<v8::Object> json_object,
  94. v8::Local<v8::String> gap) {
  95. Nan::EscapableHandleScope scope;
  96. Nan::MaybeLocal<v8::String> result =
  97. #if NAN_JSON_H_NEED_STRINGIFY
  98. Nan::To<v8::String>(stringify(json_object, gap));
  99. #else
  100. v8::JSON::Stringify(Nan::GetCurrentContext(), json_object, gap);
  101. #endif // NAN_JSON_H_NEED_STRINGIFY
  102. if (result.IsEmpty()) return v8::Local<v8::String>();
  103. return scope.Escape(result.ToLocalChecked());
  104. }
  105. private:
  106. NAN_DISALLOW_ASSIGN_COPY_MOVE(JSON)
  107. #if NAN_JSON_H_NEED_PARSE
  108. Nan::Callback parse_cb_;
  109. #endif // NAN_JSON_H_NEED_PARSE
  110. #if NAN_JSON_H_NEED_STRINGIFY
  111. Nan::Callback stringify_cb_;
  112. #endif // NAN_JSON_H_NEED_STRINGIFY
  113. #if NAN_JSON_H_NEED_PARSE
  114. inline v8::Local<v8::Value> parse(v8::Local<v8::Value> arg) {
  115. assert(!parse_cb_.IsEmpty() && "parse_cb_ is empty");
  116. return parse_cb_.Call(1, &arg);
  117. }
  118. #endif // NAN_JSON_H_NEED_PARSE
  119. #if NAN_JSON_H_NEED_STRINGIFY
  120. inline v8::Local<v8::Value> stringify(v8::Local<v8::Value> arg) {
  121. assert(!stringify_cb_.IsEmpty() && "stringify_cb_ is empty");
  122. return stringify_cb_.Call(1, &arg);
  123. }
  124. inline v8::Local<v8::Value> stringify(v8::Local<v8::Value> arg,
  125. v8::Local<v8::String> gap) {
  126. assert(!stringify_cb_.IsEmpty() && "stringify_cb_ is empty");
  127. v8::Local<v8::Value> argv[] = {
  128. arg,
  129. Nan::Null(),
  130. gap
  131. };
  132. return stringify_cb_.Call(3, argv);
  133. }
  134. #endif // NAN_JSON_H_NEED_STRINGIFY
  135. };
  136. #endif // NAN_JSON_H_