react-native-mmkv 3.2.0 → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/android/CMakeLists.txt +18 -9
  2. package/android/build.gradle +6 -2
  3. package/cpp/{MMKVManagedBuffer.h → ManagedMMBuffer.h} +6 -6
  4. package/cpp/MmkvHostObject.cpp +22 -17
  5. package/cpp/MmkvHostObject.h +1 -2
  6. package/cpp/MmkvTypes.h +50 -0
  7. package/cpp/NativeMmkvModule.cpp +3 -3
  8. package/cpp/NativeMmkvModule.h +1 -8
  9. package/lib/commonjs/MMKV.js.map +1 -1
  10. package/lib/commonjs/Types.js.map +1 -1
  11. package/lib/commonjs/createMMKV.web.js +1 -1
  12. package/lib/commonjs/createMMKV.web.js.map +1 -1
  13. package/lib/module/MMKV.js.map +1 -1
  14. package/lib/module/Types.js.map +1 -1
  15. package/lib/module/createMMKV.web.js +1 -1
  16. package/lib/module/createMMKV.web.js.map +1 -1
  17. package/lib/typescript/src/MMKV.d.ts +1 -1
  18. package/lib/typescript/src/MMKV.d.ts.map +1 -1
  19. package/lib/typescript/src/Types.d.ts +7 -1
  20. package/lib/typescript/src/Types.d.ts.map +1 -1
  21. package/lib/typescript/src/hooks.d.ts +1 -1
  22. package/lib/typescript/src/hooks.d.ts.map +1 -1
  23. package/package.json +22 -27
  24. package/react-native-mmkv.podspec +4 -10
  25. package/react-native.config.js +9 -0
  26. package/src/MMKV.ts +1 -1
  27. package/src/Types.ts +7 -1
  28. package/src/createMMKV.web.ts +1 -1
  29. package/src/hooks.ts +1 -1
  30. package/MMKV/Core/CMakeLists.txt +0 -172
  31. package/MMKV/Core/CodedInputData.cpp +0 -252
  32. package/MMKV/Core/CodedInputData.h +0 -87
  33. package/MMKV/Core/CodedInputDataCrypt.cpp +0 -280
  34. package/MMKV/Core/CodedInputDataCrypt.h +0 -87
  35. package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +0 -62
  36. package/MMKV/Core/CodedInputData_OSX.cpp +0 -92
  37. package/MMKV/Core/CodedOutputData.cpp +0 -186
  38. package/MMKV/Core/CodedOutputData.h +0 -88
  39. package/MMKV/Core/Core.xcodeproj/project.pbxproj +0 -707
  40. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  41. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  42. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +0 -67
  43. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +0 -67
  44. package/MMKV/Core/InterProcessLock.cpp +0 -186
  45. package/MMKV/Core/InterProcessLock.h +0 -119
  46. package/MMKV/Core/InterProcessLock_Android.cpp +0 -103
  47. package/MMKV/Core/InterProcessLock_Win32.cpp +0 -108
  48. package/MMKV/Core/KeyValueHolder.cpp +0 -236
  49. package/MMKV/Core/KeyValueHolder.h +0 -122
  50. package/MMKV/Core/MMBuffer.cpp +0 -210
  51. package/MMKV/Core/MMBuffer.h +0 -111
  52. package/MMKV/Core/MMKV.cpp +0 -1702
  53. package/MMKV/Core/MMKV.h +0 -595
  54. package/MMKV/Core/MMKVLog.cpp +0 -127
  55. package/MMKV/Core/MMKVLog.h +0 -86
  56. package/MMKV/Core/MMKVLog_Android.cpp +0 -134
  57. package/MMKV/Core/MMKVMetaInfo.hpp +0 -99
  58. package/MMKV/Core/MMKVPredef.h +0 -293
  59. package/MMKV/Core/MMKV_Android.cpp +0 -261
  60. package/MMKV/Core/MMKV_IO.cpp +0 -1905
  61. package/MMKV/Core/MMKV_IO.h +0 -57
  62. package/MMKV/Core/MMKV_OSX.cpp +0 -423
  63. package/MMKV/Core/MMKV_OSX.h +0 -57
  64. package/MMKV/Core/MemoryFile.cpp +0 -603
  65. package/MMKV/Core/MemoryFile.h +0 -194
  66. package/MMKV/Core/MemoryFile_Android.cpp +0 -236
  67. package/MMKV/Core/MemoryFile_Linux.cpp +0 -125
  68. package/MMKV/Core/MemoryFile_OSX.cpp +0 -142
  69. package/MMKV/Core/MemoryFile_Win32.cpp +0 -554
  70. package/MMKV/Core/MiniPBCoder.cpp +0 -672
  71. package/MMKV/Core/MiniPBCoder.h +0 -151
  72. package/MMKV/Core/MiniPBCoder_OSX.cpp +0 -237
  73. package/MMKV/Core/PBEncodeItem.hpp +0 -104
  74. package/MMKV/Core/PBUtility.cpp +0 -61
  75. package/MMKV/Core/PBUtility.h +0 -148
  76. package/MMKV/Core/ScopedLock.hpp +0 -69
  77. package/MMKV/Core/ThreadLock.cpp +0 -75
  78. package/MMKV/Core/ThreadLock.h +0 -81
  79. package/MMKV/Core/ThreadLock_Win32.cpp +0 -89
  80. package/MMKV/Core/aes/AESCrypt.cpp +0 -273
  81. package/MMKV/Core/aes/AESCrypt.h +0 -112
  82. package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +0 -1243
  83. package/MMKV/Core/aes/openssl/openssl_aes.h +0 -130
  84. package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +0 -1044
  85. package/MMKV/Core/aes/openssl/openssl_aes_locl.h +0 -38
  86. package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +0 -308
  87. package/MMKV/Core/aes/openssl/openssl_arm_arch.h +0 -84
  88. package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +0 -97
  89. package/MMKV/Core/aes/openssl/openssl_md32_common.h +0 -254
  90. package/MMKV/Core/aes/openssl/openssl_md5.h +0 -49
  91. package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +0 -166
  92. package/MMKV/Core/aes/openssl/openssl_md5_locl.h +0 -75
  93. package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +0 -30
  94. package/MMKV/Core/aes/openssl/openssl_opensslconf.h +0 -271
  95. package/MMKV/Core/core.vcxproj +0 -288
  96. package/MMKV/Core/core.vcxproj.filters +0 -150
  97. package/MMKV/Core/crc32/Checksum.h +0 -75
  98. package/MMKV/Core/crc32/crc32_armv8.cpp +0 -134
  99. package/MMKV/Core/crc32/zlib/CMakeLists.txt +0 -60
  100. package/MMKV/Core/crc32/zlib/crc32.cpp +0 -55
  101. package/MMKV/Core/crc32/zlib/crc32.h +0 -48
  102. package/MMKV/Core/crc32/zlib/zconf.h +0 -380
  103. package/MMKV/Core/crc32/zlib/zutil.h +0 -25
  104. package/MMKV/README.md +0 -354
