ResourceFilesystem.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Resource/Common.h>
  7. #include <AnKi/Util/String.h>
  8. #include <AnKi/Util/StringList.h>
  9. #include <AnKi/Util/File.h>
  10. #include <AnKi/Util/Ptr.h>
  11. namespace anki {
  12. // Forward
  13. class ConfigSet;
  14. /// @addtogroup resource
  15. /// @{
  16. /// Resource filesystem file. An interface that abstracts the resource file.
  17. class ResourceFile
  18. {
  19. public:
  20. ResourceFile(GenericMemoryPoolAllocator<U8> alloc)
  21. : m_alloc(alloc)
  22. {
  23. }
  24. ResourceFile(const ResourceFile&) = delete; // Non-copyable
  25. virtual ~ResourceFile()
  26. {
  27. }
  28. ResourceFile& operator=(const ResourceFile&) = delete; // Non-copyable
  29. /// Read data from the file
  30. virtual ANKI_USE_RESULT Error read(void* buff, PtrSize size) = 0;
  31. /// Read all the contents of a text file. If the file is not rewined it will probably fail
  32. virtual ANKI_USE_RESULT Error readAllText(StringAuto& out) = 0;
  33. /// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's
  34. virtual ANKI_USE_RESULT Error readU32(U32& u) = 0;
  35. /// Read 32bit float. Set the endianness if the file's endianness is different from the machine's
  36. virtual ANKI_USE_RESULT Error readF32(F32& f) = 0;
  37. /// Set the position indicator to a new position
  38. /// @param offset Number of bytes to offset from origin
  39. /// @param origin Position used as reference for the offset
  40. virtual ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) = 0;
  41. /// Get the size of the file.
  42. virtual PtrSize getSize() const = 0;
  43. Atomic<I32>& getRefcount()
  44. {
  45. return m_refcount;
  46. }
  47. GenericMemoryPoolAllocator<U8> getAllocator() const
  48. {
  49. return m_alloc;
  50. }
  51. private:
  52. GenericMemoryPoolAllocator<U8> m_alloc;
  53. Atomic<I32> m_refcount = {0};
  54. };
  55. /// Resource file smart pointer.
  56. using ResourceFilePtr = IntrusivePtr<ResourceFile>;
  57. /// Resource filesystem.
  58. class ResourceFilesystem
  59. {
  60. public:
  61. ResourceFilesystem(GenericMemoryPoolAllocator<U8> alloc)
  62. : m_alloc(alloc)
  63. {
  64. }
  65. ResourceFilesystem(const ResourceFilesystem&) = delete; // Non-copyable
  66. ~ResourceFilesystem();
  67. ResourceFilesystem& operator=(const ResourceFilesystem&) = delete; // Non-copyable
  68. ANKI_USE_RESULT Error init(const ConfigSet& config, const CString& cacheDir);
  69. /// Search the path list to find the file. Then open the file for reading. It's thread-safe.
  70. ANKI_USE_RESULT Error openFile(const ResourceFilename& filename, ResourceFilePtr& file);
  71. /// Iterate all the filenames from all paths provided.
  72. template<typename TFunc>
  73. ANKI_USE_RESULT Error iterateAllFilenames(TFunc func) const
  74. {
  75. for(const Path& path : m_paths)
  76. {
  77. for(const String& fname : path.m_files)
  78. {
  79. ANKI_CHECK(func(fname.toCString()));
  80. }
  81. }
  82. return Error::NONE;
  83. }
  84. #if !ANKI_TESTS
  85. private:
  86. #endif
  87. class Path
  88. {
  89. public:
  90. StringList m_files; ///< Files inside the directory.
  91. String m_path; ///< A directory or an archive.
  92. Bool m_isArchive = false;
  93. Bool m_isCache = false;
  94. Bool m_isSpecial = false;
  95. Path() = default;
  96. Path(const Path&) = delete; // Non-copyable
  97. Path(Path&& b)
  98. {
  99. *this = std::move(b);
  100. }
  101. Path& operator=(const Path&) = delete; // Non-copyable
  102. Path& operator=(Path&& b)
  103. {
  104. m_files = std::move(b.m_files);
  105. m_path = std::move(b.m_path);
  106. m_isArchive = b.m_isArchive;
  107. m_isCache = b.m_isCache;
  108. m_isSpecial = b.m_isSpecial;
  109. return *this;
  110. }
  111. };
  112. GenericMemoryPoolAllocator<U8> m_alloc;
  113. List<Path> m_paths;
  114. String m_cacheDir;
  115. /// Add a filesystem path or an archive. The path is read-only.
  116. ANKI_USE_RESULT Error addNewPath(const CString& path, const StringListAuto& excludedStrings, Bool special = false);
  117. void addCachePath(const CString& path);
  118. };
  119. /// @}
  120. } // end namespace anki