File.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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/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. NONE = 0,
  17. READ = 1 << 0,
  18. WRITE = 1 << 1,
  19. APPEND = WRITE | (1 << 3),
  20. BINARY = 1 << 4,
  21. ENDIAN_LITTLE = 1 << 5, ///< The default
  22. ENDIAN_BIG = 1 << 6,
  23. SPECIAL = 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. BEGINNING = SEEK_SET,
  31. CURRENT = SEEK_CUR,
  32. END = 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. ANKI_USE_RESULT 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. ANKI_USE_RESULT Error flush();
  68. /// Read data from the file
  69. ANKI_USE_RESULT Error read(void* buff, PtrSize size);
  70. /// Read all the contents of a text file
  71. /// If the file is not rewined it will probably fail
  72. ANKI_USE_RESULT Error readAllText(GenericMemoryPoolAllocator<U8> alloc, String& out);
  73. /// Read all the contents of a text file. If the file is not rewined it will probably fail.
  74. ANKI_USE_RESULT Error readAllText(StringAuto& out);
  75. /// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's.
  76. ANKI_USE_RESULT Error readU32(U32& u);
  77. /// Read 32bit float. Set the endianness if the file's endianness is different from the machine's.
  78. ANKI_USE_RESULT Error readF32(F32& f);
  79. /// Write data to the file
  80. ANKI_USE_RESULT Error write(const void* buff, PtrSize size);
  81. /// Write formated text
  82. ANKI_USE_RESULT Error writeText(CString format, ...);
  83. /// Set the position indicator to a new position.
  84. /// @param offset Number of bytes to offset from origin
  85. /// @param origin Position used as reference for the offset
  86. ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin);
  87. /// Return the position indicator inside the file.
  88. PtrSize tell();
  89. /// The the size of the file.
  90. PtrSize getSize() const
  91. {
  92. ANKI_ASSERT(!(m_flags & FileOpenFlag::WRITE));
  93. return m_size;
  94. }
  95. private:
  96. void* m_file = nullptr; ///< A native file type
  97. FileOpenFlag m_flags = FileOpenFlag::NONE; ///< All the flags. Set on open
  98. PtrSize m_size = 0;
  99. /// Get the current machine's endianness
  100. static FileOpenFlag getMachineEndianness();
  101. /// Open a C file
  102. ANKI_USE_RESULT Error openCFile(const CString& filename, FileOpenFlag flags);
  103. #if ANKI_OS_ANDROID
  104. /// Open an Android file
  105. ANKI_USE_RESULT Error openAndroidFile(const CString& filename, FileOpenFlag flags);
  106. #endif
  107. void zero()
  108. {
  109. m_file = nullptr;
  110. m_flags = FileOpenFlag::NONE;
  111. m_size = 0;
  112. }
  113. };
  114. /// @}
  115. } // end namespace anki