react-native-mmkv 3.3.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.
- package/android/CMakeLists.txt +18 -9
- package/android/build.gradle +6 -2
- package/cpp/{MMKVManagedBuffer.h → ManagedMMBuffer.h} +6 -6
- package/cpp/MmkvHostObject.cpp +13 -8
- package/cpp/MmkvHostObject.h +1 -2
- package/cpp/MmkvTypes.h +50 -0
- package/cpp/NativeMmkvModule.cpp +3 -3
- package/cpp/NativeMmkvModule.h +1 -8
- package/package.json +22 -23
- package/react-native-mmkv.podspec +3 -9
- package/react-native.config.js +9 -0
- package/MMKV/Core/CMakeLists.txt +0 -172
- package/MMKV/Core/CodedInputData.cpp +0 -252
- package/MMKV/Core/CodedInputData.h +0 -87
- package/MMKV/Core/CodedInputDataCrypt.cpp +0 -280
- package/MMKV/Core/CodedInputDataCrypt.h +0 -87
- package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +0 -62
- package/MMKV/Core/CodedInputData_OSX.cpp +0 -92
- package/MMKV/Core/CodedOutputData.cpp +0 -186
- package/MMKV/Core/CodedOutputData.h +0 -88
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +0 -707
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +0 -67
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +0 -67
- package/MMKV/Core/InterProcessLock.cpp +0 -186
- package/MMKV/Core/InterProcessLock.h +0 -119
- package/MMKV/Core/InterProcessLock_Android.cpp +0 -103
- package/MMKV/Core/InterProcessLock_Win32.cpp +0 -108
- package/MMKV/Core/KeyValueHolder.cpp +0 -236
- package/MMKV/Core/KeyValueHolder.h +0 -122
- package/MMKV/Core/MMBuffer.cpp +0 -210
- package/MMKV/Core/MMBuffer.h +0 -111
- package/MMKV/Core/MMKV.cpp +0 -1702
- package/MMKV/Core/MMKV.h +0 -595
- package/MMKV/Core/MMKVLog.cpp +0 -127
- package/MMKV/Core/MMKVLog.h +0 -86
- package/MMKV/Core/MMKVLog_Android.cpp +0 -134
- package/MMKV/Core/MMKVMetaInfo.hpp +0 -99
- package/MMKV/Core/MMKVPredef.h +0 -293
- package/MMKV/Core/MMKV_Android.cpp +0 -261
- package/MMKV/Core/MMKV_IO.cpp +0 -1905
- package/MMKV/Core/MMKV_IO.h +0 -57
- package/MMKV/Core/MMKV_OSX.cpp +0 -423
- package/MMKV/Core/MMKV_OSX.h +0 -57
- package/MMKV/Core/MemoryFile.cpp +0 -603
- package/MMKV/Core/MemoryFile.h +0 -194
- package/MMKV/Core/MemoryFile_Android.cpp +0 -236
- package/MMKV/Core/MemoryFile_Linux.cpp +0 -125
- package/MMKV/Core/MemoryFile_OSX.cpp +0 -142
- package/MMKV/Core/MemoryFile_Win32.cpp +0 -554
- package/MMKV/Core/MiniPBCoder.cpp +0 -672
- package/MMKV/Core/MiniPBCoder.h +0 -151
- package/MMKV/Core/MiniPBCoder_OSX.cpp +0 -237
- package/MMKV/Core/PBEncodeItem.hpp +0 -104
- package/MMKV/Core/PBUtility.cpp +0 -61
- package/MMKV/Core/PBUtility.h +0 -148
- package/MMKV/Core/ScopedLock.hpp +0 -69
- package/MMKV/Core/ThreadLock.cpp +0 -75
- package/MMKV/Core/ThreadLock.h +0 -81
- package/MMKV/Core/ThreadLock_Win32.cpp +0 -89
- package/MMKV/Core/aes/AESCrypt.cpp +0 -273
- package/MMKV/Core/aes/AESCrypt.h +0 -112
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +0 -1243
- package/MMKV/Core/aes/openssl/openssl_aes.h +0 -130
- package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +0 -1044
- package/MMKV/Core/aes/openssl/openssl_aes_locl.h +0 -38
- package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +0 -308
- package/MMKV/Core/aes/openssl/openssl_arm_arch.h +0 -84
- package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +0 -97
- package/MMKV/Core/aes/openssl/openssl_md32_common.h +0 -254
- package/MMKV/Core/aes/openssl/openssl_md5.h +0 -49
- package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +0 -166
- package/MMKV/Core/aes/openssl/openssl_md5_locl.h +0 -75
- package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +0 -30
- package/MMKV/Core/aes/openssl/openssl_opensslconf.h +0 -271
- package/MMKV/Core/core.vcxproj +0 -288
- package/MMKV/Core/core.vcxproj.filters +0 -150
- package/MMKV/Core/crc32/Checksum.h +0 -75
- package/MMKV/Core/crc32/crc32_armv8.cpp +0 -134
- package/MMKV/Core/crc32/zlib/CMakeLists.txt +0 -60
- package/MMKV/Core/crc32/zlib/crc32.cpp +0 -55
- package/MMKV/Core/crc32/zlib/crc32.h +0 -48
- package/MMKV/Core/crc32/zlib/zconf.h +0 -380
- package/MMKV/Core/crc32/zlib/zutil.h +0 -25
- package/MMKV/LICENSE.TXT +0 -193
- package/MMKV/README.md +0 -354
package/MMKV/Core/MMKV.cpp
DELETED
|
@@ -1,1702 +0,0 @@
|
|
|
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
|
-
|
|
21
|
-
#include "CodedInputData.h"
|
|
22
|
-
#include "CodedOutputData.h"
|
|
23
|
-
#include "InterProcessLock.h"
|
|
24
|
-
#include "KeyValueHolder.h"
|
|
25
|
-
#include "MMBuffer.h"
|
|
26
|
-
#include "MMKVLog.h"
|
|
27
|
-
#include "MMKVMetaInfo.hpp"
|
|
28
|
-
#include "MMKV_IO.h"
|
|
29
|
-
#include "MMKV_OSX.h"
|
|
30
|
-
#include "MemoryFile.h"
|
|
31
|
-
#include "MiniPBCoder.h"
|
|
32
|
-
#include "PBUtility.h"
|
|
33
|
-
#include "ScopedLock.hpp"
|
|
34
|
-
#include "ThreadLock.h"
|
|
35
|
-
#include "aes/AESCrypt.h"
|
|
36
|
-
#include "aes/openssl/openssl_aes.h"
|
|
37
|
-
#include "aes/openssl/openssl_md5.h"
|
|
38
|
-
#include "crc32/Checksum.h"
|
|
39
|
-
#include <algorithm>
|
|
40
|
-
#include <cstdio>
|
|
41
|
-
#include <cstring>
|
|
42
|
-
#include <unordered_set>
|
|
43
|
-
#include <cassert>
|
|
44
|
-
|
|
45
|
-
#if defined(__aarch64__) && defined(__linux__) && !defined (MMKV_OHOS)
|
|
46
|
-
# include <asm/hwcap.h>
|
|
47
|
-
# include <sys/auxv.h>
|
|
48
|
-
#endif
|
|
49
|
-
|
|
50
|
-
#ifdef MMKV_APPLE
|
|
51
|
-
# if __has_feature(objc_arc)
|
|
52
|
-
# error This file must be compiled with MRC. Use -fno-objc-arc flag.
|
|
53
|
-
# endif
|
|
54
|
-
# include "MMKV_OSX.h"
|
|
55
|
-
#endif // MMKV_APPLE
|
|
56
|
-
|
|
57
|
-
using namespace std;
|
|
58
|
-
using namespace mmkv;
|
|
59
|
-
|
|
60
|
-
unordered_map<string, MMKV *> *g_instanceDic;
|
|
61
|
-
ThreadLock *g_instanceLock;
|
|
62
|
-
MMKVPath_t g_rootDir;
|
|
63
|
-
static mmkv::ErrorHandler g_errorHandler;
|
|
64
|
-
size_t mmkv::DEFAULT_MMAP_SIZE;
|
|
65
|
-
|
|
66
|
-
#ifndef MMKV_WIN32
|
|
67
|
-
constexpr auto SPECIAL_CHARACTER_DIRECTORY_NAME = "specialCharacter";
|
|
68
|
-
constexpr auto CRC_SUFFIX = ".crc";
|
|
69
|
-
#else
|
|
70
|
-
constexpr auto SPECIAL_CHARACTER_DIRECTORY_NAME = L"specialCharacter";
|
|
71
|
-
constexpr auto CRC_SUFFIX = L".crc";
|
|
72
|
-
#endif
|
|
73
|
-
|
|
74
|
-
MMKV_NAMESPACE_BEGIN
|
|
75
|
-
|
|
76
|
-
static MMKVPath_t encodeFilePath(const string &mmapID, const MMKVPath_t &rootDir);
|
|
77
|
-
bool endsWith(const MMKVPath_t &str, const MMKVPath_t &suffix);
|
|
78
|
-
MMKVPath_t filename(const MMKVPath_t &path);
|
|
79
|
-
|
|
80
|
-
#ifndef MMKV_ANDROID
|
|
81
|
-
MMKV::MMKV(const string &mmapID, MMKVMode mode, string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity)
|
|
82
|
-
: m_mmapID(mmapID)
|
|
83
|
-
, m_mode(mode)
|
|
84
|
-
, m_path(mappedKVPathWithID(m_mmapID, mode, rootPath))
|
|
85
|
-
, m_crcPath(crcPathWithID(m_mmapID, mode, rootPath))
|
|
86
|
-
, m_dic(nullptr)
|
|
87
|
-
, m_dicCrypt(nullptr)
|
|
88
|
-
, m_expectedCapacity(std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE)))
|
|
89
|
-
, m_file(new MemoryFile(m_path, m_expectedCapacity, isReadOnly()))
|
|
90
|
-
, m_metaFile(new MemoryFile(m_crcPath, 0, isReadOnly()))
|
|
91
|
-
, m_metaInfo(new MMKVMetaInfo())
|
|
92
|
-
, m_crypter(nullptr)
|
|
93
|
-
, m_lock(new ThreadLock())
|
|
94
|
-
, m_fileLock(new FileLock(m_metaFile->getFd()))
|
|
95
|
-
, m_sharedProcessLock(new InterProcessLock(m_fileLock, SharedLockType))
|
|
96
|
-
, m_exclusiveProcessLock(new InterProcessLock(m_fileLock, ExclusiveLockType))
|
|
97
|
-
{
|
|
98
|
-
m_actualSize = 0;
|
|
99
|
-
m_output = nullptr;
|
|
100
|
-
|
|
101
|
-
# ifndef MMKV_DISABLE_CRYPT
|
|
102
|
-
if (cryptKey && !cryptKey->empty()) {
|
|
103
|
-
m_dicCrypt = new MMKVMapCrypt();
|
|
104
|
-
m_crypter = new AESCrypt(cryptKey->data(), cryptKey->length());
|
|
105
|
-
} else {
|
|
106
|
-
m_dic = new MMKVMap();
|
|
107
|
-
}
|
|
108
|
-
# else
|
|
109
|
-
m_dic = new MMKVMap();
|
|
110
|
-
# endif
|
|
111
|
-
|
|
112
|
-
m_needLoadFromFile = true;
|
|
113
|
-
m_hasFullWriteback = false;
|
|
114
|
-
|
|
115
|
-
m_crcDigest = 0;
|
|
116
|
-
|
|
117
|
-
m_lock->initialize();
|
|
118
|
-
m_sharedProcessLock->m_enable = isMultiProcess();
|
|
119
|
-
m_exclusiveProcessLock->m_enable = isMultiProcess();
|
|
120
|
-
|
|
121
|
-
// sensitive zone
|
|
122
|
-
/*{
|
|
123
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
124
|
-
loadFromFile();
|
|
125
|
-
}*/
|
|
126
|
-
}
|
|
127
|
-
#endif
|
|
128
|
-
|
|
129
|
-
MMKV::~MMKV() {
|
|
130
|
-
clearMemoryCache();
|
|
131
|
-
|
|
132
|
-
delete m_dic;
|
|
133
|
-
#ifndef MMKV_DISABLE_CRYPT
|
|
134
|
-
delete m_dicCrypt;
|
|
135
|
-
delete m_crypter;
|
|
136
|
-
#endif
|
|
137
|
-
delete m_file;
|
|
138
|
-
delete m_metaFile;
|
|
139
|
-
delete m_metaInfo;
|
|
140
|
-
delete m_lock;
|
|
141
|
-
delete m_fileLock;
|
|
142
|
-
delete m_sharedProcessLock;
|
|
143
|
-
delete m_exclusiveProcessLock;
|
|
144
|
-
#ifdef MMKV_ANDROID
|
|
145
|
-
delete m_fileModeLock;
|
|
146
|
-
delete m_sharedProcessModeLock;
|
|
147
|
-
delete m_exclusiveProcessModeLock;
|
|
148
|
-
#endif
|
|
149
|
-
|
|
150
|
-
MMKVInfo("destruct [%s]", m_mmapID.c_str());
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
MMKV *MMKV::defaultMMKV(MMKVMode mode, string *cryptKey) {
|
|
154
|
-
#ifndef MMKV_ANDROID
|
|
155
|
-
return mmkvWithID(DEFAULT_MMAP_ID, mode, cryptKey);
|
|
156
|
-
#else
|
|
157
|
-
return mmkvWithID(DEFAULT_MMAP_ID, DEFAULT_MMAP_SIZE, mode, cryptKey);
|
|
158
|
-
#endif
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
void initialize() {
|
|
162
|
-
g_instanceDic = new unordered_map<string, MMKV *>;
|
|
163
|
-
g_instanceLock = new ThreadLock();
|
|
164
|
-
g_instanceLock->initialize();
|
|
165
|
-
|
|
166
|
-
mmkv::DEFAULT_MMAP_SIZE = mmkv::getPageSize();
|
|
167
|
-
MMKVInfo("version %s, page size %d, arch %s", MMKV_VERSION, DEFAULT_MMAP_SIZE, MMKV_ABI);
|
|
168
|
-
|
|
169
|
-
// get CPU status of ARMv8 extensions (CRC32, AES)
|
|
170
|
-
#if defined(__aarch64__) && defined(__linux__) && !defined (MMKV_OHOS)
|
|
171
|
-
auto hwcaps = getauxval(AT_HWCAP);
|
|
172
|
-
# ifndef MMKV_DISABLE_CRYPT
|
|
173
|
-
if (hwcaps & HWCAP_AES) {
|
|
174
|
-
openssl::AES_set_encrypt_key = openssl_aes_armv8_set_encrypt_key;
|
|
175
|
-
openssl::AES_set_decrypt_key = openssl_aes_armv8_set_decrypt_key;
|
|
176
|
-
openssl::AES_encrypt = openssl_aes_armv8_encrypt;
|
|
177
|
-
openssl::AES_decrypt = openssl_aes_armv8_decrypt;
|
|
178
|
-
MMKVInfo("armv8 AES instructions is supported");
|
|
179
|
-
} else {
|
|
180
|
-
MMKVInfo("armv8 AES instructions is not supported");
|
|
181
|
-
}
|
|
182
|
-
# endif // MMKV_DISABLE_CRYPT
|
|
183
|
-
# ifdef MMKV_USE_ARMV8_CRC32
|
|
184
|
-
if (hwcaps & HWCAP_CRC32) {
|
|
185
|
-
CRC32 = mmkv::armv8_crc32;
|
|
186
|
-
MMKVInfo("armv8 CRC32 instructions is supported");
|
|
187
|
-
} else {
|
|
188
|
-
MMKVInfo("armv8 CRC32 instructions is not supported");
|
|
189
|
-
}
|
|
190
|
-
# endif // MMKV_USE_ARMV8_CRC32
|
|
191
|
-
#endif // __aarch64__ && defined(__linux__) && !defined (MMKV_OHOS)
|
|
192
|
-
|
|
193
|
-
#if defined(MMKV_DEBUG) && !defined(MMKV_DISABLE_CRYPT)
|
|
194
|
-
// AESCrypt::testAESCrypt();
|
|
195
|
-
// KeyValueHolderCrypt::testAESToMMBuffer();
|
|
196
|
-
#endif
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
static ThreadOnceToken_t once_control = ThreadOnceUninitialized;
|
|
200
|
-
|
|
201
|
-
void MMKV::initializeMMKV(const MMKVPath_t &rootDir, MMKVLogLevel logLevel, mmkv::LogHandler handler) {
|
|
202
|
-
g_currentLogLevel = logLevel;
|
|
203
|
-
g_logHandler = handler;
|
|
204
|
-
|
|
205
|
-
ThreadLock::ThreadOnce(&once_control, initialize);
|
|
206
|
-
|
|
207
|
-
#ifdef MMKV_APPLE
|
|
208
|
-
// crc32 instruction requires A10 chip, aka iPhone 7 or iPad 6th generation
|
|
209
|
-
int device = 0, version = 0;
|
|
210
|
-
GetAppleMachineInfo(device, version);
|
|
211
|
-
# ifndef MMKV_IOS
|
|
212
|
-
MMKVInfo("Apple Device: %d, version: %d", device, version);
|
|
213
|
-
# else
|
|
214
|
-
// we have verified that on iOS 13+, the mlock() protection in background is no longer needed
|
|
215
|
-
// this may be true as well on iOS 12 or even iOS 11, sadly we can't verify that on WeChat
|
|
216
|
-
if (@available(iOS 13, *)) {
|
|
217
|
-
MLockPtr::isMLockPtrEnabled = false;
|
|
218
|
-
}
|
|
219
|
-
MMKVInfo("Apple Device: %d, version: %d, mlock enabled: %d", device, version, MLockPtr::isMLockPtrEnabled);
|
|
220
|
-
# endif
|
|
221
|
-
#endif
|
|
222
|
-
|
|
223
|
-
if (g_rootDir.empty()) {
|
|
224
|
-
g_rootDir = rootDir;
|
|
225
|
-
mkPath(g_rootDir);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
MMKVInfo("root dir: " MMKV_PATH_FORMAT, g_rootDir.c_str());
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const MMKVPath_t &MMKV::getRootDir() {
|
|
232
|
-
return g_rootDir;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
#ifndef MMKV_ANDROID
|
|
236
|
-
MMKV *MMKV::mmkvWithID(const string &mmapID, MMKVMode mode, string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity) {
|
|
237
|
-
|
|
238
|
-
if (mmapID.empty() || !g_instanceLock) {
|
|
239
|
-
return nullptr;
|
|
240
|
-
}
|
|
241
|
-
SCOPED_LOCK(g_instanceLock);
|
|
242
|
-
|
|
243
|
-
auto mmapKey = mmapedKVKey(mmapID, rootPath);
|
|
244
|
-
auto itr = g_instanceDic->find(mmapKey);
|
|
245
|
-
if (itr != g_instanceDic->end()) {
|
|
246
|
-
MMKV *kv = itr->second;
|
|
247
|
-
return kv;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (rootPath) {
|
|
251
|
-
MMKVPath_t specialPath = (*rootPath) + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
252
|
-
if (!isFileExist(specialPath)) {
|
|
253
|
-
mkPath(specialPath);
|
|
254
|
-
}
|
|
255
|
-
MMKVInfo("prepare to load %s (id %s) from rootPath %s", mmapID.c_str(), mmapKey.c_str(), rootPath->c_str());
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
auto kv = new MMKV(mmapID, mode, cryptKey, rootPath, expectedCapacity);
|
|
259
|
-
kv->m_mmapKey = mmapKey;
|
|
260
|
-
(*g_instanceDic)[mmapKey] = kv;
|
|
261
|
-
return kv;
|
|
262
|
-
}
|
|
263
|
-
#endif
|
|
264
|
-
|
|
265
|
-
void MMKV::onExit() {
|
|
266
|
-
if (!g_instanceLock) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
SCOPED_LOCK(g_instanceLock);
|
|
270
|
-
|
|
271
|
-
for (auto &pair : *g_instanceDic) {
|
|
272
|
-
MMKV *kv = pair.second;
|
|
273
|
-
kv->sync();
|
|
274
|
-
kv->clearMemoryCache();
|
|
275
|
-
delete kv;
|
|
276
|
-
pair.second = nullptr;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
delete g_instanceDic;
|
|
280
|
-
g_instanceDic = nullptr;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const string &MMKV::mmapID() const {
|
|
284
|
-
return m_mmapID;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
mmkv::ContentChangeHandler g_contentChangeHandler = nullptr;
|
|
288
|
-
|
|
289
|
-
void MMKV::notifyContentChanged() {
|
|
290
|
-
if (g_contentChangeHandler) {
|
|
291
|
-
g_contentChangeHandler(m_mmapID);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
void MMKV::checkContentChanged() {
|
|
296
|
-
SCOPED_LOCK(m_lock);
|
|
297
|
-
checkLoadData();
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
void MMKV::registerContentChangeHandler(mmkv::ContentChangeHandler handler) {
|
|
301
|
-
g_contentChangeHandler = handler;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
void MMKV::unRegisterContentChangeHandler() {
|
|
305
|
-
g_contentChangeHandler = nullptr;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
void MMKV::clearMemoryCache(bool keepSpace) {
|
|
309
|
-
SCOPED_LOCK(m_lock);
|
|
310
|
-
if (m_needLoadFromFile) {
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
MMKVInfo("clearMemoryCache [%s]", m_mmapID.c_str());
|
|
314
|
-
m_needLoadFromFile = true;
|
|
315
|
-
m_hasFullWriteback = false;
|
|
316
|
-
|
|
317
|
-
clearDictionary(m_dic);
|
|
318
|
-
#ifndef MMKV_DISABLE_CRYPT
|
|
319
|
-
clearDictionary(m_dicCrypt);
|
|
320
|
-
if (m_crypter) {
|
|
321
|
-
if (m_metaInfo->m_version >= MMKVVersionRandomIV) {
|
|
322
|
-
m_crypter->resetIV(m_metaInfo->m_vector, sizeof(m_metaInfo->m_vector));
|
|
323
|
-
} else {
|
|
324
|
-
m_crypter->resetIV();
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
#endif
|
|
328
|
-
|
|
329
|
-
delete m_output;
|
|
330
|
-
m_output = nullptr;
|
|
331
|
-
|
|
332
|
-
if (!keepSpace) {
|
|
333
|
-
m_file->clearMemoryCache();
|
|
334
|
-
}
|
|
335
|
-
// inter-process lock rely on MetaFile's fd, never close it
|
|
336
|
-
// m_metaFile->clearMemoryCache();
|
|
337
|
-
m_actualSize = 0;
|
|
338
|
-
m_metaInfo->m_crcDigest = 0;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
void MMKV::close() {
|
|
342
|
-
MMKVInfo("close [%s]", m_mmapID.c_str());
|
|
343
|
-
SCOPED_LOCK(g_instanceLock);
|
|
344
|
-
m_lock->lock();
|
|
345
|
-
|
|
346
|
-
#ifndef MMKV_ANDROID
|
|
347
|
-
auto itr = g_instanceDic->find(m_mmapKey);
|
|
348
|
-
#else
|
|
349
|
-
auto itr = g_instanceDic->find(m_mmapID);
|
|
350
|
-
#endif
|
|
351
|
-
if (itr != g_instanceDic->end()) {
|
|
352
|
-
g_instanceDic->erase(itr);
|
|
353
|
-
}
|
|
354
|
-
delete this;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
#ifndef MMKV_DISABLE_CRYPT
|
|
358
|
-
|
|
359
|
-
string MMKV::cryptKey() const {
|
|
360
|
-
SCOPED_LOCK(m_lock);
|
|
361
|
-
|
|
362
|
-
if (m_crypter) {
|
|
363
|
-
char key[AES_KEY_LEN];
|
|
364
|
-
m_crypter->getKey(key);
|
|
365
|
-
return {key, strnlen(key, AES_KEY_LEN)};
|
|
366
|
-
}
|
|
367
|
-
return "";
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
void MMKV::checkReSetCryptKey(const string *cryptKey) {
|
|
371
|
-
SCOPED_LOCK(m_lock);
|
|
372
|
-
|
|
373
|
-
if (m_crypter) {
|
|
374
|
-
if (cryptKey && !cryptKey->empty()) {
|
|
375
|
-
string oldKey = this->cryptKey();
|
|
376
|
-
if (oldKey != *cryptKey) {
|
|
377
|
-
MMKVInfo("setting new aes key");
|
|
378
|
-
delete m_crypter;
|
|
379
|
-
auto ptr = cryptKey->data();
|
|
380
|
-
m_crypter = new AESCrypt(ptr, cryptKey->length());
|
|
381
|
-
|
|
382
|
-
checkLoadData();
|
|
383
|
-
} else {
|
|
384
|
-
// nothing to do
|
|
385
|
-
}
|
|
386
|
-
} else {
|
|
387
|
-
MMKVInfo("reset aes key");
|
|
388
|
-
delete m_crypter;
|
|
389
|
-
m_crypter = nullptr;
|
|
390
|
-
|
|
391
|
-
checkLoadData();
|
|
392
|
-
}
|
|
393
|
-
} else {
|
|
394
|
-
if (cryptKey && !cryptKey->empty()) {
|
|
395
|
-
MMKVInfo("setting new aes key");
|
|
396
|
-
auto ptr = cryptKey->data();
|
|
397
|
-
m_crypter = new AESCrypt(ptr, cryptKey->length());
|
|
398
|
-
|
|
399
|
-
checkLoadData();
|
|
400
|
-
} else {
|
|
401
|
-
// nothing to do
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
#endif // MMKV_DISABLE_CRYPT
|
|
407
|
-
|
|
408
|
-
bool MMKV::isFileValid() {
|
|
409
|
-
return m_file->isFileValid();
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// crc
|
|
413
|
-
|
|
414
|
-
// assuming m_file is valid
|
|
415
|
-
bool MMKV::checkFileCRCValid(size_t actualSize, uint32_t crcDigest) {
|
|
416
|
-
auto ptr = (uint8_t *) m_file->getMemory();
|
|
417
|
-
if (ptr) {
|
|
418
|
-
m_crcDigest = (uint32_t) CRC32(0, (const uint8_t *) ptr + Fixed32Size, (uint32_t) actualSize);
|
|
419
|
-
|
|
420
|
-
if (m_crcDigest == crcDigest) {
|
|
421
|
-
return true;
|
|
422
|
-
}
|
|
423
|
-
MMKVError("check crc [%s] fail, crc32:%u, m_crcDigest:%u", m_mmapID.c_str(), crcDigest, m_crcDigest);
|
|
424
|
-
}
|
|
425
|
-
return false;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
void MMKV::recalculateCRCDigestWithIV(const void *iv) {
|
|
429
|
-
auto ptr = (const uint8_t *) m_file->getMemory();
|
|
430
|
-
if (ptr) {
|
|
431
|
-
m_crcDigest = 0;
|
|
432
|
-
m_crcDigest = (uint32_t) CRC32(0, ptr + Fixed32Size, (uint32_t) m_actualSize);
|
|
433
|
-
writeActualSize(m_actualSize, m_crcDigest, iv, IncreaseSequence);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
void MMKV::recalculateCRCDigestOnly() {
|
|
438
|
-
auto ptr = (const uint8_t *) m_file->getMemory();
|
|
439
|
-
if (ptr) {
|
|
440
|
-
m_crcDigest = 0;
|
|
441
|
-
m_crcDigest = (uint32_t) CRC32(0, ptr + Fixed32Size, (uint32_t) m_actualSize);
|
|
442
|
-
writeActualSize(m_actualSize, m_crcDigest, nullptr, KeepSequence);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
void MMKV::updateCRCDigest(const uint8_t *ptr, size_t length) {
|
|
447
|
-
if (ptr == nullptr) {
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
m_crcDigest = (uint32_t) CRC32(m_crcDigest, ptr, (uint32_t) length);
|
|
451
|
-
|
|
452
|
-
writeActualSize(m_actualSize, m_crcDigest, nullptr, KeepSequence);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// set & get
|
|
456
|
-
|
|
457
|
-
bool MMKV::set(bool value, MMKVKey_t key) {
|
|
458
|
-
return set(value, key, m_expiredInSeconds);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
bool MMKV::set(bool value, MMKVKey_t key, uint32_t expireDuration) {
|
|
462
|
-
if (isKeyEmpty(key)) {
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbBoolSize() : pbBoolSize();
|
|
466
|
-
MMBuffer data(size);
|
|
467
|
-
CodedOutputData output(data.getPtr(), size);
|
|
468
|
-
output.writeBool(value);
|
|
469
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
470
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
471
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
472
|
-
} else {
|
|
473
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return setDataForKey(std::move(data), key);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
bool MMKV::set(int32_t value, MMKVKey_t key) {
|
|
480
|
-
return set(value, key, m_expiredInSeconds);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
bool MMKV::set(int32_t value, MMKVKey_t key, uint32_t expireDuration) {
|
|
484
|
-
if (isKeyEmpty(key)) {
|
|
485
|
-
return false;
|
|
486
|
-
}
|
|
487
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbInt32Size(value) : pbInt32Size(value);
|
|
488
|
-
MMBuffer data(size);
|
|
489
|
-
CodedOutputData output(data.getPtr(), size);
|
|
490
|
-
output.writeInt32(value);
|
|
491
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
492
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
493
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
494
|
-
} else {
|
|
495
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return setDataForKey(std::move(data), key);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
bool MMKV::set(uint32_t value, MMKVKey_t key) {
|
|
502
|
-
return set(value, key, m_expiredInSeconds);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
bool MMKV::set(uint32_t value, MMKVKey_t key, uint32_t expireDuration) {
|
|
506
|
-
if (isKeyEmpty(key)) {
|
|
507
|
-
return false;
|
|
508
|
-
}
|
|
509
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbUInt32Size(value) : pbUInt32Size(value);
|
|
510
|
-
MMBuffer data(size);
|
|
511
|
-
CodedOutputData output(data.getPtr(), size);
|
|
512
|
-
output.writeUInt32(value);
|
|
513
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
514
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
515
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
516
|
-
} else {
|
|
517
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
return setDataForKey(std::move(data), key);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
bool MMKV::set(int64_t value, MMKVKey_t key) {
|
|
524
|
-
return set(value, key, m_expiredInSeconds);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
bool MMKV::set(int64_t value, MMKVKey_t key, uint32_t expireDuration) {
|
|
528
|
-
if (isKeyEmpty(key)) {
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
531
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbInt64Size(value) : pbInt64Size(value);
|
|
532
|
-
MMBuffer data(size);
|
|
533
|
-
CodedOutputData output(data.getPtr(), size);
|
|
534
|
-
output.writeInt64(value);
|
|
535
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
536
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
537
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
538
|
-
} else {
|
|
539
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
return setDataForKey(std::move(data), key);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
bool MMKV::set(uint64_t value, MMKVKey_t key) {
|
|
546
|
-
return set(value, key, m_expiredInSeconds);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
bool MMKV::set(uint64_t value, MMKVKey_t key, uint32_t expireDuration) {
|
|
550
|
-
if (isKeyEmpty(key)) {
|
|
551
|
-
return false;
|
|
552
|
-
}
|
|
553
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbUInt64Size(value) : pbUInt64Size(value);
|
|
554
|
-
MMBuffer data(size);
|
|
555
|
-
CodedOutputData output(data.getPtr(), size);
|
|
556
|
-
output.writeUInt64(value);
|
|
557
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
558
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
559
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
560
|
-
} else {
|
|
561
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
return setDataForKey(std::move(data), key);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
bool MMKV::set(float value, MMKVKey_t key) {
|
|
568
|
-
return set(value, key, m_expiredInSeconds);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
bool MMKV::set(float value, MMKVKey_t key, uint32_t expireDuration) {
|
|
572
|
-
if (isKeyEmpty(key)) {
|
|
573
|
-
return false;
|
|
574
|
-
}
|
|
575
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbFloatSize() : pbFloatSize();
|
|
576
|
-
MMBuffer data(size);
|
|
577
|
-
CodedOutputData output(data.getPtr(), size);
|
|
578
|
-
output.writeFloat(value);
|
|
579
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
580
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
581
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
582
|
-
} else {
|
|
583
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return setDataForKey(std::move(data), key);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
bool MMKV::set(double value, MMKVKey_t key) {
|
|
590
|
-
return set(value, key, m_expiredInSeconds);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
bool MMKV::set(double value, MMKVKey_t key, uint32_t expireDuration) {
|
|
594
|
-
if (isKeyEmpty(key)) {
|
|
595
|
-
return false;
|
|
596
|
-
}
|
|
597
|
-
size_t size = mmkv_unlikely(m_enableKeyExpire) ? Fixed32Size + pbDoubleSize() : pbDoubleSize();
|
|
598
|
-
MMBuffer data(size);
|
|
599
|
-
CodedOutputData output(data.getPtr(), size);
|
|
600
|
-
output.writeDouble(value);
|
|
601
|
-
if (mmkv_unlikely(m_enableKeyExpire)) {
|
|
602
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
603
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
604
|
-
} else {
|
|
605
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
return setDataForKey(std::move(data), key);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
#ifndef MMKV_APPLE
|
|
612
|
-
|
|
613
|
-
bool MMKV::setDataForKey(mmkv::MMBuffer &&data, MMKV::MMKVKey_t key, uint32_t expireDuration) {
|
|
614
|
-
if (mmkv_likely(!m_enableKeyExpire)) {
|
|
615
|
-
assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
|
|
616
|
-
return setDataForKey(std::move(data), key, true);
|
|
617
|
-
} else {
|
|
618
|
-
auto tmp = MMBuffer(pbMMBufferSize(data) + Fixed32Size);
|
|
619
|
-
CodedOutputData output(tmp.getPtr(), tmp.length());
|
|
620
|
-
output.writeData(data);
|
|
621
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
622
|
-
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
623
|
-
return setDataForKey(std::move(tmp), key);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
bool MMKV::set(const char *value, MMKVKey_t key) {
|
|
628
|
-
return set(value, key, m_expiredInSeconds);
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
bool MMKV::set(const char *value, MMKVKey_t key, uint32_t expireDuration) {
|
|
632
|
-
if (!value) {
|
|
633
|
-
removeValueForKey(key);
|
|
634
|
-
return true;
|
|
635
|
-
}
|
|
636
|
-
return setDataForKey(MMBuffer((void *) value, strlen(value), MMBufferNoCopy), key, expireDuration);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
bool MMKV::set(const string &value, MMKVKey_t key) {
|
|
640
|
-
return set(value, key, m_expiredInSeconds);
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
bool MMKV::set(const string &value, MMKVKey_t key, uint32_t expireDuration) {
|
|
644
|
-
if (isKeyEmpty(key)) {
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
return setDataForKey(MMBuffer((void *) value.data(), value.length(), MMBufferNoCopy), key, expireDuration);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
bool MMKV::set(string_view value, MMKVKey_t key) {
|
|
651
|
-
return set(value, key, m_expiredInSeconds);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
bool MMKV::set(string_view value, MMKVKey_t key, uint32_t expireDuration) {
|
|
655
|
-
if (isKeyEmpty(key)) {
|
|
656
|
-
return false;
|
|
657
|
-
}
|
|
658
|
-
return setDataForKey(MMBuffer((void *) value.data(), value.length(), MMBufferNoCopy), key, expireDuration);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
bool MMKV::set(const MMBuffer &value, MMKVKey_t key) {
|
|
662
|
-
return set(value, key, m_expiredInSeconds);
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
bool MMKV::set(const MMBuffer &value, MMKVKey_t key, uint32_t expireDuration) {
|
|
666
|
-
if (isKeyEmpty(key)) {
|
|
667
|
-
return false;
|
|
668
|
-
}
|
|
669
|
-
return setDataForKey(MMBuffer(value.getPtr(), value.length(), MMBufferNoCopy), key, expireDuration);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
bool MMKV::set(const vector<string> &value, MMKVKey_t key) {
|
|
673
|
-
return set(value, key, m_expiredInSeconds);
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
bool MMKV::set(const vector<string> &v, MMKVKey_t key, uint32_t expireDuration) {
|
|
677
|
-
if (isKeyEmpty(key)) {
|
|
678
|
-
return false;
|
|
679
|
-
}
|
|
680
|
-
#ifdef MMKV_HAS_CPP20
|
|
681
|
-
auto data = MiniPBCoder::encodeDataWithObject(std::span(v));
|
|
682
|
-
#else
|
|
683
|
-
auto data = MiniPBCoder::encodeDataWithObject(v);
|
|
684
|
-
#endif
|
|
685
|
-
if (mmkv_unlikely(m_enableKeyExpire) && data.length() > 0) {
|
|
686
|
-
auto tmp = MMBuffer(data.length() + Fixed32Size);
|
|
687
|
-
auto ptr = (uint8_t *) tmp.getPtr();
|
|
688
|
-
memcpy(ptr, data.getPtr(), data.length());
|
|
689
|
-
auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
|
|
690
|
-
memcpy(ptr + data.length(), &time, Fixed32Size);
|
|
691
|
-
data = std::move(tmp);
|
|
692
|
-
}
|
|
693
|
-
return setDataForKey(std::move(data), key);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
bool MMKV::getString(MMKVKey_t key, string &result, bool inplaceModification) {
|
|
697
|
-
if (isKeyEmpty(key)) {
|
|
698
|
-
return false;
|
|
699
|
-
}
|
|
700
|
-
SCOPED_LOCK(m_lock);
|
|
701
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
702
|
-
auto data = getDataForKey(key);
|
|
703
|
-
if (data.length() > 0) {
|
|
704
|
-
try {
|
|
705
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
706
|
-
if (inplaceModification) {
|
|
707
|
-
input.readString(result);
|
|
708
|
-
} else {
|
|
709
|
-
result = input.readString();
|
|
710
|
-
}
|
|
711
|
-
return true;
|
|
712
|
-
} catch (std::exception &exception) {
|
|
713
|
-
MMKVError("%s", exception.what());
|
|
714
|
-
} catch (...) {
|
|
715
|
-
MMKVError("decode fail");
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
return false;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
bool MMKV::getBytes(MMKVKey_t key, mmkv::MMBuffer &result) {
|
|
722
|
-
if (isKeyEmpty(key)) {
|
|
723
|
-
return false;
|
|
724
|
-
}
|
|
725
|
-
SCOPED_LOCK(m_lock);
|
|
726
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
727
|
-
auto data = getDataForKey(key);
|
|
728
|
-
if (data.length() > 0) {
|
|
729
|
-
try {
|
|
730
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
731
|
-
result = input.readData();
|
|
732
|
-
return true;
|
|
733
|
-
} catch (std::exception &exception) {
|
|
734
|
-
MMKVError("%s", exception.what());
|
|
735
|
-
} catch (...) {
|
|
736
|
-
MMKVError("decode fail");
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
return false;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
MMBuffer MMKV::getBytes(MMKVKey_t key) {
|
|
743
|
-
if (isKeyEmpty(key)) {
|
|
744
|
-
return MMBuffer();
|
|
745
|
-
}
|
|
746
|
-
SCOPED_LOCK(m_lock);
|
|
747
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
748
|
-
auto data = getDataForKey(key);
|
|
749
|
-
if (data.length() > 0) {
|
|
750
|
-
try {
|
|
751
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
752
|
-
return input.readData();
|
|
753
|
-
} catch (std::exception &exception) {
|
|
754
|
-
MMKVError("%s", exception.what());
|
|
755
|
-
} catch (...) {
|
|
756
|
-
MMKVError("decode fail");
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
return MMBuffer();
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
bool MMKV::getVector(MMKVKey_t key, vector<string> &result) {
|
|
763
|
-
if (isKeyEmpty(key)) {
|
|
764
|
-
return false;
|
|
765
|
-
}
|
|
766
|
-
SCOPED_LOCK(m_lock);
|
|
767
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
768
|
-
auto data = getDataForKey(key);
|
|
769
|
-
if (data.length() > 0) {
|
|
770
|
-
try {
|
|
771
|
-
result = MiniPBCoder::decodeVector(data);
|
|
772
|
-
return true;
|
|
773
|
-
} catch (std::exception &exception) {
|
|
774
|
-
MMKVError("%s", exception.what());
|
|
775
|
-
} catch (...) {
|
|
776
|
-
MMKVError("decode fail");
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
return false;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
void MMKV::shared_lock() {
|
|
783
|
-
m_lock->lock();
|
|
784
|
-
m_sharedProcessLock->lock();
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
void MMKV::shared_unlock() {
|
|
788
|
-
m_sharedProcessLock->lock();
|
|
789
|
-
m_lock->lock();
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
#endif // MMKV_APPLE
|
|
793
|
-
|
|
794
|
-
bool MMKV::getBool(MMKVKey_t key, bool defaultValue, bool *hasValue) {
|
|
795
|
-
if (isKeyEmpty(key)) {
|
|
796
|
-
if (hasValue != nullptr) {
|
|
797
|
-
*hasValue = false;
|
|
798
|
-
}
|
|
799
|
-
return defaultValue;
|
|
800
|
-
}
|
|
801
|
-
SCOPED_LOCK(m_lock);
|
|
802
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
803
|
-
auto data = getDataForKey(key);
|
|
804
|
-
if (data.length() > 0) {
|
|
805
|
-
try {
|
|
806
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
807
|
-
if (hasValue != nullptr) {
|
|
808
|
-
*hasValue = true;
|
|
809
|
-
}
|
|
810
|
-
return input.readBool();
|
|
811
|
-
} catch (std::exception &exception) {
|
|
812
|
-
MMKVError("%s", exception.what());
|
|
813
|
-
} catch (...) {
|
|
814
|
-
MMKVError("decode fail");
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
if (hasValue != nullptr) {
|
|
818
|
-
*hasValue = false;
|
|
819
|
-
}
|
|
820
|
-
return defaultValue;
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
int32_t MMKV::getInt32(MMKVKey_t key, int32_t defaultValue, bool *hasValue) {
|
|
824
|
-
if (isKeyEmpty(key)) {
|
|
825
|
-
if (hasValue != nullptr) {
|
|
826
|
-
*hasValue = false;
|
|
827
|
-
}
|
|
828
|
-
return defaultValue;
|
|
829
|
-
}
|
|
830
|
-
SCOPED_LOCK(m_lock);
|
|
831
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
832
|
-
auto data = getDataForKey(key);
|
|
833
|
-
if (data.length() > 0) {
|
|
834
|
-
try {
|
|
835
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
836
|
-
if (hasValue != nullptr) {
|
|
837
|
-
*hasValue = true;
|
|
838
|
-
}
|
|
839
|
-
return input.readInt32();
|
|
840
|
-
} catch (std::exception &exception) {
|
|
841
|
-
MMKVError("%s", exception.what());
|
|
842
|
-
} catch (...) {
|
|
843
|
-
MMKVError("decode fail");
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
if (hasValue != nullptr) {
|
|
847
|
-
*hasValue = false;
|
|
848
|
-
}
|
|
849
|
-
return defaultValue;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
uint32_t MMKV::getUInt32(MMKVKey_t key, uint32_t defaultValue, bool *hasValue) {
|
|
853
|
-
if (isKeyEmpty(key)) {
|
|
854
|
-
if (hasValue != nullptr) {
|
|
855
|
-
*hasValue = false;
|
|
856
|
-
}
|
|
857
|
-
return defaultValue;
|
|
858
|
-
}
|
|
859
|
-
SCOPED_LOCK(m_lock);
|
|
860
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
861
|
-
auto data = getDataForKey(key);
|
|
862
|
-
if (data.length() > 0) {
|
|
863
|
-
try {
|
|
864
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
865
|
-
if (hasValue != nullptr) {
|
|
866
|
-
*hasValue = true;
|
|
867
|
-
}
|
|
868
|
-
return input.readUInt32();
|
|
869
|
-
} catch (std::exception &exception) {
|
|
870
|
-
MMKVError("%s", exception.what());
|
|
871
|
-
} catch (...) {
|
|
872
|
-
MMKVError("decode fail");
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
if (hasValue != nullptr) {
|
|
876
|
-
*hasValue = false;
|
|
877
|
-
}
|
|
878
|
-
return defaultValue;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
int64_t MMKV::getInt64(MMKVKey_t key, int64_t defaultValue, bool *hasValue) {
|
|
882
|
-
if (isKeyEmpty(key)) {
|
|
883
|
-
if (hasValue != nullptr) {
|
|
884
|
-
*hasValue = false;
|
|
885
|
-
}
|
|
886
|
-
return defaultValue;
|
|
887
|
-
}
|
|
888
|
-
SCOPED_LOCK(m_lock);
|
|
889
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
890
|
-
auto data = getDataForKey(key);
|
|
891
|
-
if (data.length() > 0) {
|
|
892
|
-
try {
|
|
893
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
894
|
-
if (hasValue != nullptr) {
|
|
895
|
-
*hasValue = true;
|
|
896
|
-
}
|
|
897
|
-
return input.readInt64();
|
|
898
|
-
} catch (std::exception &exception) {
|
|
899
|
-
MMKVError("%s", exception.what());
|
|
900
|
-
} catch (...) {
|
|
901
|
-
MMKVError("decode fail");
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (hasValue != nullptr) {
|
|
905
|
-
*hasValue = false;
|
|
906
|
-
}
|
|
907
|
-
return defaultValue;
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
uint64_t MMKV::getUInt64(MMKVKey_t key, uint64_t defaultValue, bool *hasValue) {
|
|
911
|
-
if (isKeyEmpty(key)) {
|
|
912
|
-
if (hasValue != nullptr) {
|
|
913
|
-
*hasValue = false;
|
|
914
|
-
}
|
|
915
|
-
return defaultValue;
|
|
916
|
-
}
|
|
917
|
-
SCOPED_LOCK(m_lock);
|
|
918
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
919
|
-
auto data = getDataForKey(key);
|
|
920
|
-
if (data.length() > 0) {
|
|
921
|
-
try {
|
|
922
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
923
|
-
if (hasValue != nullptr) {
|
|
924
|
-
*hasValue = true;
|
|
925
|
-
}
|
|
926
|
-
return input.readUInt64();
|
|
927
|
-
} catch (std::exception &exception) {
|
|
928
|
-
MMKVError("%s", exception.what());
|
|
929
|
-
} catch (...) {
|
|
930
|
-
MMKVError("decode fail");
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
if (hasValue != nullptr) {
|
|
934
|
-
*hasValue = false;
|
|
935
|
-
}
|
|
936
|
-
return defaultValue;
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
float MMKV::getFloat(MMKVKey_t key, float defaultValue, bool *hasValue) {
|
|
940
|
-
if (isKeyEmpty(key)) {
|
|
941
|
-
if (hasValue != nullptr) {
|
|
942
|
-
*hasValue = false;
|
|
943
|
-
}
|
|
944
|
-
return defaultValue;
|
|
945
|
-
}
|
|
946
|
-
SCOPED_LOCK(m_lock);
|
|
947
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
948
|
-
auto data = getDataForKey(key);
|
|
949
|
-
if (data.length() > 0) {
|
|
950
|
-
try {
|
|
951
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
952
|
-
if (hasValue != nullptr) {
|
|
953
|
-
*hasValue = true;
|
|
954
|
-
}
|
|
955
|
-
return input.readFloat();
|
|
956
|
-
} catch (std::exception &exception) {
|
|
957
|
-
MMKVError("%s", exception.what());
|
|
958
|
-
} catch (...) {
|
|
959
|
-
MMKVError("decode fail");
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
if (hasValue != nullptr) {
|
|
963
|
-
*hasValue = false;
|
|
964
|
-
}
|
|
965
|
-
return defaultValue;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
double MMKV::getDouble(MMKVKey_t key, double defaultValue, bool *hasValue) {
|
|
969
|
-
if (isKeyEmpty(key)) {
|
|
970
|
-
if (hasValue != nullptr) {
|
|
971
|
-
*hasValue = false;
|
|
972
|
-
}
|
|
973
|
-
return defaultValue;
|
|
974
|
-
}
|
|
975
|
-
SCOPED_LOCK(m_lock);
|
|
976
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
977
|
-
auto data = getDataForKey(key);
|
|
978
|
-
if (data.length() > 0) {
|
|
979
|
-
try {
|
|
980
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
981
|
-
if (hasValue != nullptr) {
|
|
982
|
-
*hasValue = true;
|
|
983
|
-
}
|
|
984
|
-
return input.readDouble();
|
|
985
|
-
} catch (std::exception &exception) {
|
|
986
|
-
MMKVError("%s", exception.what());
|
|
987
|
-
} catch (...) {
|
|
988
|
-
MMKVError("decode fail");
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
if (hasValue != nullptr) {
|
|
992
|
-
*hasValue = false;
|
|
993
|
-
}
|
|
994
|
-
return defaultValue;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
size_t MMKV::getValueSize(MMKVKey_t key, bool actualSize) {
|
|
998
|
-
if (isKeyEmpty(key)) {
|
|
999
|
-
return 0;
|
|
1000
|
-
}
|
|
1001
|
-
SCOPED_LOCK(m_lock);
|
|
1002
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
1003
|
-
auto data = getDataForKey(key);
|
|
1004
|
-
if (actualSize) {
|
|
1005
|
-
try {
|
|
1006
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
1007
|
-
auto length = input.readInt32();
|
|
1008
|
-
if (length >= 0) {
|
|
1009
|
-
auto s_length = static_cast<size_t>(length);
|
|
1010
|
-
if (pbRawVarint32Size(length) + s_length == data.length()) {
|
|
1011
|
-
return s_length;
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
} catch (std::exception &exception) {
|
|
1015
|
-
MMKVError("%s", exception.what());
|
|
1016
|
-
} catch (...) {
|
|
1017
|
-
MMKVError("decode fail");
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
return data.length();
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
int32_t MMKV::writeValueToBuffer(MMKVKey_t key, void *ptr, int32_t size) {
|
|
1024
|
-
if (isKeyEmpty(key) || size < 0) {
|
|
1025
|
-
return -1;
|
|
1026
|
-
}
|
|
1027
|
-
auto s_size = static_cast<size_t>(size);
|
|
1028
|
-
|
|
1029
|
-
SCOPED_LOCK(m_lock);
|
|
1030
|
-
SCOPED_LOCK(m_sharedProcessLock);
|
|
1031
|
-
auto data = getDataForKey(key);
|
|
1032
|
-
try {
|
|
1033
|
-
CodedInputData input(data.getPtr(), data.length());
|
|
1034
|
-
auto length = input.readInt32();
|
|
1035
|
-
auto offset = pbRawVarint32Size(length);
|
|
1036
|
-
if (length >= 0) {
|
|
1037
|
-
auto s_length = static_cast<size_t>(length);
|
|
1038
|
-
if (offset + s_length == data.length()) {
|
|
1039
|
-
if (s_length <= s_size) {
|
|
1040
|
-
memcpy(ptr, (uint8_t *) data.getPtr() + offset, s_length);
|
|
1041
|
-
return length;
|
|
1042
|
-
}
|
|
1043
|
-
} else {
|
|
1044
|
-
if (data.length() <= s_size) {
|
|
1045
|
-
memcpy(ptr, data.getPtr(), data.length());
|
|
1046
|
-
return static_cast<int32_t>(data.length());
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
} catch (std::exception &exception) {
|
|
1051
|
-
MMKVError("%s", exception.what());
|
|
1052
|
-
} catch (...) {
|
|
1053
|
-
MMKVError("encode fail");
|
|
1054
|
-
}
|
|
1055
|
-
return -1;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
// enumerate
|
|
1059
|
-
|
|
1060
|
-
bool MMKV::containsKey(MMKVKey_t key) {
|
|
1061
|
-
SCOPED_LOCK(m_lock);
|
|
1062
|
-
checkLoadData();
|
|
1063
|
-
|
|
1064
|
-
if (mmkv_likely(!m_enableKeyExpire)) {
|
|
1065
|
-
if (m_crypter) {
|
|
1066
|
-
return m_dicCrypt->find(key) != m_dicCrypt->end();
|
|
1067
|
-
} else {
|
|
1068
|
-
return m_dic->find(key) != m_dic->end();
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
auto raw = getDataWithoutMTimeForKey(key);
|
|
1072
|
-
return raw.length() != 0;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
size_t MMKV::count(bool filterExpire) {
|
|
1076
|
-
SCOPED_LOCK(m_lock);
|
|
1077
|
-
checkLoadData();
|
|
1078
|
-
|
|
1079
|
-
if (mmkv_unlikely(filterExpire && m_enableKeyExpire)) {
|
|
1080
|
-
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
1081
|
-
fullWriteback(nullptr, true);
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
if (m_crypter) {
|
|
1085
|
-
return m_dicCrypt->size();
|
|
1086
|
-
} else {
|
|
1087
|
-
return m_dic->size();
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
size_t MMKV::totalSize() {
|
|
1092
|
-
SCOPED_LOCK(m_lock);
|
|
1093
|
-
checkLoadData();
|
|
1094
|
-
return m_file->getFileSize();
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
size_t MMKV::actualSize() {
|
|
1098
|
-
SCOPED_LOCK(m_lock);
|
|
1099
|
-
checkLoadData();
|
|
1100
|
-
return m_actualSize;
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
bool MMKV::removeValueForKey(MMKVKey_t key) {
|
|
1104
|
-
if (isKeyEmpty(key)) {
|
|
1105
|
-
return false;
|
|
1106
|
-
}
|
|
1107
|
-
if (isReadOnly()) {
|
|
1108
|
-
MMKVWarning("[%s] file readonly", m_mmapID.c_str());
|
|
1109
|
-
return false;
|
|
1110
|
-
}
|
|
1111
|
-
SCOPED_LOCK(m_lock);
|
|
1112
|
-
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
1113
|
-
checkLoadData();
|
|
1114
|
-
|
|
1115
|
-
return removeDataForKey(key);
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
#ifndef MMKV_APPLE
|
|
1119
|
-
|
|
1120
|
-
vector<string> MMKV::allKeys(bool filterExpire) {
|
|
1121
|
-
SCOPED_LOCK(m_lock);
|
|
1122
|
-
checkLoadData();
|
|
1123
|
-
|
|
1124
|
-
if (mmkv_unlikely(filterExpire && m_enableKeyExpire)) {
|
|
1125
|
-
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
1126
|
-
fullWriteback(nullptr, true);
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
vector<string> keys;
|
|
1130
|
-
if (m_crypter) {
|
|
1131
|
-
for (const auto &itr : *m_dicCrypt) {
|
|
1132
|
-
keys.push_back(itr.first);
|
|
1133
|
-
}
|
|
1134
|
-
} else {
|
|
1135
|
-
for (const auto &itr : *m_dic) {
|
|
1136
|
-
keys.push_back(itr.first);
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
return keys;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
bool MMKV::removeValuesForKeys(const vector<string> &arrKeys) {
|
|
1143
|
-
if (isReadOnly()) {
|
|
1144
|
-
MMKVWarning("[%s] file readonly", m_mmapID.c_str());
|
|
1145
|
-
return false;
|
|
1146
|
-
}
|
|
1147
|
-
if (arrKeys.empty()) {
|
|
1148
|
-
return true;
|
|
1149
|
-
}
|
|
1150
|
-
if (arrKeys.size() == 1) {
|
|
1151
|
-
return removeValueForKey(arrKeys[0]);
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
SCOPED_LOCK(m_lock);
|
|
1155
|
-
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
1156
|
-
checkLoadData();
|
|
1157
|
-
|
|
1158
|
-
size_t deleteCount = 0;
|
|
1159
|
-
if (m_crypter) {
|
|
1160
|
-
for (const auto &key : arrKeys) {
|
|
1161
|
-
auto itr = m_dicCrypt->find(key);
|
|
1162
|
-
if (itr != m_dicCrypt->end()) {
|
|
1163
|
-
m_dicCrypt->erase(itr);
|
|
1164
|
-
deleteCount++;
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
} else {
|
|
1168
|
-
for (const auto &key : arrKeys) {
|
|
1169
|
-
auto itr = m_dic->find(key);
|
|
1170
|
-
if (itr != m_dic->end()) {
|
|
1171
|
-
m_dic->erase(itr);
|
|
1172
|
-
deleteCount++;
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
if (deleteCount > 0) {
|
|
1177
|
-
m_hasFullWriteback = false;
|
|
1178
|
-
|
|
1179
|
-
return fullWriteback();
|
|
1180
|
-
}
|
|
1181
|
-
return true;
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
#endif // MMKV_APPLE
|
|
1185
|
-
|
|
1186
|
-
// file
|
|
1187
|
-
|
|
1188
|
-
void MMKV::sync(SyncFlag flag) {
|
|
1189
|
-
MMKVInfo("MMKV::sync, SyncFlag = %d", flag);
|
|
1190
|
-
SCOPED_LOCK(m_lock);
|
|
1191
|
-
if (m_needLoadFromFile || !isFileValid()) {
|
|
1192
|
-
return;
|
|
1193
|
-
}
|
|
1194
|
-
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
1195
|
-
|
|
1196
|
-
m_file->msync(flag);
|
|
1197
|
-
m_metaFile->msync(flag);
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
void MMKV::lock() {
|
|
1201
|
-
SCOPED_LOCK(m_lock);
|
|
1202
|
-
m_exclusiveProcessLock->lock();
|
|
1203
|
-
}
|
|
1204
|
-
void MMKV::unlock() {
|
|
1205
|
-
SCOPED_LOCK(m_lock);
|
|
1206
|
-
m_exclusiveProcessLock->unlock();
|
|
1207
|
-
}
|
|
1208
|
-
bool MMKV::try_lock() {
|
|
1209
|
-
SCOPED_LOCK(m_lock);
|
|
1210
|
-
return m_exclusiveProcessLock->try_lock();
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
#ifndef MMKV_WIN32
|
|
1214
|
-
void MMKV::lock_thread() {
|
|
1215
|
-
m_lock->lock();
|
|
1216
|
-
}
|
|
1217
|
-
void MMKV::unlock_thread() {
|
|
1218
|
-
m_lock->unlock();
|
|
1219
|
-
}
|
|
1220
|
-
bool MMKV::try_lock_thread() {
|
|
1221
|
-
return m_lock->try_lock();
|
|
1222
|
-
}
|
|
1223
|
-
#endif
|
|
1224
|
-
|
|
1225
|
-
// backup
|
|
1226
|
-
|
|
1227
|
-
static bool backupOneToDirectoryByFilePath(const string &mmapKey, const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
|
|
1228
|
-
File crcFile(srcPath, OpenFlag::ReadOnly);
|
|
1229
|
-
if (!crcFile.isFileValid()) {
|
|
1230
|
-
return false;
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
bool ret;
|
|
1234
|
-
{
|
|
1235
|
-
#ifdef MMKV_WIN32
|
|
1236
|
-
MMKVInfo("backup one mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1237
|
-
#else
|
|
1238
|
-
MMKVInfo("backup one mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1239
|
-
#endif
|
|
1240
|
-
FileLock fileLock(crcFile.getFd());
|
|
1241
|
-
InterProcessLock lock(&fileLock, SharedLockType);
|
|
1242
|
-
SCOPED_LOCK(&lock);
|
|
1243
|
-
|
|
1244
|
-
ret = copyFile(srcPath, dstPath);
|
|
1245
|
-
if (ret) {
|
|
1246
|
-
auto srcCRCPath = srcPath + CRC_SUFFIX;
|
|
1247
|
-
auto dstCRCPath = dstPath + CRC_SUFFIX;
|
|
1248
|
-
ret = copyFile(srcCRCPath, dstCRCPath);
|
|
1249
|
-
}
|
|
1250
|
-
MMKVInfo("finish backup one mmkv[%s]", mmapKey.c_str());
|
|
1251
|
-
}
|
|
1252
|
-
return ret;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
bool MMKV::backupOneToDirectory(const string &mmapKey, const MMKVPath_t &dstPath, const MMKVPath_t &srcPath, bool compareFullPath) {
|
|
1256
|
-
if (!g_instanceLock) {
|
|
1257
|
-
return false;
|
|
1258
|
-
}
|
|
1259
|
-
// we have to lock the creation of MMKV instance, regardless of in cache or not
|
|
1260
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1261
|
-
MMKV *kv = nullptr;
|
|
1262
|
-
if (!compareFullPath) {
|
|
1263
|
-
auto itr = g_instanceDic->find(mmapKey);
|
|
1264
|
-
if (itr != g_instanceDic->end()) {
|
|
1265
|
-
kv = itr->second;
|
|
1266
|
-
}
|
|
1267
|
-
} else {
|
|
1268
|
-
// mmapKey is actually filename, we can't simply call find()
|
|
1269
|
-
for (auto &pair : *g_instanceDic) {
|
|
1270
|
-
if (pair.second->m_path == srcPath) {
|
|
1271
|
-
kv = pair.second;
|
|
1272
|
-
break;
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
// get one in cache, do it the easy way
|
|
1277
|
-
if (kv) {
|
|
1278
|
-
#ifdef MMKV_WIN32
|
|
1279
|
-
MMKVInfo("backup one cached mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1280
|
-
#else
|
|
1281
|
-
MMKVInfo("backup one cached mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1282
|
-
#endif
|
|
1283
|
-
SCOPED_LOCK(kv->m_lock);
|
|
1284
|
-
SCOPED_LOCK(kv->m_sharedProcessLock);
|
|
1285
|
-
|
|
1286
|
-
kv->sync();
|
|
1287
|
-
auto ret = copyFile(kv->m_path, dstPath);
|
|
1288
|
-
if (ret) {
|
|
1289
|
-
auto dstCRCPath = dstPath + CRC_SUFFIX;
|
|
1290
|
-
ret = copyFile(kv->m_crcPath, dstCRCPath);
|
|
1291
|
-
}
|
|
1292
|
-
MMKVInfo("finish backup one mmkv[%s], ret: %d", mmapKey.c_str(), ret);
|
|
1293
|
-
return ret;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
// no luck with cache, do it the hard way
|
|
1297
|
-
bool ret = backupOneToDirectoryByFilePath(mmapKey, srcPath, dstPath);
|
|
1298
|
-
return ret;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
bool MMKV::backupOneToDirectory(const string &mmapID, const MMKVPath_t &dstDir, const MMKVPath_t *srcDir) {
|
|
1302
|
-
auto rootPath = srcDir ? srcDir : &g_rootDir;
|
|
1303
|
-
if (*rootPath == dstDir) {
|
|
1304
|
-
return true;
|
|
1305
|
-
}
|
|
1306
|
-
mkPath(dstDir);
|
|
1307
|
-
auto encodePath = encodeFilePath(mmapID, dstDir);
|
|
1308
|
-
auto dstPath = dstDir + MMKV_PATH_SLASH + encodePath;
|
|
1309
|
-
auto mmapKey = mmapedKVKey(mmapID, rootPath);
|
|
1310
|
-
#ifdef MMKV_ANDROID
|
|
1311
|
-
// historically Android mistakenly use mmapKey as mmapID
|
|
1312
|
-
auto srcPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
|
|
1313
|
-
#else
|
|
1314
|
-
auto srcPath = *rootPath + MMKV_PATH_SLASH + encodePath;
|
|
1315
|
-
#endif
|
|
1316
|
-
return backupOneToDirectory(mmapKey, dstPath, srcPath, false);
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
bool endsWith(const MMKVPath_t &str, const MMKVPath_t &suffix) {
|
|
1320
|
-
if (str.length() >= suffix.length()) {
|
|
1321
|
-
return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
|
|
1322
|
-
} else {
|
|
1323
|
-
return false;
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
MMKVPath_t filename(const MMKVPath_t &path) {
|
|
1328
|
-
auto startPos = path.rfind(MMKV_PATH_SLASH);
|
|
1329
|
-
startPos++; // don't need to check for npos, because npos+1 == 0
|
|
1330
|
-
auto filename = path.substr(startPos);
|
|
1331
|
-
return filename;
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &srcDir, bool isInSpecialDir) {
|
|
1335
|
-
unordered_set<MMKVPath_t> mmapIDSet;
|
|
1336
|
-
unordered_set<MMKVPath_t> mmapIDCRCSet;
|
|
1337
|
-
walkInDir(srcDir, WalkFile, [&](const MMKVPath_t &filePath, WalkType) {
|
|
1338
|
-
if (endsWith(filePath, CRC_SUFFIX)) {
|
|
1339
|
-
mmapIDCRCSet.insert(filePath);
|
|
1340
|
-
} else {
|
|
1341
|
-
mmapIDSet.insert(filePath);
|
|
1342
|
-
}
|
|
1343
|
-
});
|
|
1344
|
-
|
|
1345
|
-
size_t count = 0;
|
|
1346
|
-
if (!mmapIDSet.empty()) {
|
|
1347
|
-
mkPath(dstDir);
|
|
1348
|
-
auto compareFullPath = isInSpecialDir;
|
|
1349
|
-
for (auto &srcPath : mmapIDSet) {
|
|
1350
|
-
auto srcCRCPath = srcPath + CRC_SUFFIX;
|
|
1351
|
-
if (mmapIDCRCSet.find(srcCRCPath) == mmapIDCRCSet.end()) {
|
|
1352
|
-
#ifdef MMKV_WIN32
|
|
1353
|
-
MMKVWarning("crc not exist [%ls]", srcCRCPath.c_str());
|
|
1354
|
-
#else
|
|
1355
|
-
MMKVWarning("crc not exist [%s]", srcCRCPath.c_str());
|
|
1356
|
-
#endif
|
|
1357
|
-
continue;
|
|
1358
|
-
}
|
|
1359
|
-
auto basename = filename(srcPath);
|
|
1360
|
-
const auto &strBasename = MMKVPath_t2String(basename);
|
|
1361
|
-
auto mmapKey = isInSpecialDir ? strBasename : mmapedKVKey(strBasename, &srcDir);
|
|
1362
|
-
auto dstPath = dstDir + MMKV_PATH_SLASH;
|
|
1363
|
-
dstPath += basename;
|
|
1364
|
-
if (backupOneToDirectory(mmapKey, dstPath, srcPath, compareFullPath)) {
|
|
1365
|
-
count++;
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
return count;
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t *srcDir) {
|
|
1373
|
-
auto rootPath = srcDir ? srcDir : &g_rootDir;
|
|
1374
|
-
if (*rootPath == dstDir) {
|
|
1375
|
-
return true;
|
|
1376
|
-
}
|
|
1377
|
-
auto count = backupAllToDirectory(dstDir, *rootPath, false);
|
|
1378
|
-
|
|
1379
|
-
auto specialSrcDir = *rootPath + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1380
|
-
if (isFileExist(specialSrcDir)) {
|
|
1381
|
-
auto specialDstDir = dstDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1382
|
-
count += backupAllToDirectory(specialDstDir, specialSrcDir, true);
|
|
1383
|
-
}
|
|
1384
|
-
return count;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
// restore
|
|
1388
|
-
|
|
1389
|
-
static bool restoreOneFromDirectoryByFilePath(const string &mmapKey, const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
|
|
1390
|
-
auto dstCRCPath = dstPath + CRC_SUFFIX;
|
|
1391
|
-
File dstCRCFile(std::move(dstCRCPath), OpenFlag::ReadWrite | OpenFlag::Create);
|
|
1392
|
-
if (!dstCRCFile.isFileValid()) {
|
|
1393
|
-
return false;
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
bool ret;
|
|
1397
|
-
{
|
|
1398
|
-
#ifdef MMKV_WIN32
|
|
1399
|
-
MMKVInfo("restore one mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1400
|
-
#else
|
|
1401
|
-
MMKVInfo("restore one mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1402
|
-
#endif
|
|
1403
|
-
FileLock fileLock(dstCRCFile.getFd());
|
|
1404
|
-
InterProcessLock lock(&fileLock, ExclusiveLockType);
|
|
1405
|
-
SCOPED_LOCK(&lock);
|
|
1406
|
-
|
|
1407
|
-
ret = copyFileContent(srcPath, dstPath);
|
|
1408
|
-
if (ret) {
|
|
1409
|
-
auto srcCRCPath = srcPath + CRC_SUFFIX;
|
|
1410
|
-
ret = copyFileContent(srcCRCPath, dstCRCFile.getFd());
|
|
1411
|
-
}
|
|
1412
|
-
MMKVInfo("finish restore one mmkv[%s]", mmapKey.c_str());
|
|
1413
|
-
}
|
|
1414
|
-
return ret;
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
// We can't simply replace the existing file, because other processes might have already open it.
|
|
1418
|
-
// They won't know a difference when the file has been replaced.
|
|
1419
|
-
// We have to let them know by overriding the existing file with new content.
|
|
1420
|
-
bool MMKV::restoreOneFromDirectory(const string &mmapKey, const MMKVPath_t &srcPath, const MMKVPath_t &dstPath, bool compareFullPath) {
|
|
1421
|
-
if (!g_instanceLock) {
|
|
1422
|
-
return false;
|
|
1423
|
-
}
|
|
1424
|
-
// we have to lock the creation of MMKV instance, regardless of in cache or not
|
|
1425
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1426
|
-
MMKV *kv = nullptr;
|
|
1427
|
-
if (!compareFullPath) {
|
|
1428
|
-
auto itr = g_instanceDic->find(mmapKey);
|
|
1429
|
-
if (itr != g_instanceDic->end()) {
|
|
1430
|
-
kv = itr->second;
|
|
1431
|
-
}
|
|
1432
|
-
} else {
|
|
1433
|
-
// mmapKey is actually filename, we can't simply call find()
|
|
1434
|
-
for (auto &pair : *g_instanceDic) {
|
|
1435
|
-
if (pair.second->m_path == dstPath) {
|
|
1436
|
-
kv = pair.second;
|
|
1437
|
-
break;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
// get one in cache, do it the easy way
|
|
1442
|
-
if (kv) {
|
|
1443
|
-
#ifdef MMKV_WIN32
|
|
1444
|
-
MMKVInfo("restore one cached mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1445
|
-
#else
|
|
1446
|
-
MMKVInfo("restore one cached mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
|
|
1447
|
-
#endif
|
|
1448
|
-
SCOPED_LOCK(kv->m_lock);
|
|
1449
|
-
SCOPED_LOCK(kv->m_exclusiveProcessLock);
|
|
1450
|
-
|
|
1451
|
-
kv->sync();
|
|
1452
|
-
auto ret = copyFileContent(srcPath, kv->m_file->getFd());
|
|
1453
|
-
if (ret) {
|
|
1454
|
-
auto srcCRCPath = srcPath + CRC_SUFFIX;
|
|
1455
|
-
// ret = copyFileContent(srcCRCPath, kv->m_metaFile->getFd());
|
|
1456
|
-
#ifndef MMKV_ANDROID
|
|
1457
|
-
MemoryFile srcCRCFile(srcCRCPath);
|
|
1458
|
-
#else
|
|
1459
|
-
MemoryFile srcCRCFile(srcCRCPath, DEFAULT_MMAP_SIZE, MMFILE_TYPE_FILE);
|
|
1460
|
-
#endif
|
|
1461
|
-
if (srcCRCFile.isFileValid()) {
|
|
1462
|
-
memcpy(kv->m_metaFile->getMemory(), srcCRCFile.getMemory(), sizeof(MMKVMetaInfo));
|
|
1463
|
-
} else {
|
|
1464
|
-
ret = false;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
// reload data after restore
|
|
1469
|
-
kv->clearMemoryCache();
|
|
1470
|
-
kv->loadFromFile();
|
|
1471
|
-
if (kv->isMultiProcess()) {
|
|
1472
|
-
kv->notifyContentChanged();
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
MMKVInfo("finish restore one mmkv[%s], ret: %d", mmapKey.c_str(), ret);
|
|
1476
|
-
return ret;
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
// no luck with cache, do it the hard way
|
|
1480
|
-
bool ret = restoreOneFromDirectoryByFilePath(mmapKey, srcPath, dstPath);
|
|
1481
|
-
return ret;
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
bool MMKV::restoreOneFromDirectory(const string &mmapID, const MMKVPath_t &srcDir, const MMKVPath_t *dstDir) {
|
|
1485
|
-
auto rootPath = dstDir ? dstDir : &g_rootDir;
|
|
1486
|
-
if (*rootPath == srcDir) {
|
|
1487
|
-
return true;
|
|
1488
|
-
}
|
|
1489
|
-
mkPath(*rootPath);
|
|
1490
|
-
auto encodePath = encodeFilePath(mmapID, *rootPath);
|
|
1491
|
-
auto srcPath = srcDir + MMKV_PATH_SLASH + encodePath;
|
|
1492
|
-
auto mmapKey = mmapedKVKey(mmapID, rootPath);
|
|
1493
|
-
#ifdef MMKV_ANDROID
|
|
1494
|
-
// historically Android mistakenly use mmapKey as mmapID
|
|
1495
|
-
auto dstPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath);
|
|
1496
|
-
#else
|
|
1497
|
-
auto dstPath = *rootPath + MMKV_PATH_SLASH + encodePath;
|
|
1498
|
-
#endif
|
|
1499
|
-
return restoreOneFromDirectory(mmapKey, srcPath, dstPath, false);
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
size_t MMKV::restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t &dstDir, bool isInSpecialDir) {
|
|
1503
|
-
unordered_set<MMKVPath_t> mmapIDSet;
|
|
1504
|
-
unordered_set<MMKVPath_t> mmapIDCRCSet;
|
|
1505
|
-
walkInDir(srcDir, WalkFile, [&](const MMKVPath_t &filePath, WalkType) {
|
|
1506
|
-
if (endsWith(filePath, CRC_SUFFIX)) {
|
|
1507
|
-
mmapIDCRCSet.insert(filePath);
|
|
1508
|
-
} else {
|
|
1509
|
-
mmapIDSet.insert(filePath);
|
|
1510
|
-
}
|
|
1511
|
-
});
|
|
1512
|
-
|
|
1513
|
-
size_t count = 0;
|
|
1514
|
-
if (!mmapIDSet.empty()) {
|
|
1515
|
-
mkPath(dstDir);
|
|
1516
|
-
auto compareFullPath = isInSpecialDir;
|
|
1517
|
-
for (auto &srcPath : mmapIDSet) {
|
|
1518
|
-
auto srcCRCPath = srcPath + CRC_SUFFIX;
|
|
1519
|
-
if (mmapIDCRCSet.find(srcCRCPath) == mmapIDCRCSet.end()) {
|
|
1520
|
-
#ifdef MMKV_WIN32
|
|
1521
|
-
MMKVWarning("crc not exist [%ls]", srcCRCPath.c_str());
|
|
1522
|
-
#else
|
|
1523
|
-
MMKVWarning("crc not exist [%s]", srcCRCPath.c_str());
|
|
1524
|
-
#endif
|
|
1525
|
-
continue;
|
|
1526
|
-
}
|
|
1527
|
-
auto basename = filename(srcPath);
|
|
1528
|
-
const auto &strBasename = MMKVPath_t2String(basename);
|
|
1529
|
-
auto mmapKey = isInSpecialDir ? strBasename : mmapedKVKey(strBasename, &dstDir);
|
|
1530
|
-
auto dstPath = dstDir + MMKV_PATH_SLASH;
|
|
1531
|
-
dstPath += basename;
|
|
1532
|
-
if (restoreOneFromDirectory(mmapKey, srcPath, dstPath, compareFullPath)) {
|
|
1533
|
-
count++;
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
return count;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
size_t MMKV::restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t *dstDir) {
|
|
1541
|
-
auto rootPath = dstDir ? dstDir : &g_rootDir;
|
|
1542
|
-
if (*rootPath == srcDir) {
|
|
1543
|
-
return true;
|
|
1544
|
-
}
|
|
1545
|
-
auto count = restoreAllFromDirectory(srcDir, *rootPath, true);
|
|
1546
|
-
|
|
1547
|
-
auto specialSrcDir = srcDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1548
|
-
if (isFileExist(specialSrcDir)) {
|
|
1549
|
-
auto specialDstDir = *rootPath + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1550
|
-
count += restoreAllFromDirectory(specialSrcDir, specialDstDir, false);
|
|
1551
|
-
}
|
|
1552
|
-
return count;
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
// callbacks
|
|
1556
|
-
|
|
1557
|
-
void MMKV::registerErrorHandler(ErrorHandler handler) {
|
|
1558
|
-
if (!g_instanceLock) {
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1562
|
-
g_errorHandler = handler;
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
void MMKV::unRegisterErrorHandler() {
|
|
1566
|
-
if (!g_instanceLock) {
|
|
1567
|
-
return;
|
|
1568
|
-
}
|
|
1569
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1570
|
-
g_errorHandler = nullptr;
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
void MMKV::registerLogHandler(LogHandler handler) {
|
|
1574
|
-
if (!g_instanceLock) {
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1578
|
-
g_logHandler = handler;
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
void MMKV::unRegisterLogHandler() {
|
|
1582
|
-
if (!g_instanceLock) {
|
|
1583
|
-
return;
|
|
1584
|
-
}
|
|
1585
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1586
|
-
g_logHandler = nullptr;
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
void MMKV::setLogLevel(MMKVLogLevel level) {
|
|
1590
|
-
if (!g_instanceLock) {
|
|
1591
|
-
return;
|
|
1592
|
-
}
|
|
1593
|
-
SCOPED_LOCK(g_instanceLock);
|
|
1594
|
-
g_currentLogLevel = level;
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
static void mkSpecialCharacterFileDirectory() {
|
|
1598
|
-
MMKVPath_t path = g_rootDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1599
|
-
mkPath(path);
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
template <typename T>
|
|
1603
|
-
static string md5(const basic_string<T> &value) {
|
|
1604
|
-
uint8_t md[MD5_DIGEST_LENGTH] = {};
|
|
1605
|
-
char tmp[3] = {}, buf[33] = {};
|
|
1606
|
-
openssl::MD5((const uint8_t *) value.c_str(), value.size() * (sizeof(T) / sizeof(uint8_t)), md);
|
|
1607
|
-
for (auto ch : md) {
|
|
1608
|
-
snprintf(tmp, sizeof(tmp), "%2.2x", ch);
|
|
1609
|
-
strcat(buf, tmp);
|
|
1610
|
-
}
|
|
1611
|
-
return {buf};
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
static MMKVPath_t encodeFilePath(const string &mmapID) {
|
|
1615
|
-
const char *specialCharacters = "\\/:*?\"<>|";
|
|
1616
|
-
string encodedID;
|
|
1617
|
-
bool hasSpecialCharacter = false;
|
|
1618
|
-
for (auto ch : mmapID) {
|
|
1619
|
-
if (strchr(specialCharacters, ch) != nullptr) {
|
|
1620
|
-
encodedID = md5(mmapID);
|
|
1621
|
-
hasSpecialCharacter = true;
|
|
1622
|
-
break;
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
if (hasSpecialCharacter) {
|
|
1626
|
-
static ThreadOnceToken_t once = ThreadOnceUninitialized;
|
|
1627
|
-
ThreadLock::ThreadOnce(&once, mkSpecialCharacterFileDirectory);
|
|
1628
|
-
return MMKVPath_t(SPECIAL_CHARACTER_DIRECTORY_NAME) + MMKV_PATH_SLASH + string2MMKVPath_t(encodedID);
|
|
1629
|
-
} else {
|
|
1630
|
-
return string2MMKVPath_t(mmapID);
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
static MMKVPath_t encodeFilePath(const string &mmapID, const MMKVPath_t &rootDir) {
|
|
1635
|
-
const char *specialCharacters = "\\/:*?\"<>|";
|
|
1636
|
-
string encodedID;
|
|
1637
|
-
bool hasSpecialCharacter = false;
|
|
1638
|
-
for (auto ch : mmapID) {
|
|
1639
|
-
if (strchr(specialCharacters, ch) != nullptr) {
|
|
1640
|
-
encodedID = md5(mmapID);
|
|
1641
|
-
hasSpecialCharacter = true;
|
|
1642
|
-
break;
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
if (hasSpecialCharacter) {
|
|
1646
|
-
MMKVPath_t path = rootDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME;
|
|
1647
|
-
mkPath(path);
|
|
1648
|
-
|
|
1649
|
-
return MMKVPath_t(SPECIAL_CHARACTER_DIRECTORY_NAME) + MMKV_PATH_SLASH + string2MMKVPath_t(encodedID);
|
|
1650
|
-
} else {
|
|
1651
|
-
return string2MMKVPath_t(mmapID);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
string mmapedKVKey(const string &mmapID, const MMKVPath_t *rootPath) {
|
|
1656
|
-
if (rootPath && g_rootDir != (*rootPath)) {
|
|
1657
|
-
return md5(*rootPath + MMKV_PATH_SLASH + string2MMKVPath_t(mmapID));
|
|
1658
|
-
}
|
|
1659
|
-
return mmapID;
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
MMKVPath_t mappedKVPathWithID(const string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath) {
|
|
1663
|
-
#ifndef MMKV_ANDROID
|
|
1664
|
-
if (rootPath) {
|
|
1665
|
-
#else
|
|
1666
|
-
if (mode & MMKV_ASHMEM) {
|
|
1667
|
-
return ashmemMMKVPathWithID(encodeFilePath(mmapID));
|
|
1668
|
-
} else if (rootPath) {
|
|
1669
|
-
#endif
|
|
1670
|
-
return *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapID);
|
|
1671
|
-
}
|
|
1672
|
-
return g_rootDir + MMKV_PATH_SLASH + encodeFilePath(mmapID);
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
MMKVPath_t crcPathWithID(const string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath) {
|
|
1676
|
-
#ifndef MMKV_ANDROID
|
|
1677
|
-
if (rootPath) {
|
|
1678
|
-
#else
|
|
1679
|
-
if (mode & MMKV_ASHMEM) {
|
|
1680
|
-
return ashmemMMKVPathWithID(encodeFilePath(mmapID)) + CRC_SUFFIX;
|
|
1681
|
-
} else if (rootPath) {
|
|
1682
|
-
#endif
|
|
1683
|
-
return *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapID) + CRC_SUFFIX;
|
|
1684
|
-
}
|
|
1685
|
-
return g_rootDir + MMKV_PATH_SLASH + encodeFilePath(mmapID) + CRC_SUFFIX;
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
MMKVRecoverStrategic onMMKVCRCCheckFail(const string &mmapID) {
|
|
1689
|
-
if (g_errorHandler) {
|
|
1690
|
-
return g_errorHandler(mmapID, MMKVErrorType::MMKVCRCCheckFail);
|
|
1691
|
-
}
|
|
1692
|
-
return OnErrorDiscard;
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1695
|
-
MMKVRecoverStrategic onMMKVFileLengthError(const string &mmapID) {
|
|
1696
|
-
if (g_errorHandler) {
|
|
1697
|
-
return g_errorHandler(mmapID, MMKVErrorType::MMKVFileLength);
|
|
1698
|
-
}
|
|
1699
|
-
return OnErrorDiscard;
|
|
1700
|
-
}
|
|
1701
|
-
|
|
1702
|
-
MMKV_NAMESPACE_END
|