MemoryFile.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Tencent is pleased to support the open source community by making
  3. * MMKV available.
  4. *
  5. * Copyright (C) 2018 THL A29 Limited, a Tencent company.
  6. * All rights reserved.
  7. *
  8. * Licensed under the BSD 3-Clause License (the "License"); you may not use
  9. * this file except in compliance with the License. You may obtain a copy of
  10. * the License at
  11. *
  12. * https://opensource.org/licenses/BSD-3-Clause
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #ifndef MMKV_MAMERYFILE_H
  21. #define MMKV_MAMERYFILE_H
  22. #ifdef __cplusplus
  23. #include "MMKVPredef.h"
  24. #include <functional>
  25. #ifdef MMKV_ANDROID
  26. MMKVPath_t ashmemMMKVPathWithID(const MMKVPath_t &mmapID);
  27. namespace mmkv {
  28. extern int g_android_api;
  29. extern std::string g_android_tmpDir;
  30. enum FileType : bool { MMFILE_TYPE_FILE = false, MMFILE_TYPE_ASHMEM = true };
  31. } // namespace mmkv
  32. #endif // MMKV_ANDROID
  33. namespace mmkv {
  34. enum class OpenFlag : uint32_t {
  35. ReadOnly = 1 << 0,
  36. WriteOnly = 1 << 1,
  37. ReadWrite = ReadOnly | WriteOnly,
  38. Create = 1 << 2,
  39. Excel = 1 << 3, // fail if Create is set but the file already exist
  40. Truncate = 1 << 4,
  41. };
  42. static inline OpenFlag operator | (OpenFlag left, OpenFlag right) {
  43. return static_cast<OpenFlag>(static_cast<uint32_t>(left) | static_cast<uint32_t>(right));
  44. }
  45. static inline bool operator & (OpenFlag left, OpenFlag right) {
  46. return ((static_cast<uint32_t>(left) & static_cast<uint32_t>(right)) != 0);
  47. }
  48. class File {
  49. MMKVPath_t m_path;
  50. MMKVFileHandle_t m_fd;
  51. public:
  52. const OpenFlag m_flag;
  53. #ifndef MMKV_ANDROID
  54. explicit File(MMKVPath_t path, OpenFlag flag);
  55. #else
  56. File(MMKVPath_t path, OpenFlag flag, size_t size = 0, FileType fileType = MMFILE_TYPE_FILE);
  57. explicit File(MMKVFileHandle_t ashmemFD);
  58. size_t m_size;
  59. const FileType m_fileType;
  60. #endif // MMKV_ANDROID
  61. ~File() { close(); }
  62. bool open();
  63. void close();
  64. MMKVFileHandle_t getFd() { return m_fd; }
  65. const MMKVPath_t &getPath() const { return m_path; }
  66. #ifndef MMKV_WIN32
  67. bool isFileValid() const { return m_fd >= 0; }
  68. #else
  69. bool isFileValid() const { return m_fd != INVALID_HANDLE_VALUE; }
  70. #endif
  71. // get the actual file size on disk
  72. size_t getActualFileSize() const;
  73. // just forbid it for possibly misuse
  74. explicit File(const File &other) = delete;
  75. File &operator=(const File &other) = delete;
  76. friend class MemoryFile;
  77. };
  78. class MemoryFile {
  79. File m_diskFile;
  80. #ifdef MMKV_WIN32
  81. HANDLE m_fileMapping;
  82. #endif
  83. void *m_ptr;
  84. size_t m_size;
  85. bool mmap();
  86. void doCleanMemoryCache(bool forceClean);
  87. public:
  88. #ifndef MMKV_ANDROID
  89. explicit MemoryFile(MMKVPath_t path);
  90. #else
  91. MemoryFile(MMKVPath_t path, size_t size, FileType fileType);
  92. explicit MemoryFile(MMKVFileHandle_t ashmemFD);
  93. const FileType m_fileType;
  94. #endif // MMKV_ANDROID
  95. ~MemoryFile() { doCleanMemoryCache(true); }
  96. size_t getFileSize() const { return m_size; }
  97. // get the actual file size on disk
  98. size_t getActualFileSize() const { return m_diskFile.getActualFileSize(); }
  99. void *getMemory() { return m_ptr; }
  100. const MMKVPath_t &getPath() { return m_diskFile.getPath(); }
  101. MMKVFileHandle_t getFd() { return m_diskFile.getFd(); }
  102. // the newly expanded file content will be zeroed
  103. bool truncate(size_t size);
  104. bool msync(SyncFlag syncFlag);
  105. // call this if clearMemoryCache() has been called
  106. void reloadFromFile();
  107. void clearMemoryCache() { doCleanMemoryCache(false); }
  108. #ifndef MMKV_WIN32
  109. bool isFileValid() { return m_diskFile.isFileValid() && m_size > 0 && m_ptr; }
  110. #else
  111. bool isFileValid() { return m_diskFile.isFileValid() && m_size > 0 && m_fileMapping && m_ptr; }
  112. #endif
  113. // just forbid it for possibly misuse
  114. explicit MemoryFile(const MemoryFile &other) = delete;
  115. MemoryFile &operator=(const MemoryFile &other) = delete;
  116. };
  117. class MMBuffer;
  118. extern bool mkPath(const MMKVPath_t &path);
  119. extern bool isFileExist(const MMKVPath_t &nsFilePath);
  120. extern MMBuffer *readWholeFile(const MMKVPath_t &path);
  121. extern bool zeroFillFile(MMKVFileHandle_t fd, size_t startPos, size_t size);
  122. extern size_t getPageSize();
  123. extern bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath);
  124. // copy file by potentially renaming target file, might change file inode
  125. extern bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath);
  126. // copy file by source file content, keep file inode the same
  127. extern bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath);
  128. extern bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD);
  129. extern bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD, bool needTruncate);
  130. enum WalkType : uint32_t {
  131. WalkFile = 1 << 0,
  132. WalkFolder = 1 << 1,
  133. };
  134. extern void walkInDir(const MMKVPath_t &dirPath, WalkType type, const std::function<void(const MMKVPath_t&, WalkType)> &walker);
  135. } // namespace mmkv
  136. #endif
  137. #endif //MMKV_MAMERYFILE_H