9
9
#if BX_CRT_NONE
10
10
# include " crt0.h"
11
11
#else
12
+ # include < dirent.h>
12
13
# include < stdio.h>
13
14
# include < sys/stat.h>
14
15
#endif // !BX_CRT_NONE
@@ -553,14 +554,168 @@ namespace bx
553
554
return impl->write (_data, _size, _err);
554
555
}
555
556
556
- bool stat (const FilePath& _filePath, FileInfo& _outFileInfo)
557
+ class DirectoryReaderImpl : public ReaderOpenI , public CloserI , public ReaderI
558
+ {
559
+ public:
560
+ // /
561
+ DirectoryReaderImpl ();
562
+
563
+ // /
564
+ virtual ~DirectoryReaderImpl ();
565
+
566
+ // /
567
+ virtual bool open (const FilePath& _filePath, Error* _err) override ;
568
+
569
+ // /
570
+ virtual void close () override ;
571
+
572
+ // /
573
+ virtual int32_t read (void * _data, int32_t _size, Error* _err) override ;
574
+
575
+ private:
576
+ FileInfo m_cache;
577
+ DIR* m_dir;
578
+ int32_t m_pos;
579
+ };
580
+
581
+ DirectoryReaderImpl::DirectoryReaderImpl ()
582
+ : m_dir(NULL )
583
+ , m_pos(0 )
584
+ {
585
+ }
586
+
587
+ DirectoryReaderImpl::~DirectoryReaderImpl ()
588
+ {
589
+ close ();
590
+ }
591
+
592
+ static bool fetch (FileInfo& _out, DIR* _dir)
593
+ {
594
+ for (;;)
595
+ {
596
+ const dirent* item = readdir (_dir);
597
+
598
+ if (NULL == item)
599
+ {
600
+ return false ;
601
+ }
602
+
603
+ if (0 != (item->d_type & DT_DIR) )
604
+ {
605
+ _out.type = FileType::Dir;
606
+ _out.size = UINT64_MAX;
607
+ _out.filePath .set (item->d_name );
608
+ return true ;
609
+ }
610
+
611
+ if (0 != (item->d_type & DT_REG) )
612
+ {
613
+ _out.type = FileType::File;
614
+ _out.size = UINT64_MAX;
615
+ _out.filePath .set (item->d_name );
616
+ return true ;
617
+ }
618
+ }
619
+
620
+ return false ;
621
+ }
622
+
623
+ bool DirectoryReaderImpl::open (const FilePath& _filePath, Error* _err)
624
+ {
625
+ BX_CHECK (NULL != _err, " Reader/Writer interface calling functions must handle errors." );
626
+
627
+ m_dir = opendir (_filePath.get () );
628
+
629
+ if (NULL == m_dir)
630
+ {
631
+ BX_ERROR_SET (_err, BX_ERROR_READERWRITER_OPEN, " DirectoryReader: Failed to open directory." );
632
+ return false ;
633
+ }
634
+
635
+ m_pos = 0 ;
636
+
637
+ return true ;
638
+ }
639
+
640
+ void DirectoryReaderImpl::close ()
641
+ {
642
+ if (NULL != m_dir)
643
+ {
644
+ closedir (m_dir);
645
+ m_dir = NULL ;
646
+ }
647
+ }
648
+
649
+ int32_t DirectoryReaderImpl::read (void * _data, int32_t _size, Error* _err)
650
+ {
651
+ BX_CHECK (NULL != _err, " Reader/Writer interface calling functions must handle errors." );
652
+
653
+ int32_t total = 0 ;
654
+
655
+ uint8_t * out = (uint8_t *)_data;
656
+
657
+ for (; 0 < _size;)
658
+ {
659
+ if (0 == m_pos)
660
+ {
661
+ if (!fetch (m_cache, m_dir) )
662
+ {
663
+ BX_ERROR_SET (_err, BX_ERROR_READERWRITER_EOF, " DirectoryReader: EOF." );
664
+ return total;
665
+ }
666
+ }
667
+
668
+ const uint8_t * src = (const uint8_t *)&m_cache;
669
+ int32_t size = min<int32_t >(_size, sizeof (m_cache)-m_pos);
670
+ memCopy (&out[total], &src[m_pos], size);
671
+ total += size;
672
+ _size -= size;
673
+
674
+ m_pos += size;
675
+ m_pos %= sizeof (m_cache);
676
+ }
677
+
678
+ return total;
679
+ }
680
+
681
+ DirectoryReader::DirectoryReader ()
682
+ {
683
+ BX_STATIC_ASSERT (sizeof (DirectoryReaderImpl) <= sizeof (m_internal) );
684
+ BX_PLACEMENT_NEW (m_internal, DirectoryReaderImpl);
685
+ }
686
+
687
+ DirectoryReader::~DirectoryReader ()
688
+ {
689
+ DirectoryReaderImpl* impl = reinterpret_cast <DirectoryReaderImpl*>(m_internal);
690
+ impl->~DirectoryReaderImpl ();
691
+ }
692
+
693
+ bool DirectoryReader::open (const FilePath& _filePath, Error* _err)
694
+ {
695
+ DirectoryReaderImpl* impl = reinterpret_cast <DirectoryReaderImpl*>(m_internal);
696
+ return impl->open (_filePath, _err);
697
+ }
698
+
699
+ void DirectoryReader::close ()
700
+ {
701
+ DirectoryReaderImpl* impl = reinterpret_cast <DirectoryReaderImpl*>(m_internal);
702
+ impl->close ();
703
+ }
704
+
705
+ int32_t DirectoryReader::read (void * _data, int32_t _size, Error* _err)
706
+ {
707
+ DirectoryReaderImpl* impl = reinterpret_cast <DirectoryReaderImpl*>(m_internal);
708
+ return impl->read (_data, _size, _err);
709
+ }
710
+
711
+ bool stat (FileInfo& _outFileInfo, const FilePath& _filePath)
557
712
{
558
713
#if BX_CRT_NONE
559
714
BX_UNUSED (_filePath, _outFileInfo);
560
715
return false ;
561
716
#else
562
- _outFileInfo.m_size = 0 ;
563
- _outFileInfo.m_type = FileInfo ::Count;
717
+ _outFileInfo.size = 0 ;
718
+ _outFileInfo.type = FileType ::Count;
564
719
565
720
# if BX_COMPILER_MSVC
566
721
struct ::_stat64 st;
@@ -573,11 +728,11 @@ namespace bx
573
728
574
729
if (0 != (st.st_mode & _S_IFREG) )
575
730
{
576
- _outFileInfo.m_type = FileInfo::Regular ;
731
+ _outFileInfo.type = FileType::File ;
577
732
}
578
733
else if (0 != (st.st_mode & _S_IFDIR) )
579
734
{
580
- _outFileInfo.m_type = FileInfo::Directory ;
735
+ _outFileInfo.type = FileType::Dir ;
581
736
}
582
737
# else
583
738
struct ::stat st;
@@ -589,15 +744,15 @@ namespace bx
589
744
590
745
if (0 != (st.st_mode & S_IFREG) )
591
746
{
592
- _outFileInfo.m_type = FileInfo::Regular ;
747
+ _outFileInfo.type = FileType::File ;
593
748
}
594
749
else if (0 != (st.st_mode & S_IFDIR) )
595
750
{
596
- _outFileInfo.m_type = FileInfo::Directory ;
751
+ _outFileInfo.type = FileType::Dir ;
597
752
}
598
753
# endif // BX_COMPILER_MSVC
599
754
600
- _outFileInfo.m_size = st.st_size ;
755
+ _outFileInfo.size = st.st_size ;
601
756
602
757
return true ;
603
758
#endif // BX_CRT_NONE
0 commit comments