File.h 3.9 KB

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