1 #pragma once 2 3 #include <cstddef> 4 #include <cassert> 5 6 #include "qcommon/q_platform.h" 7 #include "qcommon/safe/gsl.h" 8 9 /** 10 @file RAII C++ bindings for filesystem operations 11 */ 12 13 namespace FS 14 { 15 class FileBuffer 16 { 17 friend FileBuffer ReadFile( gsl::czstring ); 18 // called by ReadFile() 19 FileBuffer( void* buffer, const long size ) NOEXCEPT; 20 public: 21 FileBuffer() NOEXCEPT = default; 22 ~FileBuffer() NOEXCEPT; 23 // noncopyable 24 FileBuffer( const FileBuffer& ) = delete; 25 FileBuffer& operator=( const FileBuffer& ) = delete; 26 // movable 27 FileBuffer( FileBuffer&& rhs ) NOEXCEPT; 28 FileBuffer& operator=( FileBuffer&& rhs ) NOEXCEPT; 29 30 /// nullptr if no such file begin()31 const char* begin() const NOEXCEPT 32 { 33 return static_cast< const char* >( _buffer ); 34 } end()35 const char* end() const NOEXCEPT 36 { 37 return static_cast< const char* >( _buffer ) + _size; 38 } size()39 long size() const NOEXCEPT 40 { 41 return _size; 42 } valid()43 bool valid() const NOEXCEPT 44 { 45 return _buffer != nullptr; 46 } view()47 gsl::cstring_view view() const NOEXCEPT 48 { 49 return{ begin(), end() }; 50 } 51 52 private: 53 // TODO: ought to be const; would have to fix FS_ReadFile though. 54 void* _buffer = nullptr; 55 long _size = 0; 56 }; 57 58 FileBuffer ReadFile( gsl::czstring path ); 59 60 // FileList only available in Client; Library exclusively uses FS_GetFileList(), which by supplying a buffer avoids dynamic allocations. 61 // TODO: investigate making FS_ListFiles available in Library Code? 62 #if !defined( SP_GAME ) 63 class FileList 64 { 65 friend FileList ListFiles( const char*, const char* ); 66 // called by ListFiles() 67 FileList( char** files, int numFiles ) NOEXCEPT; 68 public: 69 FileList() NOEXCEPT = default; 70 ~FileList() NOEXCEPT; 71 // noncopyable 72 FileList( const FileList& ) = delete; 73 FileList& operator=( const FileList& ) = delete; 74 // movable 75 FileList( FileList&& rhs ) NOEXCEPT; 76 FileList& operator=( FileList&& rhs ) NOEXCEPT; 77 begin()78 const char *const *begin() const NOEXCEPT 79 { 80 return _begin; 81 } end()82 const char *const *end() const NOEXCEPT 83 { 84 return _end; 85 } size()86 std::size_t size() const NOEXCEPT 87 { 88 return static_cast< std::size_t >( _end - begin() ); 89 } 90 91 private: 92 // TODO: this should really be const; it's a matter of making FS_ListFiles' result const. 93 char** _begin = nullptr; 94 const char* const* _end = nullptr; 95 }; 96 97 /** 98 @brief Returns a list of the files in a directory. 99 100 The returned files will not include any directories or `/`. 101 102 @note ERR_FATAL if called before file system initialization 103 @todo Which is it? Returns no directories at all, or returns them when looking for extension "/"? 104 @param directory should not have either a leading or trailing / 105 @param extension if "/", only subdirectories will be returned 106 */ 107 FileList ListFiles( const char* directory, const char* extension ); 108 #endif 109 } 110