@@ -97,6 +97,7 @@ using v8::Local;
97
97
using v8::MaybeLocal;
98
98
using v8::Number;
99
99
using v8::Object;
100
+ using v8::Promise;
100
101
using v8::String;
101
102
using v8::Undefined;
102
103
using v8::Value;
@@ -127,30 +128,75 @@ void FSReqWrap::Resolve(Local<Value> value) {
127
128
MakeCallback (env ()->oncomplete_string (), arraysize (argv), argv);
128
129
}
129
130
130
- void FSReqWrap::Init (const char * syscall,
131
- const char * data,
132
- size_t len,
133
- enum encoding encoding) {
134
- syscall_ = syscall ;
135
- encoding_ = encoding;
136
-
137
- if (data != nullptr ) {
138
- CHECK_EQ (data_, nullptr );
139
- buffer_.AllocateSufficientStorage (len + 1 );
140
- buffer_.SetLengthAndZeroTerminate (len);
141
- memcpy (*buffer_, data, len);
142
- data_ = *buffer_;
143
- }
144
- }
145
-
146
131
void NewFSReqWrap (const FunctionCallbackInfo<Value>& args) {
147
132
CHECK (args.IsConstructCall ());
148
133
Environment* env = Environment::GetCurrent (args.GetIsolate ());
149
134
new FSReqWrap (env, args.This ());
150
135
}
151
136
137
+ FSReqPromise::FSReqPromise (Environment* env, Local<Object> req)
138
+ : FSReqBase(env, req, AsyncWrap::PROVIDER_FSREQPROMISE) {
139
+ auto resolver = Promise::Resolver::New (env->context ()).ToLocalChecked ();
140
+ req->Set (env->context (), env->promise_string (),
141
+ resolver.As <Promise>()).FromJust ();
142
+
143
+ Local<ArrayBuffer> ab =
144
+ ArrayBuffer::New (env->isolate (), statFields_,
145
+ sizeof (double ) * 14 ,
146
+ v8::ArrayBufferCreationMode::kInternalized );
147
+ object ()->Set (env->context (),
148
+ env->statfields_string (),
149
+ Float64Array::New (ab, 0 , 14 )).FromJust ();
150
+ }
151
+
152
+ FSReqPromise::~FSReqPromise () {
153
+ // Validate that the promise was explicitly resolved or rejected.
154
+ CHECK (finished_);
155
+ }
156
+
157
+ void FSReqPromise::Reject (Local<Value> reject) {
158
+ finished_ = true ;
159
+ InternalCallbackScope callback_scope (this );
160
+ HandleScope scope (env ()->isolate ());
161
+ Local<Value> value =
162
+ object ()->Get (env ()->context (),
163
+ env ()->promise_string ()).ToLocalChecked ();
164
+ CHECK (value->IsPromise ());
165
+ Local<Promise> promise = value.As <Promise>();
166
+ Local<Promise::Resolver> resolver = promise.As <Promise::Resolver>();
167
+ resolver->Reject (env ()->context (), reject);
168
+ }
169
+
170
+ void FSReqPromise::FillStatsArray (const uv_stat_t * stat) {
171
+ node::FillStatsArray (statFields_, stat);
172
+ }
152
173
153
- FSReqAfterScope::FSReqAfterScope (FSReqWrap* wrap, uv_fs_t * req)
174
+ void FSReqPromise::ResolveStat () {
175
+ Resolve (
176
+ object ()->Get (env ()->context (),
177
+ env ()->statfields_string ()).ToLocalChecked ());
178
+ }
179
+
180
+ void FSReqPromise::Resolve (Local<Value> value) {
181
+ finished_ = true ;
182
+ InternalCallbackScope callback_scope (this );
183
+ HandleScope scope (env ()->isolate ());
184
+ Local<Value> val =
185
+ object ()->Get (env ()->context (),
186
+ env ()->promise_string ()).ToLocalChecked ();
187
+ CHECK (val->IsPromise ());
188
+ Local<Promise> promise = val.As <Promise>();
189
+ Local<Promise::Resolver> resolver = promise.As <Promise::Resolver>();
190
+ resolver->Resolve (env ()->context (), value);
191
+ }
192
+
193
+ void NewFSReqPromise (const FunctionCallbackInfo<Value>& args) {
194
+ CHECK (args.IsConstructCall ());
195
+ Environment* env = Environment::GetCurrent (args.GetIsolate ());
196
+ new FSReqPromise (env, args.This ());
197
+ }
198
+
199
+ FSReqAfterScope::FSReqAfterScope (FSReqBase* wrap, uv_fs_t * req)
154
200
: wrap_(wrap),
155
201
req_ (req),
156
202
handle_scope_(wrap->env ()->isolate()),
@@ -190,15 +236,15 @@ bool FSReqAfterScope::Proceed() {
190
236
}
191
237
192
238
void AfterNoArgs (uv_fs_t * req) {
193
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
239
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
194
240
FSReqAfterScope after (req_wrap, req);
195
241
196
242
if (after.Proceed ())
197
243
req_wrap->Resolve (Undefined (req_wrap->env ()->isolate ()));
198
244
}
199
245
200
246
void AfterStat (uv_fs_t * req) {
201
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
247
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
202
248
FSReqAfterScope after (req_wrap, req);
203
249
204
250
if (after.Proceed ()) {
@@ -208,15 +254,15 @@ void AfterStat(uv_fs_t* req) {
208
254
}
209
255
210
256
void AfterInteger (uv_fs_t * req) {
211
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
257
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
212
258
FSReqAfterScope after (req_wrap, req);
213
259
214
260
if (after.Proceed ())
215
261
req_wrap->Resolve (Integer::New (req_wrap->env ()->isolate (), req->result ));
216
262
}
217
263
218
264
void AfterStringPath (uv_fs_t * req) {
219
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
265
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
220
266
FSReqAfterScope after (req_wrap, req);
221
267
222
268
MaybeLocal<Value> link ;
@@ -235,7 +281,7 @@ void AfterStringPath(uv_fs_t* req) {
235
281
}
236
282
237
283
void AfterStringPtr (uv_fs_t * req) {
238
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
284
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
239
285
FSReqAfterScope after (req_wrap, req);
240
286
241
287
MaybeLocal<Value> link ;
@@ -254,7 +300,7 @@ void AfterStringPtr(uv_fs_t* req) {
254
300
}
255
301
256
302
void AfterScanDir (uv_fs_t * req) {
257
- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
303
+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
258
304
FSReqAfterScope after (req_wrap, req);
259
305
260
306
if (after.Proceed ()) {
@@ -318,12 +364,12 @@ class fs_req_wrap {
318
364
};
319
365
320
366
template <typename Func, typename ... Args>
321
- inline FSReqWrap * AsyncDestCall (Environment* env,
367
+ inline FSReqBase * AsyncDestCall (Environment* env,
322
368
const FunctionCallbackInfo<Value>& args,
323
369
const char * syscall, const char * dest, size_t len,
324
370
enum encoding enc, uv_fs_cb after, Func fn, Args... fn_args) {
325
371
Local<Object> req = args[args.Length () - 1 ].As <Object>();
326
- FSReqWrap * req_wrap = Unwrap<FSReqWrap >(req);
372
+ FSReqBase * req_wrap = Unwrap<FSReqBase >(req);
327
373
CHECK_NE (req_wrap, nullptr );
328
374
req_wrap->Init (syscall , dest, len, enc);
329
375
int err = fn (env->event_loop (), req_wrap->req (), fn_args..., after);
@@ -343,7 +389,7 @@ inline FSReqWrap* AsyncDestCall(Environment* env,
343
389
}
344
390
345
391
template <typename Func, typename ... Args>
346
- inline FSReqWrap * AsyncCall (Environment* env,
392
+ inline FSReqBase * AsyncCall (Environment* env,
347
393
const FunctionCallbackInfo<Value>& args,
348
394
const char * syscall, enum encoding enc,
349
395
uv_fs_cb after, Func fn, Args... fn_args) {
@@ -1396,6 +1442,16 @@ void InitFs(Local<Object> target,
1396
1442
FIXED_ONE_BYTE_STRING (env->isolate (), " FSReqWrap" );
1397
1443
fst->SetClassName (wrapString);
1398
1444
target->Set (context, wrapString, fst->GetFunction ()).FromJust ();
1445
+
1446
+ // Create Function Template for FSReqPromise
1447
+ Local<FunctionTemplate> fpt =
1448
+ FunctionTemplate::New (env->isolate (), NewFSReqPromise);
1449
+ fpt->InstanceTemplate ()->SetInternalFieldCount (1 );
1450
+ AsyncWrap::AddWrapMethods (env, fpt);
1451
+ Local<String> promiseString =
1452
+ FIXED_ONE_BYTE_STRING (env->isolate (), " FSReqPromise" );
1453
+ fpt->SetClassName (promiseString);
1454
+ target->Set (context, promiseString, fpt->GetFunction ()).FromJust ();
1399
1455
}
1400
1456
1401
1457
} // namespace fs
0 commit comments