File.h 4.2 KB

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