@@ -59,8 +59,8 @@ DirHandle::DirHandle(Environment* env, Local<Object> obj, uv_dir_t* dir)
5959      dir_ (dir) {
6060  MakeWeak ();
6161
62-   dir_->nentries  = 1 ;
63-   dir_->dirents  = &dirent_ ;
62+   dir_->nentries  = arraysize (dirents_) ;
63+   dir_->dirents  = dirents_ ;
6464}
6565
6666DirHandle* DirHandle::New (Environment* env, uv_dir_t * dir) {
@@ -160,7 +160,37 @@ void DirHandle::Close(const FunctionCallbackInfo<Value>& args) {
160160  }
161161}
162162
163- void  AfterDirReadSingle (uv_fs_t * req) {
163+ static  MaybeLocal<Array> DirentListToArray (
164+     Environment* env,
165+     uv_dirent_t * ents,
166+     int  num,
167+     enum  encoding encoding,
168+     Local<Value>* err_out) {
169+   MaybeStackBuffer<Local<Value>, 96 > entries (num * 3 );
170+ 
171+   //  Return an array of all read filenames.
172+   int  j = 0 ;
173+   for  (int  i = 0 ; i < num; i++) {
174+     Local<Value> filename;
175+     Local<Value> error;
176+     const  size_t  namelen = strlen (ents[i].name );
177+     if  (!StringBytes::Encode (env->isolate (),
178+                              ents[i].name ,
179+                              namelen,
180+                              encoding,
181+                              &error).ToLocal (&filename)) {
182+       *err_out = error;
183+       return  MaybeLocal<Array>();
184+     }
185+ 
186+     entries[j++] = filename;
187+     entries[j++] = Integer::New (env->isolate (), ents[i].type );
188+   }
189+ 
190+   return  Array::New (env->isolate (), entries.out (), j);
191+ }
192+ 
193+ static  void  AfterDirRead (uv_fs_t * req) {
164194  FSReqBase* req_wrap = FSReqBase::from_req (req);
165195  FSReqAfterScope after (req_wrap, req);
166196
@@ -170,7 +200,6 @@ void AfterDirReadSingle(uv_fs_t* req) {
170200
171201  Environment* env = req_wrap->env ();
172202  Isolate* isolate = env->isolate ();
173-   Local<Value> error;
174203
175204  if  (req->result  == 0 ) {
176205    //  Done
@@ -182,26 +211,17 @@ void AfterDirReadSingle(uv_fs_t* req) {
182211  uv_dir_t * dir = static_cast <uv_dir_t *>(req->ptr );
183212  req->ptr  = nullptr ;
184213
185-   //  Single entries are returned without an array wrapper
186-   const  uv_dirent_t & ent = dir->dirents [0 ];
187- 
188-   MaybeLocal<Value> filename =
189-     StringBytes::Encode (isolate,
190-                         ent.name ,
191-                         req_wrap->encoding (),
192-                         &error);
193-   if  (filename.IsEmpty ())
214+   Local<Value> error;
215+   Local<Array> js_array;
216+   if  (!DirentListToArray (env,
217+                          dir->dirents ,
218+                          req->result ,
219+                          req_wrap->encoding (),
220+                          &error).ToLocal (&js_array)) {
194221    return  req_wrap->Reject (error);
222+   }
195223
196- 
197-   Local<Array> result = Array::New (isolate, 2 );
198-   result->Set (env->context (),
199-               0 ,
200-               filename.ToLocalChecked ()).FromJust ();
201-   result->Set (env->context (),
202-               1 ,
203-               Integer::New (isolate, ent.type )).FromJust ();
204-   req_wrap->Resolve (result);
224+   req_wrap->Resolve (js_array);
205225}
206226
207227
@@ -217,10 +237,10 @@ void DirHandle::Read(const FunctionCallbackInfo<Value>& args) {
217237  DirHandle* dir;
218238  ASSIGN_OR_RETURN_UNWRAP (&dir, args.Holder ());
219239
220-   FSReqBase* req_wrap_async = static_cast <FSReqBase*>( GetReqWrap (env, args[1 ]) );
240+   FSReqBase* req_wrap_async = GetReqWrap (env, args[1 ]);
221241  if  (req_wrap_async != nullptr ) {  //  dir.read(encoding, req)
222242    AsyncCall (env, req_wrap_async, args, " readdir" 
223-               AfterDirReadSingle , uv_fs_readdir, dir->dir ());
243+               AfterDirRead , uv_fs_readdir, dir->dir ());
224244  } else  {  //  dir.read(encoding, undefined, ctx)
225245    CHECK_EQ (argc, 3 );
226246    FSReqWrapSync req_wrap_sync;
@@ -240,28 +260,20 @@ void DirHandle::Read(const FunctionCallbackInfo<Value>& args) {
240260    }
241261
242262    CHECK_GE (req_wrap_sync.req .result , 0 );
243-     const  uv_dirent_t & ent = dir->dir ()->dirents [0 ];
244263
245264    Local<Value> error;
246-     MaybeLocal<Value> filename = 
247-        StringBytes::Encode (isolate ,
248-                           ent. name ,
249-                           encoding ,
250-                           &error); 
251-     if  (filename. IsEmpty ( )) {
265+     Local<Array> js_array; 
266+     if  (! DirentListToArray (env ,
267+                            dir-> dir ()-> dirents ,
268+                            req_wrap_sync. req . result ,
269+                            encoding, 
270+                            &error). ToLocal (&js_array )) {
252271      Local<Object> ctx = args[2 ].As <Object>();
253-       ctx->Set (env->context (), env->error_string (), error). FromJust ( );
272+       USE ( ctx->Set (env->context (), env->error_string (), error));
254273      return ;
255274    }
256275
257-     Local<Array> result = Array::New (isolate, 2 );
258-     result->Set (env->context (),
259-                 0 ,
260-                 filename.ToLocalChecked ()).FromJust ();
261-     result->Set (env->context (),
262-                 1 ,
263-                 Integer::New (isolate, ent.type )).FromJust ();
264-     args.GetReturnValue ().Set (result);
276+     args.GetReturnValue ().Set (js_array);
265277  }
266278}
267279
0 commit comments