@@ -59,8 +59,8 @@ DirHandle::DirHandle(Environment* env, Local<Object> obj, uv_dir_t* dir)
59
59
dir_ (dir) {
60
60
MakeWeak ();
61
61
62
- dir_->nentries = 1 ;
63
- dir_->dirents = &dirent_ ;
62
+ dir_->nentries = arraysize (dirents_) ;
63
+ dir_->dirents = dirents_ ;
64
64
}
65
65
66
66
DirHandle* DirHandle::New (Environment* env, uv_dir_t * dir) {
@@ -160,7 +160,37 @@ void DirHandle::Close(const FunctionCallbackInfo<Value>& args) {
160
160
}
161
161
}
162
162
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) {
164
194
FSReqBase* req_wrap = FSReqBase::from_req (req);
165
195
FSReqAfterScope after (req_wrap, req);
166
196
@@ -170,7 +200,6 @@ void AfterDirReadSingle(uv_fs_t* req) {
170
200
171
201
Environment* env = req_wrap->env ();
172
202
Isolate* isolate = env->isolate ();
173
- Local<Value> error;
174
203
175
204
if (req->result == 0 ) {
176
205
// Done
@@ -182,26 +211,17 @@ void AfterDirReadSingle(uv_fs_t* req) {
182
211
uv_dir_t * dir = static_cast <uv_dir_t *>(req->ptr );
183
212
req->ptr = nullptr ;
184
213
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)) {
194
221
return req_wrap->Reject (error);
222
+ }
195
223
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);
205
225
}
206
226
207
227
@@ -217,10 +237,10 @@ void DirHandle::Read(const FunctionCallbackInfo<Value>& args) {
217
237
DirHandle* dir;
218
238
ASSIGN_OR_RETURN_UNWRAP (&dir, args.Holder ());
219
239
220
- FSReqBase* req_wrap_async = static_cast <FSReqBase*>( GetReqWrap (env, args[1 ]) );
240
+ FSReqBase* req_wrap_async = GetReqWrap (env, args[1 ]);
221
241
if (req_wrap_async != nullptr ) { // dir.read(encoding, req)
222
242
AsyncCall (env, req_wrap_async, args, " readdir" , encoding,
223
- AfterDirReadSingle , uv_fs_readdir, dir->dir ());
243
+ AfterDirRead , uv_fs_readdir, dir->dir ());
224
244
} else { // dir.read(encoding, undefined, ctx)
225
245
CHECK_EQ (argc, 3 );
226
246
FSReqWrapSync req_wrap_sync;
@@ -240,28 +260,20 @@ void DirHandle::Read(const FunctionCallbackInfo<Value>& args) {
240
260
}
241
261
242
262
CHECK_GE (req_wrap_sync.req .result , 0 );
243
- const uv_dirent_t & ent = dir->dir ()->dirents [0 ];
244
263
245
264
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 )) {
252
271
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));
254
273
return ;
255
274
}
256
275
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);
265
277
}
266
278
}
267
279
0 commit comments