filesystem_apk.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright (c) 2012-2023 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "core/platform.h"
  6. #if CROWN_PLATFORM_ANDROID
  7. #include "core/containers/vector.inl"
  8. #include "core/filesystem/file.h"
  9. #include "core/filesystem/filesystem_apk.h"
  10. #include "core/memory/temp_allocator.inl"
  11. #include "core/os.h"
  12. #include "core/strings/dynamic_string.inl"
  13. namespace crown
  14. {
  15. struct FileApk : public File
  16. {
  17. AAssetManager *_asset_manager;
  18. AAsset *_asset;
  19. explicit FileApk(AAssetManager *asset_manager)
  20. : _asset_manager(asset_manager)
  21. , _asset(NULL)
  22. {
  23. }
  24. virtual ~FileApk()
  25. {
  26. close();
  27. }
  28. void open(const char *path, FileOpenMode::Enum mode) override
  29. {
  30. CE_UNUSED(mode);
  31. _asset = AAssetManager_open(_asset_manager, path, AASSET_MODE_RANDOM);
  32. }
  33. void close() override
  34. {
  35. if (_asset) {
  36. AAsset_close(_asset);
  37. _asset = NULL;
  38. }
  39. }
  40. bool is_open() override
  41. {
  42. return _asset != NULL;
  43. }
  44. u32 size() override
  45. {
  46. CE_ASSERT(is_open(), "File is not open");
  47. return AAsset_getLength(_asset);
  48. }
  49. u32 position() override
  50. {
  51. CE_ASSERT(is_open(), "File is not open");
  52. return u32(AAsset_getLength(_asset) - AAsset_getRemainingLength(_asset));
  53. }
  54. bool end_of_file() override
  55. {
  56. CE_ASSERT(is_open(), "File is not open");
  57. return AAsset_getRemainingLength(_asset) == 0;
  58. }
  59. void seek(u32 position) override
  60. {
  61. CE_ASSERT(is_open(), "File is not open");
  62. off_t seek_result = AAsset_seek(_asset, (off_t)position, SEEK_SET);
  63. CE_ASSERT(seek_result != (off_t)-1, "AAsset_seek: error");
  64. CE_UNUSED(seek_result);
  65. }
  66. void seek_to_end() override
  67. {
  68. CE_ASSERT(is_open(), "File is not open");
  69. off_t seek_result = AAsset_seek(_asset, 0, SEEK_END);
  70. CE_ASSERT(seek_result != (off_t)-1, "AAsset_seek: error");
  71. CE_UNUSED(seek_result);
  72. }
  73. void skip(u32 bytes) override
  74. {
  75. CE_ASSERT(is_open(), "File is not open");
  76. off_t seek_result = AAsset_seek(_asset, (off_t)bytes, SEEK_CUR);
  77. CE_ASSERT(seek_result != (off_t)-1, "AAsset_seek: error");
  78. CE_UNUSED(seek_result);
  79. }
  80. u32 read(void *data, u32 size) override
  81. {
  82. CE_ASSERT(is_open(), "File is not open");
  83. CE_ENSURE(NULL != data);
  84. return (u32)AAsset_read(_asset, data, size);
  85. }
  86. u32 write(const void *data, u32 size) override
  87. {
  88. CE_UNUSED_2(data, size);
  89. CE_ASSERT(is_open(), "File is not open");
  90. CE_FATAL("Apk files are read only!");
  91. return 0;
  92. }
  93. void flush() override
  94. {
  95. // Not needed
  96. }
  97. };
  98. FilesystemApk::FilesystemApk(Allocator &a, AAssetManager *asset_manager)
  99. : _allocator(&a)
  100. , _asset_manager(asset_manager)
  101. {
  102. }
  103. File *FilesystemApk::open(const char *path, FileOpenMode::Enum mode)
  104. {
  105. CE_ENSURE(NULL != path);
  106. CE_ASSERT(mode == FileOpenMode::READ, "Cannot open for writing in Android assets folder");
  107. FileApk *file = CE_NEW(*_allocator, FileApk)(_asset_manager);
  108. file->open(path, mode);
  109. return file;
  110. }
  111. void FilesystemApk::close(File &file)
  112. {
  113. CE_DELETE(*_allocator, &file);
  114. }
  115. Stat FilesystemApk::stat(const char *path)
  116. {
  117. CE_UNUSED(path);
  118. Stat info;
  119. info.file_type = Stat::REGULAR;
  120. info.size = 0;
  121. info.mtime = UINT64_MAX;
  122. return info;
  123. }
  124. bool FilesystemApk::exists(const char *path)
  125. {
  126. CE_UNUSED(path);
  127. return true;
  128. }
  129. bool FilesystemApk::is_directory(const char *path)
  130. {
  131. return true;
  132. }
  133. bool FilesystemApk::is_file(const char *path)
  134. {
  135. return true;
  136. }
  137. u64 FilesystemApk::last_modified_time(const char *path)
  138. {
  139. return 0;
  140. }
  141. CreateResult FilesystemApk::create_directory(const char *path)
  142. {
  143. CE_UNUSED(path);
  144. CE_FATAL("Cannot create directory in Android assets folder");
  145. CreateResult cr;
  146. cr.error = CreateResult::UNKNOWN;
  147. return cr;
  148. }
  149. DeleteResult FilesystemApk::delete_directory(const char *path)
  150. {
  151. CE_UNUSED(path);
  152. CE_FATAL("Cannot delete directory in Android assets folder");
  153. DeleteResult dr;
  154. dr.error = DeleteResult::UNKNOWN;
  155. return dr;
  156. }
  157. DeleteResult FilesystemApk::delete_file(const char *path)
  158. {
  159. CE_UNUSED(path);
  160. CE_FATAL("Cannot delete file in Android assets folder");
  161. DeleteResult dr;
  162. dr.error = DeleteResult::UNKNOWN;
  163. return dr;
  164. }
  165. void FilesystemApk::list_files(const char *path, Vector<DynamicString> &files)
  166. {
  167. CE_ENSURE(NULL != path);
  168. AAssetDir *root_dir = AAssetManager_openDir(_asset_manager, path);
  169. CE_ASSERT(root_dir != NULL, "Failed to open Android assets folder");
  170. const char *filename = NULL;
  171. while ((filename = AAssetDir_getNextFileName(root_dir)) != NULL) {
  172. TempAllocator512 ta;
  173. DynamicString name(ta);
  174. name = filename;
  175. vector::push_back(files, name);
  176. }
  177. AAssetDir_close(root_dir);
  178. }
  179. void FilesystemApk::absolute_path(DynamicString &os_path, const char *path)
  180. {
  181. os_path = path;
  182. }
  183. } // namespace crown
  184. #endif // if CROWN_PLATFORM_ANDROID