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