@@ -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" , encoding,
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