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_
|