@@ -1,554 +0,0 @@
1
- /*
2
- * Tencent is pleased to support the open source community by making
3
- * MMKV available.
4
- *
5
- * Copyright (C) 2019 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
-
21
- #include "MemoryFile.h"
22
-
23
- #ifdef MMKV_WIN32
24
-
25
- # include "InterProcessLock.h"
26
- # include "MMBuffer.h"
27
- # include "MMKVLog.h"
28
- # include "ScopedLock.hpp"
29
- # include "ThreadLock.h"
30
- # include <cassert>
31
- # include <strsafe.h>
32
-
33
- using namespace std;
34
-
35
- namespace mmkv {
36
-
37
- static bool getFileSize(MMKVFileHandle_t fd, size_t &size);
38
- static bool ftruncate(MMKVFileHandle_t file, size_t size);
39
-
40
- File::File(MMKVPath_t path, OpenFlag flag) : m_path(std::move(path)), m_fd(INVALID_HANDLE_VALUE), m_flag(flag) {
41
- open();
42
- }
43
-
44
- static pair<int, int> OpenFlag2NativeFlag(OpenFlag flag) {
45
- int access = 0, create = OPEN_EXISTING;
46
- if ((flag & OpenFlagRWMask) == OpenFlag::ReadWrite) {
47
- access = (GENERIC_READ | GENERIC_WRITE);
48
- } else if (flag & OpenFlag::ReadOnly) {
49
- access |= GENERIC_READ;
50
- } else if (flag & OpenFlag::WriteOnly) {
51
- access |= GENERIC_WRITE;
52
- }
53
- if (flag & OpenFlag::Create) {
54
- create = OPEN_ALWAYS;
55
- }
56
- if (flag & OpenFlag::Excel) {
57
- access = CREATE_NEW;
58
- }
59
- if (flag & OpenFlag::Truncate) {
60
- access = CREATE_ALWAYS;
61
- }
62
- return {access, create};
63
- }
64
-
65
- bool File::open() {
66
- if (isFileValid()) {
67
- return true;
68
- }
69
- auto pair = OpenFlag2NativeFlag(m_flag);
70
- m_fd = CreateFile(m_path.c_str(), pair.first, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
71
- pair.second, FILE_ATTRIBUTE_NORMAL, nullptr);
72
- if (!isFileValid()) {
73
- MMKVError("fail to open:[%ls], flag %x, error %d", m_path.c_str(), m_flag, GetLastError());
74
- return false;
75
- }
76
- MMKVInfo("open fd[%p], flag %x, %ls", m_fd, m_flag, m_path.c_str());
77
- return true;
78
- }
79
-
80
- void File::close() {
81
- if (isFileValid()) {
82
- MMKVInfo("closing fd[%p], %ls", m_fd, m_path.c_str());
83
- if (CloseHandle(m_fd)) {
84
- m_fd = INVALID_HANDLE_VALUE;
85
- } else {
86
- MMKVError("fail to close [%ls], %d", m_path.c_str(), GetLastError());
87
- }
88
- }
89
- }
90
-
91
- size_t File::getActualFileSize() const {
92
- size_t size = 0;
93
- mmkv::getFileSize(m_fd, size);
94
- return size;
95
- }
96
-
97
- MemoryFile::MemoryFile(MMKVPath_t path, size_t expectedCapacity, bool readOnly)
98
- : m_diskFile(std::move(path), readOnly ? OpenFlag::ReadOnly : (OpenFlag::ReadWrite | OpenFlag::Create))
99
- , m_fileMapping(nullptr)
100
- , m_ptr(nullptr)
101
- , m_size(0)
102
- , m_readOnly(readOnly) {
103
- reloadFromFile(expectedCapacity);
104
- }
105
-
106
- bool MemoryFile::truncate(size_t size) {
107
- if (!m_diskFile.isFileValid()) {
108
- return false;
109
- }
110
- if (size == m_size) {
111
- return true;
112
- }
113
- if (m_readOnly) {
114
- // truncate readonly file not allow
115
- return false;
116
- }
117
-
118
- auto oldSize = m_size;
119
- m_size = size;
120
- // round up to (n * pagesize)
121
- if (m_size < DEFAULT_MMAP_SIZE || (m_size % DEFAULT_MMAP_SIZE != 0)) {
122
- m_size = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE;
123
- }
124
-
125
- if (m_ptr) {
126
- if (!UnmapViewOfFile(m_ptr)) {
127
- MMKVError("fail to munmap [%ls], %d", m_diskFile.m_path.c_str(), GetLastError());
128
- }
129
- m_ptr = nullptr;
130
- }
131
- if (m_fileMapping) {
132
- CloseHandle(m_fileMapping);
133
- m_fileMapping = nullptr;
134
- }
135
-
136
- if (!ftruncate(m_diskFile.getFd(), m_size)) {
137
- MMKVError("fail to truncate [%ls] to size %zu", m_diskFile.m_path.c_str(), m_size);
138
- m_size = oldSize;
139
- mmap();
140
- return false;
141
- }
142
- if (m_size > oldSize) {
143
- if (!zeroFillFile(m_diskFile.getFd(), oldSize, m_size - oldSize)) {
144
- MMKVError("fail to zeroFile [%ls] to size %zu", m_diskFile.m_path.c_str(), m_size);
145
- m_size = oldSize;
146
- mmap();
147
- return false;
148
- }
149
- }
150
-
151
- auto ret = mmap();
152
- if (!ret) {
153
- doCleanMemoryCache(true);
154
- }
155
- return ret;
156
- }
157
-
158
- bool MemoryFile::msync(SyncFlag syncFlag) {
159
- if (m_readOnly) {
160
- // there's no point in msync() readonly memory
161
- return true;
162
- }
163
- if (m_ptr) {
164
- if (FlushViewOfFile(m_ptr, m_size)) {
165
- if (syncFlag == MMKV_SYNC) {
166
- if (!FlushFileBuffers(m_diskFile.getFd())) {
167
- MMKVError("fail to FlushFileBuffers [%ls]:%d", m_diskFile.m_path.c_str(), GetLastError());
168
- return false;
169
- }
170
- }
171
- return true;
172
- }
173
- MMKVError("fail to FlushViewOfFile [%ls]:%d", m_diskFile.m_path.c_str(), GetLastError());
174
- return false;
175
- }
176
- return false;
177
- }
178
-
179
- bool MemoryFile::mmap() {
180
- auto mode = m_readOnly ? PAGE_READONLY : PAGE_READWRITE;
181
- m_fileMapping = CreateFileMapping(m_diskFile.getFd(), nullptr, mode, 0, 0, nullptr);
182
- if (!m_fileMapping) {
183
- MMKVError("fail to CreateFileMapping [%ls], mode %x, %d", m_diskFile.m_path.c_str(), mode, GetLastError());
184
- return false;
185
- } else {
186
- auto viewMode = m_readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
187
- m_ptr = (char *) MapViewOfFile(m_fileMapping, viewMode, 0, 0, 0);
188
- if (!m_ptr) {
189
- MMKVError("fail to mmap [%ls], mode %x, %d", m_diskFile.m_path.c_str(), viewMode, GetLastError());
190
- return false;
191
- }
192
- MMKVInfo("mmap to address [%p], [%ls]", m_ptr, m_diskFile.m_path.c_str());
193
- }
194
-
195
- return true;
196
- }
197
-
198
- void MemoryFile::reloadFromFile(size_t expectedCapacity) {
199
- if (isFileValid()) {
200
- MMKVWarning("calling reloadFromFile while the cache [%ls] is still valid", m_diskFile.m_path.c_str());
201
- assert(0);
202
- clearMemoryCache();
203
- }
204
- m_diskFile.open();
205
- if (m_diskFile.isFileValid()) {
206
- FileLock fileLock(m_diskFile.getFd());
207
- InterProcessLock lock(&fileLock, ExclusiveLockType);
208
- SCOPED_LOCK(&lock);
209
-
210
- mmkv::getFileSize(m_diskFile.getFd(), m_size);
211
- size_t expectedSize = std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE));
212
- // round up to (n * pagesize)
213
- if (!m_readOnly && (m_size < expectedSize || (m_size % DEFAULT_MMAP_SIZE != 0))) {
214
- size_t roundSize = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE;;
215
- roundSize = std::max<size_t>(expectedSize, roundSize);
216
- truncate(roundSize);
217
- } else {
218
- auto ret = mmap();
219
- if (!ret) {
220
- doCleanMemoryCache(true);
221
- }
222
- }
223
- }
224
- }
225
-
226
- void MemoryFile::doCleanMemoryCache(bool forceClean) {
227
- if (m_ptr) {
228
- UnmapViewOfFile(m_ptr);
229
- m_ptr = nullptr;
230
- }
231
- if (m_fileMapping) {
232
- CloseHandle(m_fileMapping);
233
- m_fileMapping = nullptr;
234
- }
235
- m_diskFile.close();
236
- }
237
-
238
- size_t getPageSize() {
239
- SYSTEM_INFO system_info;
240
- GetSystemInfo(&system_info);
241
- return system_info.dwPageSize;
242
- }
243
-
244
- bool isFileExist(const MMKVPath_t &nsFilePath) {
245
- if (nsFilePath.empty()) {
246
- return false;
247
- }
248
- auto attribute = GetFileAttributes(nsFilePath.c_str());
249
- return (attribute != INVALID_FILE_ATTRIBUTES);
250
- }
251
-
252
- bool mkPath(const MMKVPath_t &str) {
253
- wchar_t *path = _wcsdup(str.c_str());
254
-
255
- bool done = false;
256
- wchar_t *slash = path;
257
-
258
- while (!done) {
259
- slash += wcsspn(slash, L"\\");
260
- slash += wcscspn(slash, L"\\");
261
-
262
- done = (*slash == L'\0');
263
- *slash = L'\0';
264
-
265
- auto attribute = GetFileAttributes(path);
266
- if (attribute == INVALID_FILE_ATTRIBUTES) {
267
- if (!CreateDirectory(path, nullptr)) {
268
- MMKVError("fail to create dir:%ls, %d", str.c_str(), GetLastError());
269
- free(path);
270
- return false;
271
- }
272
- } else if (!(attribute & FILE_ATTRIBUTE_DIRECTORY)) {
273
- MMKVError("%ls attribute:%d not a directry", str.c_str(), attribute);
274
- free(path);
275
- return false;
276
- }
277
-
278
- *slash = L'\\';
279
- }
280
- free(path);
281
- return true;
282
- }
283
-
284
- MMBuffer *readWholeFile(const MMKVPath_t &nsFilePath) {
285
- MMBuffer *buffer = nullptr;
286
- auto fd = CreateFile(nsFilePath.c_str(), GENERIC_READ | GENERIC_WRITE,
287
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING,
288
- FILE_ATTRIBUTE_NORMAL, nullptr);
289
- if (fd != INVALID_HANDLE_VALUE) {
290
- size_t fileLength = 0;
291
- getFileSize(fd, fileLength);
292
- if (fileLength > 0) {
293
- buffer = new MMBuffer(static_cast<size_t>(fileLength));
294
- SetFilePointer(fd, 0, 0, FILE_BEGIN);
295
- DWORD readSize = 0;
296
- if (ReadFile(fd, buffer->getPtr(), (DWORD) fileLength, &readSize, nullptr)) {
297
- //fileSize = readSize;
298
- } else {
299
- MMKVWarning("fail to read %ls: %d", nsFilePath.c_str(), GetLastError());
300
- delete buffer;
301
- buffer = nullptr;
302
- }
303
- }
304
- CloseHandle(fd);
305
- } else {
306
- MMKVWarning("fail to open %ls: %d", nsFilePath.c_str(), GetLastError());
307
- }
308
- return buffer;
309
- }
310
-
311
- bool zeroFillFile(MMKVFileHandle_t file, size_t startPos, size_t size) {
312
- if (file == INVALID_HANDLE_VALUE) {
313
- return false;
314
- }
315
- if (size == 0) {
316
- return true;
317
- }
318
-
319
- LARGE_INTEGER position;
320
- position.QuadPart = startPos;
321
- if (!SetFilePointerEx(file, position, nullptr, FILE_BEGIN)) {
322
- MMKVError("fail to lseek fd[%p], error:%d", file, GetLastError());
323
- return false;
324
- }
325
-
326
- static const char zeros[4096] = {0};
327
- while (size >= sizeof(zeros)) {
328
- DWORD bytesWritten = 0;
329
- if (!WriteFile(file, zeros, sizeof(zeros), &bytesWritten, nullptr)) {
330
- MMKVError("fail to write fd[%p], error:%d", file, GetLastError());
331
- return false;
332
- }
333
- size -= bytesWritten;
334
- }
335
- if (size > 0) {
336
- DWORD bytesWritten = 0;
337
- if (!WriteFile(file, zeros, (DWORD) size, &bytesWritten, nullptr)) {
338
- MMKVError("fail to write fd[%p], error:%d", file, GetLastError());
339
- return false;
340
- }
341
- }
342
- return true;
343
- }
344
-
345
- static bool ftruncate(MMKVFileHandle_t file, size_t size) {
346
- LARGE_INTEGER large;
347
- large.QuadPart = size;
348
- if (SetFilePointerEx(file, large, 0, FILE_BEGIN)) {
349
- if (SetEndOfFile(file)) {
350
- return true;
351
- }
352
- MMKVError("fail to SetEndOfFile:%d", GetLastError());
353
- return false;
354
- } else {
355
- MMKVError("fail to SetFilePointer:%d", GetLastError());
356
- return false;
357
- }
358
- }
359
-
360
- static bool getFileSize(MMKVFileHandle_t fd, size_t &size) {
361
- LARGE_INTEGER filesize = {0};
362
- if (GetFileSizeEx(fd, &filesize)) {
363
- size = static_cast<size_t>(filesize.QuadPart);
364
- return true;
365
- }
366
- return false;
367
- }
368
-
369
- static pair<MMKVPath_t, MMKVFileHandle_t> createUniqueTempFile(const wchar_t *prefix) {
370
- wchar_t lpTempPathBuffer[MAX_PATH];
371
- // Gets the temp path env string (no guarantee it's a valid path).
372
- auto dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer);
373
- if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
374
- MMKVError("GetTempPath failed %d", GetLastError());
375
- return {L"", INVALID_HANDLE_VALUE};
376
- }
377
- // Generates a temporary file name.
378
- wchar_t szTempFileName[MAX_PATH];
379
- if (!GetTempFileName(lpTempPathBuffer, prefix, 0, szTempFileName)) {
380
- MMKVError("GetTempFileName failed %d", GetLastError());
381
- return {L"", INVALID_HANDLE_VALUE};
382
- }
383
- auto hTempFile =
384
- CreateFile(szTempFileName, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
385
- if (hTempFile == INVALID_HANDLE_VALUE) {
386
- MMKVError("fail to create unique temp file [%ls], %d", szTempFileName, GetLastError());
387
- return {L"", INVALID_HANDLE_VALUE};
388
- }
389
- MMKVDebug("create unique temp file [%ls] with fd[%p]", szTempFileName, hTempFile);
390
- return {MMKVPath_t(szTempFileName), hTempFile};
391
- }
392
-
393
- bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
394
- if (MoveFileEx(srcPath.c_str(), dstPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) == 0) {
395
- MMKVError("MoveFileEx [%ls] to [%ls] failed %d", srcPath.c_str(), dstPath.c_str(), GetLastError());
396
- return false;
397
- }
398
- return true;
399
- }
400
-
401
- bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD, bool needTruncate) {
402
- if (dstFD == INVALID_HANDLE_VALUE) {
403
- return false;
404
- }
405
- bool ret = false;
406
- File srcFile(srcPath, OpenFlag::ReadOnly);
407
- if (!srcFile.isFileValid()) {
408
- return false;
409
- }
410
- auto bufferSize = getPageSize();
411
- auto buffer = (char *) malloc(bufferSize);
412
- if (!buffer) {
413
- MMKVError("fail to malloc size %zu, %d(%s)", bufferSize, errno, strerror(errno));
414
- goto errorOut;
415
- }
416
- SetFilePointer(dstFD, 0, 0, FILE_BEGIN);
417
-
418
- // the Win32 platform don't have sendfile()/fcopyfile() equivalent, do it the hard way
419
- while (true) {
420
- DWORD sizeRead = 0;
421
- if (!ReadFile(srcFile.getFd(), buffer, (DWORD) bufferSize, &sizeRead, nullptr)) {
422
- MMKVError("fail to read %ls: %d", srcPath.c_str(), GetLastError());
423
- goto errorOut;
424
- }
425
-
426
- DWORD sizeWrite = 0;
427
- if (!WriteFile(dstFD, buffer, sizeRead, &sizeWrite, nullptr)) {
428
- MMKVError("fail to write fd [%d], %d", dstFD, GetLastError());
429
- goto errorOut;
430
- }
431
-
432
- if (sizeRead < bufferSize) {
433
- break;
434
- }
435
- }
436
- if (needTruncate) {
437
- size_t dstFileSize = 0;
438
- getFileSize(dstFD, dstFileSize);
439
- auto srcFileSize = srcFile.getActualFileSize();
440
- if ((dstFileSize != srcFileSize) && !ftruncate(dstFD, static_cast<off_t>(srcFileSize))) {
441
- MMKVError("fail to truncate [%d] to size [%zu]", dstFD, srcFileSize);
442
- goto errorOut;
443
- }
444
- }
445
-
446
- ret = true;
447
- MMKVInfo("copy content from %ls to fd[%d] finish", srcPath.c_str(), dstFD);
448
-
449
- errorOut:
450
- free(buffer);
451
- return ret;
452
- }
453
-
454
- // copy to a temp file then rename it
455
- // this is the best we can do on Win32
456
- bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
457
- auto pair = createUniqueTempFile(L"MMKV");
458
- auto tmpFD = pair.second;
459
- auto &tmpPath = pair.first;
460
- if (tmpFD == INVALID_HANDLE_VALUE) {
461
- return false;
462
- }
463
-
464
- bool renamed = false;
465
- if (copyFileContent(srcPath, tmpFD, false)) {
466
- MMKVInfo("copyed file [%ls] to [%ls]", srcPath.c_str(), tmpPath.c_str());
467
- CloseHandle(tmpFD);
468
- renamed = tryAtomicRename(tmpPath.c_str(), dstPath.c_str());
469
- if (renamed) {
470
- MMKVInfo("copyfile [%ls] to [%ls] finish.", srcPath.c_str(), dstPath.c_str());
471
- }
472
- } else {
473
- CloseHandle(tmpFD);
474
- }
475
-
476
- if (!renamed) {
477
- DeleteFile(tmpPath.c_str());
478
- }
479
- return renamed;
480
- }
481
-
482
- bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
483
- File dstFile(dstPath, OpenFlag::WriteOnly | OpenFlag::Create | OpenFlag::Truncate);
484
- if (!dstFile.isFileValid()) {
485
- return false;
486
- }
487
- auto ret = copyFileContent(srcPath, dstFile.getFd(), false);
488
- if (!ret) {
489
- MMKVError("fail to copyfile(): target file %ls", dstPath.c_str());
490
- } else {
491
- MMKVInfo("copy content from %ls to [%ls] finish", srcPath.c_str(), dstPath.c_str());
492
- }
493
- return ret;
494
- }
495
-
496
- bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD) {
497
- return copyFileContent(srcPath, dstFD, true);
498
- }
499
-
500
- void walkInDir(const MMKVPath_t &dirPath,
501
- WalkType type,
502
- const std::function<void(const MMKVPath_t &, WalkType)> &walker) {
503
- wchar_t szDir[MAX_PATH];
504
- StringCchCopy(szDir, MAX_PATH, dirPath.c_str());
505
- StringCchCat(szDir, MAX_PATH, L"\\*");
506
-
507
- WIN32_FIND_DATA ffd;
508
- auto hFind = FindFirstFile(szDir, &ffd);
509
- if (hFind == INVALID_HANDLE_VALUE) {
510
- return;
511
- }
512
-
513
- do {
514
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
515
- if (type & WalkFolder) {
516
- if (wcscmp(ffd.cFileName, L".") == 0 || wcscmp(ffd.cFileName, L"..") == 0) {
517
- continue;
518
- }
519
- walker(dirPath + L"\\" + ffd.cFileName, WalkFolder);
520
- }
521
- } else if (type & WalkFile) {
522
- walker(dirPath + L"\\" + ffd.cFileName, WalkFile);
523
- }
524
- } while (FindNextFile(hFind, &ffd) != 0);
525
-
526
- auto dwError = GetLastError();
527
- if (dwError != ERROR_NO_MORE_FILES) {
528
- MMKVError("WalkInDir fail %d", dwError);
529
- }
530
-
531
- FindClose(hFind);
532
- }
533
-
534
- } // namespace mmkv
535
-
536
- std::wstring string2MMKVPath_t(const std::string &str) {
537
- auto length = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
538
- auto buffer = new wchar_t[length];
539
- MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buffer, length);
540
- wstring result(buffer);
541
- delete[] buffer;
542
- return result;
543
- }
544
-
545
- std::string MMKVPath_t2String(const MMKVPath_t &str) {
546
- auto length = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, nullptr, 0, 0, 0);
547
- auto buffer = new char[length];
548
- WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, buffer, length, 0, 0);
549
- string result(buffer);
550
- delete[] buffer;
551
- return result;
552
- }
553
-
554
- #endif // MMKV_WIN32