@@ -97,6 +97,7 @@ using v8::Local;
9797using v8::MaybeLocal;
9898using v8::Number;
9999using v8::Object;
100+ using v8::Promise;
100101using v8::String;
101102using v8::Undefined;
102103using v8::Value;
@@ -127,30 +128,75 @@ void FSReqWrap::Resolve(Local<Value> value) {
127128 MakeCallback (env ()->oncomplete_string (), arraysize (argv), argv);
128129}
129130
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-
146131void NewFSReqWrap (const FunctionCallbackInfo<Value>& args) {
147132 CHECK (args.IsConstructCall ());
148133 Environment* env = Environment::GetCurrent (args.GetIsolate ());
149134 new FSReqWrap (env, args.This ());
150135}
151136
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+ }
152173
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)
154200 : wrap_(wrap),
155201 req_ (req),
156202 handle_scope_(wrap->env ()->isolate()),
@@ -190,15 +236,15 @@ bool FSReqAfterScope::Proceed() {
190236}
191237
192238void AfterNoArgs (uv_fs_t * req) {
193- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
239+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
194240 FSReqAfterScope after (req_wrap, req);
195241
196242 if (after.Proceed ())
197243 req_wrap->Resolve (Undefined (req_wrap->env ()->isolate ()));
198244}
199245
200246void AfterStat (uv_fs_t * req) {
201- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
247+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
202248 FSReqAfterScope after (req_wrap, req);
203249
204250 if (after.Proceed ()) {
@@ -208,15 +254,15 @@ void AfterStat(uv_fs_t* req) {
208254}
209255
210256void AfterInteger (uv_fs_t * req) {
211- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
257+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
212258 FSReqAfterScope after (req_wrap, req);
213259
214260 if (after.Proceed ())
215261 req_wrap->Resolve (Integer::New (req_wrap->env ()->isolate (), req->result ));
216262}
217263
218264void AfterStringPath (uv_fs_t * req) {
219- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
265+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
220266 FSReqAfterScope after (req_wrap, req);
221267
222268 MaybeLocal<Value> link;
@@ -235,7 +281,7 @@ void AfterStringPath(uv_fs_t* req) {
235281}
236282
237283void AfterStringPtr (uv_fs_t * req) {
238- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
284+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
239285 FSReqAfterScope after (req_wrap, req);
240286
241287 MaybeLocal<Value> link;
@@ -254,7 +300,7 @@ void AfterStringPtr(uv_fs_t* req) {
254300}
255301
256302void AfterScanDir (uv_fs_t * req) {
257- FSReqWrap * req_wrap = static_cast <FSReqWrap *>(req->data );
303+ FSReqBase * req_wrap = static_cast <FSReqBase *>(req->data );
258304 FSReqAfterScope after (req_wrap, req);
259305
260306 if (after.Proceed ()) {
@@ -318,12 +364,12 @@ class fs_req_wrap {
318364};
319365
320366template <typename Func, typename ... Args>
321- inline FSReqWrap * AsyncDestCall (Environment* env,
367+ inline FSReqBase * AsyncDestCall (Environment* env,
322368 const FunctionCallbackInfo<Value>& args,
323369 const char * syscall, const char * dest, size_t len,
324370 enum encoding enc, uv_fs_cb after, Func fn, Args... fn_args) {
325371 Local<Object> req = args[args.Length () - 1 ].As <Object>();
326- FSReqWrap * req_wrap = Unwrap<FSReqWrap >(req);
372+ FSReqBase * req_wrap = Unwrap<FSReqBase >(req);
327373 CHECK_NE (req_wrap, nullptr );
328374 req_wrap->Init (syscall, dest, len, enc);
329375 int err = fn (env->event_loop (), req_wrap->req (), fn_args..., after);
@@ -343,7 +389,7 @@ inline FSReqWrap* AsyncDestCall(Environment* env,
343389}
344390
345391template <typename Func, typename ... Args>
346- inline FSReqWrap * AsyncCall (Environment* env,
392+ inline FSReqBase * AsyncCall (Environment* env,
347393 const FunctionCallbackInfo<Value>& args,
348394 const char * syscall, enum encoding enc,
349395 uv_fs_cb after, Func fn, Args... fn_args) {
@@ -1396,6 +1442,16 @@ void InitFs(Local<Object> target,
13961442 FIXED_ONE_BYTE_STRING (env->isolate (), " FSReqWrap" );
13971443 fst->SetClassName (wrapString);
13981444 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 ();
13991455}
14001456
14011457} // namespace fs
0 commit comments