File.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright (C) 2009-present, 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/Util/String.h>
  7. #include <AnKi/Util/Enum.h>
  8. #include <cstdio>
  9. namespace anki {
  10. /// @addtogroup util_file
  11. /// @{
  12. /// Open mode
  13. /// @memberof File
  14. enum class FileOpenFlag : U8
  15. {
  16. kNone = 0,
  17. kRead = 1 << 0,
  18. kWrite = 1 << 1,
  19. kAppend = kWrite | (1 << 3),
  20. kBinary = 1 << 4,
  21. kLittleEndian = 1 << 5, ///< The default
  22. kBigEndian = 1 << 6,
  23. kSpecial = 1 << 7, ///< Android package file.
  24. };
  25. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(FileOpenFlag)
  26. /// Passed to seek function
  27. /// @memberof File
  28. enum class FileSeekOrigin
  29. {
  30. kBeginning = SEEK_SET,
  31. kCurrent = SEEK_CUR,
  32. kEnd = SEEK_END
  33. };
  34. /// An abstraction over typical files and files in ziped archives. This class can read from regular C files, zip files
  35. /// and on Android from the packed asset files.
  36. /// To identify the file:
  37. /// - If the filename starts with '$' it will try to load a system specific file. For Android this is a file in the .apk
  38. /// - If the above are false then try to load a regular C file
  39. class File
  40. {
  41. public:
  42. /// Default constructor
  43. File() = default;
  44. File(const File&) = delete; // Non-copyable
  45. File& operator=(const File&) = delete; // Non-copyable
  46. /// Move
  47. File(File&& b)
  48. {
  49. *this = std::move(b);
  50. }
  51. /// Closes the file if it's open
  52. ~File();
  53. /// Move
  54. File& operator=(File&& b);
  55. /// Open a file.
  56. /// @param[in] filename The file to open
  57. /// @param[in] openMask The open flags. It's a combination of FileOpenFlag enum
  58. Error open(const CString& filename, FileOpenFlag openMask);
  59. /// Return true if the file is oppen
  60. Bool isOpen() const
  61. {
  62. return m_file != nullptr;
  63. }
  64. /// Close the file
  65. void close();
  66. /// Flush pending operations
  67. Error flush();
  68. /// Read data from the file
  69. Error read(void* buff, PtrSize size);
  70. /// Read all the contents of a text file. If the file is not rewined it will probably fail.
  71. template<typename TMemPool>
  72. Error readAllText(BaseString<TMemPool>& out)
  73. {
  74. Error err = Error::kNone;
  75. PtrSize size = getSize();
  76. if(size != 0)
  77. {
  78. out = BaseString<TMemPool>('?', size, out.getMemoryPool());
  79. err = read(&out[0], size);
  80. }
  81. else
  82. {
  83. err = Error::kFunctionFailed;
  84. }
  85. return err;
  86. }
  87. /// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's.
  88. Error readU32(U32& u);
  89. /// Read 32bit float. Set the endianness if the file's endianness is different from the machine's.
  90. Error readF32(F32& f);
  91. /// Write data to the file
  92. Error write(const void* buff, PtrSize size);
  93. /// Write formated text
  94. ANKI_CHECK_FORMAT(1, 2)
  95. Error writeTextf(const Char* format, ...);
  96. /// Write plain text.
  97. Error writeText(CString text);
  98. /// Set the position indicator to a new position.
  99. /// @param offset Number of bytes to offset from origin
  100. /// @param origin Position used as reference for the offset
  101. Error seek(PtrSize offset, FileSeekOrigin origin);
  102. /// Return the position indicator inside the file.
  103. PtrSize tell();
  104. /// The the size of the file.
  105. PtrSize getSize() const
  106. {
  107. ANKI_ASSERT(!(m_flags & FileOpenFlag::kWrite));
  108. return m_size;
  109. }
  110. private:
  111. void* m_file = nullptr; ///< A native file type
  112. FileOpenFlag m_flags = FileOpenFlag::kNone; ///< All the flags. Set on open
  113. PtrSize m_size = 0;
  114. /// Get the current machine's endianness
  115. static FileOpenFlag getMachineEndianness();
  116. /// Open a C file
  117. Error openCFile(const CString& filename, FileOpenFlag flags);
  118. #if ANKI_OS_ANDROID
  119. /// Open an Android file
  120. Error openAndroidFile(const CString& filename, FileOpenFlag flags);
  121. #endif
  122. void zero()
  123. {
  124. m_file = nullptr;
  125. m_flags = FileOpenFlag::kNone;
  126. m_size = 0;
  127. }
  128. };
  129. /// @}
  130. } // end namespace anki