@@ -551,51 +551,139 @@ void AfterScanDir(uv_fs_t* req) {
551
551
FSReqBase* req_wrap = FSReqBase::from_req (req);
552
552
FSReqAfterScope after (req_wrap, req);
553
553
554
- if (after.Proceed ()) {
555
- Environment* env = req_wrap->env ();
556
- Local<Value> error;
557
- int r;
558
- Local<Array> names = Array::New (env->isolate (), 0 );
559
- Local<Function> fn = env->push_values_to_array_function ();
560
- Local<Value> name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
561
- size_t name_idx = 0 ;
554
+ if (!after.Proceed ()) {
555
+ return ;
556
+ }
557
+ Environment* env = req_wrap->env ();
558
+ Local<Value> error;
559
+ int r;
560
+ Local<Array> names = Array::New (env->isolate (), 0 );
561
+ Local<Function> fn = env->push_values_to_array_function ();
562
+ Local<Value> name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
563
+ size_t name_idx = 0 ;
564
+
565
+ for (int i = 0 ; ; i++) {
566
+ uv_dirent_t ent;
567
+
568
+ r = uv_fs_scandir_next (req, &ent);
569
+ if (r == UV_EOF)
570
+ break ;
571
+ if (r != 0 ) {
572
+ return req_wrap->Reject (
573
+ UVException (r, nullptr , req_wrap->syscall (),
574
+ static_cast <const char *>(req->path )));
575
+ }
562
576
563
- for (int i = 0 ; ; i++) {
564
- uv_dirent_t ent;
577
+ MaybeLocal<Value> filename =
578
+ StringBytes::Encode (env->isolate (),
579
+ ent.name ,
580
+ req_wrap->encoding (),
581
+ &error);
582
+ if (filename.IsEmpty ())
583
+ return req_wrap->Reject (error);
565
584
566
- r = uv_fs_scandir_next (req, &ent );
567
- if (r == UV_EOF)
568
- break ;
569
- if (r != 0 ) {
570
- return req_wrap-> Reject (
571
- UVException (r, nullptr , req_wrap-> syscall (),
572
- static_cast < const char *>(req-> path ))) ;
585
+ name_argv[name_idx++] = filename. ToLocalChecked ( );
586
+
587
+ if (name_idx >= arraysize (name_argv)) {
588
+ MaybeLocal<Value> ret = fn-> Call (env-> context (), names, name_idx,
589
+ name_argv);
590
+ if (ret. IsEmpty ()) {
591
+ return ;
573
592
}
593
+ name_idx = 0 ;
594
+ }
595
+ }
574
596
575
- MaybeLocal<Value> filename =
576
- StringBytes::Encode (env->isolate (),
577
- ent.name ,
578
- req_wrap->encoding (),
579
- &error);
580
- if (filename.IsEmpty ())
581
- return req_wrap->Reject (error);
597
+ if (name_idx > 0 ) {
598
+ fn->Call (env->context (), names, name_idx, name_argv)
599
+ .ToLocalChecked ();
600
+ }
582
601
583
- name_argv[name_idx++] = filename.ToLocalChecked ();
602
+ req_wrap->Resolve (names);
603
+ }
584
604
585
- if (name_idx >= arraysize (name_argv)) {
586
- fn->Call (env->context (), names, name_idx, name_argv)
587
- .ToLocalChecked ();
588
- name_idx = 0 ;
605
+ void AfterScanDirWithTypes (uv_fs_t * req) {
606
+ FSReqBase* req_wrap = FSReqBase::from_req (req);
607
+ FSReqAfterScope after (req_wrap, req);
608
+
609
+ if (!after.Proceed ()) {
610
+ return ;
611
+ }
612
+
613
+ Environment* env = req_wrap->env ();
614
+ Local<Value> error;
615
+ int r;
616
+ Local<Array> names = Array::New (env->isolate (), 0 );
617
+ Local<Function> fn = env->push_values_to_array_function ();
618
+ Local<Value> name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
619
+ size_t name_idx = 0 ;
620
+ Local<Value> types = Array::New (env->isolate (), 0 );
621
+ Local<Value> type_argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
622
+ size_t type_idx = 0 ;
623
+
624
+ for (int i = 0 ; ; i++) {
625
+ uv_dirent_t ent;
626
+
627
+ r = uv_fs_scandir_next (req, &ent);
628
+ if (r == UV_EOF)
629
+ break ;
630
+ if (r != 0 ) {
631
+ return req_wrap->Reject (
632
+ UVException (r, nullptr , req_wrap->syscall (),
633
+ static_cast <const char *>(req->path )));
634
+ }
635
+
636
+ MaybeLocal<Value> filename =
637
+ StringBytes::Encode (env->isolate (),
638
+ ent.name ,
639
+ req_wrap->encoding (),
640
+ &error);
641
+ if (filename.IsEmpty ())
642
+ return req_wrap->Reject (error);
643
+
644
+ name_argv[name_idx++] = filename.ToLocalChecked ();
645
+
646
+ if (name_idx >= arraysize (name_argv)) {
647
+ MaybeLocal<Value> ret = fn->Call (env->context (), names, name_idx,
648
+ name_argv);
649
+ if (ret.IsEmpty ()) {
650
+ return ;
589
651
}
652
+ name_idx = 0 ;
590
653
}
591
654
592
- if (name_idx > 0 ) {
593
- fn->Call (env->context (), names, name_idx, name_argv)
594
- .ToLocalChecked ();
655
+ type_argv[type_idx++] = Integer::New (env->isolate (), ent.type );
656
+
657
+ if (type_idx >= arraysize (type_argv)) {
658
+ MaybeLocal<Value> ret = fn->Call (env->context (), types, type_idx,
659
+ type_argv);
660
+ if (ret.IsEmpty ()) {
661
+ return ;
662
+ }
663
+ type_idx = 0 ;
664
+ }
665
+ }
666
+
667
+ if (name_idx > 0 ) {
668
+ MaybeLocal<Value> ret = fn->Call (env->context (), names, name_idx,
669
+ name_argv);
670
+ if (ret.IsEmpty ()) {
671
+ return ;
595
672
}
673
+ }
596
674
597
- req_wrap->Resolve (names);
675
+ if (type_idx > 0 ) {
676
+ MaybeLocal<Value> ret = fn->Call (env->context (), types, type_idx,
677
+ type_argv);
678
+ if (ret.IsEmpty ()) {
679
+ return ;
680
+ }
598
681
}
682
+
683
+ Local<Array> result = Array::New (env->isolate (), 2 );
684
+ result->Set (0 , names);
685
+ result->Set (1 , types);
686
+ req_wrap->Resolve (result);
599
687
}
600
688
601
689
@@ -1228,15 +1316,22 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1228
1316
1229
1317
const enum encoding encoding = ParseEncoding (env->isolate (), args[1 ], UTF8);
1230
1318
1231
- FSReqBase* req_wrap_async = GetReqWrap (env, args[2 ]);
1232
- if (req_wrap_async != nullptr ) { // readdir(path, encoding, req)
1233
- AsyncCall (env, req_wrap_async, args, " scandir" , encoding, AfterScanDir,
1234
- uv_fs_scandir, *path, 0 /* flags*/ );
1235
- } else { // readdir(path, encoding, undefined, ctx)
1236
- CHECK_EQ (argc, 4 );
1319
+ bool with_types = args[2 ]->BooleanValue ();
1320
+
1321
+ FSReqBase* req_wrap_async = GetReqWrap (env, args[3 ]);
1322
+ if (req_wrap_async != nullptr ) { // readdir(path, encoding, withTypes, req)
1323
+ if (with_types) {
1324
+ AsyncCall (env, req_wrap_async, args, " scandir" , encoding,
1325
+ AfterScanDirWithTypes, uv_fs_scandir, *path, 0 /* flags*/ );
1326
+ } else {
1327
+ AsyncCall (env, req_wrap_async, args, " scandir" , encoding,
1328
+ AfterScanDir, uv_fs_scandir, *path, 0 /* flags*/ );
1329
+ }
1330
+ } else { // readdir(path, encoding, withTypes, undefined, ctx)
1331
+ CHECK_EQ (argc, 5 );
1237
1332
FSReqWrapSync req_wrap_sync;
1238
1333
FS_SYNC_TRACE_BEGIN (readdir);
1239
- int err = SyncCall (env, args[3 ], &req_wrap_sync, " scandir" ,
1334
+ int err = SyncCall (env, args[4 ], &req_wrap_sync, " scandir" ,
1240
1335
uv_fs_scandir, *path, 0 /* flags*/ );
1241
1336
FS_SYNC_TRACE_END (readdir);
1242
1337
if (err < 0 ) {
@@ -1250,14 +1345,22 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1250
1345
Local<Value> name_v[NODE_PUSH_VAL_TO_ARRAY_MAX];
1251
1346
size_t name_idx = 0 ;
1252
1347
1348
+ Local<Value> types;
1349
+ Local<Value> type_v[NODE_PUSH_VAL_TO_ARRAY_MAX];
1350
+ size_t type_idx;
1351
+ if (with_types) {
1352
+ types = Array::New (env->isolate (), 0 );
1353
+ type_idx = 0 ;
1354
+ }
1355
+
1253
1356
for (int i = 0 ; ; i++) {
1254
1357
uv_dirent_t ent;
1255
1358
1256
1359
r = uv_fs_scandir_next (&(req_wrap_sync.req ), &ent);
1257
1360
if (r == UV_EOF)
1258
1361
break ;
1259
1362
if (r != 0 ) {
1260
- Local<Object> ctx = args[3 ].As <Object>();
1363
+ Local<Object> ctx = args[4 ].As <Object>();
1261
1364
ctx->Set (env->context (), env->errno_string (),
1262
1365
Integer::New (env->isolate (), r)).FromJust ();
1263
1366
ctx->Set (env->context (), env->syscall_string (),
@@ -1270,8 +1373,9 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1270
1373
ent.name ,
1271
1374
encoding,
1272
1375
&error);
1376
+
1273
1377
if (filename.IsEmpty ()) {
1274
- Local<Object> ctx = args[3 ].As <Object>();
1378
+ Local<Object> ctx = args[4 ].As <Object>();
1275
1379
ctx->Set (env->context (), env->error_string (), error).FromJust ();
1276
1380
return ;
1277
1381
}
@@ -1286,6 +1390,19 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1286
1390
}
1287
1391
name_idx = 0 ;
1288
1392
}
1393
+
1394
+ if (with_types) {
1395
+ type_v[type_idx++] = Integer::New (env->isolate (), ent.type );
1396
+
1397
+ if (type_idx >= arraysize (type_v)) {
1398
+ MaybeLocal<Value> ret = fn->Call (env->context (), types, type_idx,
1399
+ type_v);
1400
+ if (ret.IsEmpty ()) {
1401
+ return ;
1402
+ }
1403
+ type_idx = 0 ;
1404
+ }
1405
+ }
1289
1406
}
1290
1407
1291
1408
if (name_idx > 0 ) {
@@ -1295,7 +1412,21 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1295
1412
}
1296
1413
}
1297
1414
1298
- args.GetReturnValue ().Set (names);
1415
+ if (with_types && type_idx > 0 ) {
1416
+ MaybeLocal<Value> ret = fn->Call (env->context (), types, type_idx, type_v);
1417
+ if (ret.IsEmpty ()) {
1418
+ return ;
1419
+ }
1420
+ }
1421
+
1422
+ if (with_types) {
1423
+ Local<Array> result = Array::New (env->isolate (), 2 );
1424
+ result->Set (0 , names);
1425
+ result->Set (1 , types);
1426
+ args.GetReturnValue ().Set (result);
1427
+ } else {
1428
+ args.GetReturnValue ().Set (names);
1429
+ }
1299
1430
}
1300
1431
}
1301
1432
0 commit comments