react-native-mmkv 3.3.0 → 4.0.0-beta.1

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 (95) 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 +13 -8
  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/hooks.js +2 -2
  10. package/lib/commonjs/hooks.js.map +1 -1
  11. package/lib/module/hooks.js +2 -2
  12. package/lib/module/hooks.js.map +1 -1
  13. package/lib/typescript/src/MemoryWarningListener.web.d.ts.map +1 -1
  14. package/lib/typescript/src/createMMKV.d.ts.map +1 -1
  15. package/lib/typescript/src/createMMKV.web.d.ts.map +1 -1
  16. package/package.json +24 -24
  17. package/react-native-mmkv.podspec +3 -9
  18. package/react-native.config.js +9 -0
  19. package/src/hooks.ts +2 -2
  20. package/MMKV/Core/CMakeLists.txt +0 -172
  21. package/MMKV/Core/CodedInputData.cpp +0 -252
  22. package/MMKV/Core/CodedInputData.h +0 -87
  23. package/MMKV/Core/CodedInputDataCrypt.cpp +0 -280
  24. package/MMKV/Core/CodedInputDataCrypt.h +0 -87
  25. package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +0 -62
  26. package/MMKV/Core/CodedInputData_OSX.cpp +0 -92
  27. package/MMKV/Core/CodedOutputData.cpp +0 -186
  28. package/MMKV/Core/CodedOutputData.h +0 -88
  29. package/MMKV/Core/Core.xcodeproj/project.pbxproj +0 -707
  30. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  31. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  32. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +0 -67
  33. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +0 -67
  34. package/MMKV/Core/InterProcessLock.cpp +0 -186
  35. package/MMKV/Core/InterProcessLock.h +0 -119
  36. package/MMKV/Core/InterProcessLock_Android.cpp +0 -103
  37. package/MMKV/Core/InterProcessLock_Win32.cpp +0 -108
  38. package/MMKV/Core/KeyValueHolder.cpp +0 -236
  39. package/MMKV/Core/KeyValueHolder.h +0 -122
  40. package/MMKV/Core/MMBuffer.cpp +0 -210
  41. package/MMKV/Core/MMBuffer.h +0 -111
  42. package/MMKV/Core/MMKV.cpp +0 -1702
  43. package/MMKV/Core/MMKV.h +0 -595
  44. package/MMKV/Core/MMKVLog.cpp +0 -127
  45. package/MMKV/Core/MMKVLog.h +0 -86
  46. package/MMKV/Core/MMKVLog_Android.cpp +0 -134
  47. package/MMKV/Core/MMKVMetaInfo.hpp +0 -99
  48. package/MMKV/Core/MMKVPredef.h +0 -293
  49. package/MMKV/Core/MMKV_Android.cpp +0 -261
  50. package/MMKV/Core/MMKV_IO.cpp +0 -1905
  51. package/MMKV/Core/MMKV_IO.h +0 -57
  52. package/MMKV/Core/MMKV_OSX.cpp +0 -423
  53. package/MMKV/Core/MMKV_OSX.h +0 -57
  54. package/MMKV/Core/MemoryFile.cpp +0 -603
  55. package/MMKV/Core/MemoryFile.h +0 -194
  56. package/MMKV/Core/MemoryFile_Android.cpp +0 -236
  57. package/MMKV/Core/MemoryFile_Linux.cpp +0 -125
  58. package/MMKV/Core/MemoryFile_OSX.cpp +0 -142
  59. package/MMKV/Core/MemoryFile_Win32.cpp +0 -554
  60. package/MMKV/Core/MiniPBCoder.cpp +0 -672
  61. package/MMKV/Core/MiniPBCoder.h +0 -151
  62. package/MMKV/Core/MiniPBCoder_OSX.cpp +0 -237
  63. package/MMKV/Core/PBEncodeItem.hpp +0 -104
  64. package/MMKV/Core/PBUtility.cpp +0 -61
  65. package/MMKV/Core/PBUtility.h +0 -148
  66. package/MMKV/Core/ScopedLock.hpp +0 -69
  67. package/MMKV/Core/ThreadLock.cpp +0 -75
  68. package/MMKV/Core/ThreadLock.h +0 -81
  69. package/MMKV/Core/ThreadLock_Win32.cpp +0 -89
  70. package/MMKV/Core/aes/AESCrypt.cpp +0 -273
  71. package/MMKV/Core/aes/AESCrypt.h +0 -112
  72. package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +0 -1243
  73. package/MMKV/Core/aes/openssl/openssl_aes.h +0 -130
  74. package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +0 -1044
  75. package/MMKV/Core/aes/openssl/openssl_aes_locl.h +0 -38
  76. package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +0 -308
  77. package/MMKV/Core/aes/openssl/openssl_arm_arch.h +0 -84
  78. package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +0 -97
  79. package/MMKV/Core/aes/openssl/openssl_md32_common.h +0 -254
  80. package/MMKV/Core/aes/openssl/openssl_md5.h +0 -49
  81. package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +0 -166
  82. package/MMKV/Core/aes/openssl/openssl_md5_locl.h +0 -75
  83. package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +0 -30
  84. package/MMKV/Core/aes/openssl/openssl_opensslconf.h +0 -271
  85. package/MMKV/Core/core.vcxproj +0 -288
  86. package/MMKV/Core/core.vcxproj.filters +0 -150
  87. package/MMKV/Core/crc32/Checksum.h +0 -75
  88. package/MMKV/Core/crc32/crc32_armv8.cpp +0 -134
  89. package/MMKV/Core/crc32/zlib/CMakeLists.txt +0 -60
  90. package/MMKV/Core/crc32/zlib/crc32.cpp +0 -55
  91. package/MMKV/Core/crc32/zlib/crc32.h +0 -48
  92. package/MMKV/Core/crc32/zlib/zconf.h +0 -380
  93. package/MMKV/Core/crc32/zlib/zutil.h +0 -25
  94. package/MMKV/LICENSE.TXT +0 -193
  95. 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