react-native-mmkv 3.0.0-beta.6 → 3.0.0-beta.8

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 (57) hide show
  1. package/MMKV/Core/CMakeLists.txt +1 -1
  2. package/MMKV/Core/Core.xcodeproj/project.pbxproj +4 -6
  3. package/MMKV/Core/KeyValueHolder.cpp +1 -1
  4. package/MMKV/Core/KeyValueHolder.h +5 -1
  5. package/MMKV/Core/MMBuffer.h +1 -1
  6. package/MMKV/Core/MMKV.cpp +70 -73
  7. package/MMKV/Core/MMKV.h +126 -11
  8. package/MMKV/Core/MMKVPredef.h +44 -3
  9. package/MMKV/Core/MMKV_IO.cpp +47 -33
  10. package/MMKV/Core/MMKV_OSX.cpp +16 -29
  11. package/MMKV/Core/MemoryFile_Android.cpp +27 -13
  12. package/MMKV/Core/MiniPBCoder.cpp +308 -9
  13. package/MMKV/Core/MiniPBCoder.h +36 -17
  14. package/MMKV/Core/MiniPBCoder_OSX.cpp +1 -0
  15. package/MMKV/Core/PBEncodeItem.hpp +18 -0
  16. package/MMKV/Core/PBUtility.h +0 -12
  17. package/MMKV/Core/ThreadLock.cpp +1 -3
  18. package/MMKV/Core/aes/AESCrypt.cpp +26 -6
  19. package/MMKV/Core/aes/AESCrypt.h +5 -1
  20. package/MMKV/Core/core.vcxproj +4 -4
  21. package/MMKV/Core/crc32/Checksum.h +4 -1
  22. package/android/CMakeLists.txt +0 -1
  23. package/android/src/main/java/com/mrousavy/mmkv/MmkvPlatformContextModule.java +9 -0
  24. package/cpp/MmkvHostObject.cpp +35 -37
  25. package/ios/MmkvPlatformContextModule.mm +19 -1
  26. package/lib/commonjs/MMKV.js.map +1 -1
  27. package/lib/commonjs/NativeMmkvPlatformContext.js.map +1 -1
  28. package/lib/commonjs/createMMKV.js +17 -0
  29. package/lib/commonjs/createMMKV.js.map +1 -1
  30. package/lib/commonjs/hooks.js.map +1 -1
  31. package/lib/module/MMKV.js.map +1 -1
  32. package/lib/module/NativeMmkvPlatformContext.js.map +1 -1
  33. package/lib/module/createMMKV.js +17 -0
  34. package/lib/module/createMMKV.js.map +1 -1
  35. package/lib/module/hooks.js.map +1 -1
  36. package/lib/typescript/src/MMKV.d.ts +0 -1
  37. package/lib/typescript/src/MMKV.d.ts.map +1 -1
  38. package/lib/typescript/src/NativeMmkv.d.ts +3 -3
  39. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts +11 -0
  40. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts.map +1 -1
  41. package/lib/typescript/src/Types.d.ts +4 -0
  42. package/lib/typescript/src/Types.d.ts.map +1 -1
  43. package/lib/typescript/src/createMMKV.d.ts +1 -1
  44. package/lib/typescript/src/createMMKV.d.ts.map +1 -1
  45. package/lib/typescript/src/createMMKV.web.d.ts +1 -1
  46. package/lib/typescript/src/createMMKV.web.d.ts.map +1 -1
  47. package/lib/typescript/src/hooks.d.ts +1 -1
  48. package/lib/typescript/src/hooks.d.ts.map +1 -1
  49. package/package.json +6 -6
  50. package/src/MMKV.ts +0 -1
  51. package/src/NativeMmkv.ts +3 -3
  52. package/src/NativeMmkvPlatformContext.ts +11 -0
  53. package/src/Types.ts +4 -0
  54. package/src/createMMKV.ts +20 -2
  55. package/src/createMMKV.web.ts +1 -1
  56. package/src/hooks.ts +1 -1
  57. package/android/src/main/cpp/cpp-adapter.cpp +0 -7
@@ -34,7 +34,7 @@
34
34
  #include <vector>
35
35
  #include <unordered_map>
36
36
 
37
- constexpr auto MMKV_VERSION = "v1.3.5";
37
+ constexpr auto MMKV_VERSION = "v1.3.9";
38
38
 
39
39
  #ifdef DEBUG
40
40
  # define MMKV_DEBUG
@@ -44,6 +44,10 @@ constexpr auto MMKV_VERSION = "v1.3.5";
44
44
  # undef MMKV_DEBUG
45
45
  #endif
46
46
 
47
+ #if __cplusplus>=202002L
48
+ # define MMKV_HAS_CPP20
49
+ #endif
50
+
47
51
  #ifdef __ANDROID__
48
52
  # ifdef FORCE_POSIX
49
53
  # define MMKV_POSIX
@@ -195,9 +199,34 @@ using MMKVVector = std::vector<std::pair<NSString *, mmkv::MMBuffer>>;
195
199
  using MMKVMap = std::unordered_map<NSString *, mmkv::KeyValueHolder, KeyHasher, KeyEqualer>;
196
200
  using MMKVMapCrypt = std::unordered_map<NSString *, mmkv::KeyValueHolderCrypt, KeyHasher, KeyEqualer>;
197
201
  #else
202
+ struct KeyHasher {
203
+ // enables heterogeneous lookup
204
+ using is_transparent = void;
205
+
206
+ std::size_t operator()(const std::string_view& str) const {
207
+ return std::hash<std::string_view>{}(str);
208
+ }
209
+
210
+ std::size_t operator()(const std::string& str) const {
211
+ return std::hash<std::string>{}(str);
212
+ }
213
+ };
214
+
215
+ struct KeyEqualer {
216
+ // enables heterogeneous lookup
217
+ using is_transparent = void;
218
+
219
+ bool operator()(const std::string_view& lhs, const std::string_view& rhs) const {
220
+ return lhs == rhs;
221
+ }
222
+
223
+ bool operator()(const std::string& lhs, const std::string& rhs) const {
224
+ return lhs == rhs;
225
+ }
226
+ };
198
227
  using MMKVVector = std::vector<std::pair<std::string, mmkv::MMBuffer>>;
199
- using MMKVMap = std::unordered_map<std::string, mmkv::KeyValueHolder>;
200
- using MMKVMapCrypt = std::unordered_map<std::string, mmkv::KeyValueHolderCrypt>;
228
+ using MMKVMap = std::unordered_map<std::string, mmkv::KeyValueHolder, KeyHasher, KeyEqualer>;
229
+ using MMKVMapCrypt = std::unordered_map<std::string, mmkv::KeyValueHolderCrypt, KeyHasher, KeyEqualer>;
201
230
  #endif // MMKV_APPLE
202
231
 
203
232
  template <typename T>
@@ -217,6 +246,18 @@ constexpr size_t AES_KEY_BITSET_LEN = 128;
217
246
 
218
247
  #endif //cplus-plus
219
248
 
249
+ #ifndef MMKV_WIN32
250
+ # ifndef likely
251
+ # define mmkv_unlikely(x) (__builtin_expect(bool(x), 0))
252
+ # define mmkv_likely(x) (__builtin_expect(bool(x), 1))
253
+ # endif
254
+ #else
255
+ # ifndef likely
256
+ # define mmkv_unlikely(x) (x)
257
+ # define mmkv_likely(x) (x)
258
+ # endif
259
+ #endif
260
+
220
261
  #if defined(__arm__)
221
262
  #if defined(__ARM_ARCH_7A__)
222
263
  #if defined(__ARM_NEON__)
@@ -338,7 +338,6 @@ void MMKV::checkLoadData() {
338
338
  }
339
339
  }
340
340
 
341
- constexpr uint32_t ItemSizeHolder = 0x00ffffff;
342
341
  constexpr uint32_t ItemSizeHolderSize = 4;
343
342
 
344
343
  static pair<MMBuffer, size_t> prepareEncode(const MMKVMap &dic) {
@@ -496,7 +495,7 @@ bool MMKV::writeActualSize(size_t size, uint32_t crcDigest, const void *iv, bool
496
495
  needsFullWrite = true;
497
496
  }
498
497
  #ifndef MMKV_DISABLE_CRYPT
499
- if (unlikely(iv)) {
498
+ if (mmkv_unlikely(iv)) {
500
499
  memcpy(m_metaInfo->m_vector, iv, sizeof(m_metaInfo->m_vector));
501
500
  if (m_metaInfo->m_version < MMKVVersionRandomIV) {
502
501
  m_metaInfo->m_version = MMKVVersionRandomIV;
@@ -504,7 +503,7 @@ bool MMKV::writeActualSize(size_t size, uint32_t crcDigest, const void *iv, bool
504
503
  needsFullWrite = true;
505
504
  }
506
505
  #endif
507
- if (unlikely(increaseSequence)) {
506
+ if (mmkv_unlikely(increaseSequence)) {
508
507
  m_metaInfo->m_sequence++;
509
508
  m_metaInfo->m_lastConfirmedMetaInfo.lastActualSize = static_cast<uint32_t>(size);
510
509
  m_metaInfo->m_lastConfirmedMetaInfo.lastCRCDigest = crcDigest;
@@ -526,7 +525,7 @@ bool MMKV::writeActualSize(size_t size, uint32_t crcDigest, const void *iv, bool
526
525
  return false;
527
526
  }
528
527
  #endif
529
- if (unlikely(needsFullWrite)) {
528
+ if (mmkv_unlikely(needsFullWrite)) {
530
529
  m_metaInfo->write(m_metaFile->getMemory());
531
530
  } else {
532
531
  m_metaInfo->writeCRCAndActualSizeOnly(m_metaFile->getMemory());
@@ -557,7 +556,7 @@ MMBuffer MMKV::getRawDataForKey(MMKVKey_t key) {
557
556
  }
558
557
 
559
558
  mmkv::MMBuffer MMKV::getDataForKey(MMKVKey_t key) {
560
- if (unlikely(m_enableKeyExpire)) {
559
+ if (mmkv_unlikely(m_enableKeyExpire)) {
561
560
  return getDataWithoutMTimeForKey(key);
562
561
  }
563
562
  return getRawDataForKey(key);
@@ -617,7 +616,7 @@ bool MMKV::setDataForKey(MMBuffer &&data, MMKVKey_t key, bool isDataHolder) {
617
616
  } else {
618
617
  kvHolder = KeyValueHolderCrypt(std::move(data));
619
618
  }
620
- if (likely(!m_enableKeyExpire)) {
619
+ if (mmkv_likely(!m_enableKeyExpire)) {
621
620
  itr->second = std::move(kvHolder);
622
621
  } else {
623
622
  itr = m_dicCrypt->find(key);
@@ -670,9 +669,9 @@ bool MMKV::setDataForKey(MMBuffer &&data, MMKVKey_t key, bool isDataHolder) {
670
669
  return true;
671
670
  }
672
671
  } catch (std::exception &exception) {
673
- MMKVError("compareBeforeSet exception: %s", exception.what());
672
+ MMKVWarning("compareBeforeSet exception: %s", exception.what());
674
673
  } catch (...) {
675
- MMKVError("compareBeforeSet fail");
674
+ MMKVWarning("compareBeforeSet fail");
676
675
  }
677
676
  } else {
678
677
  if (oldValueData == data) {
@@ -683,7 +682,7 @@ bool MMKV::setDataForKey(MMBuffer &&data, MMKVKey_t key, bool isDataHolder) {
683
682
  }
684
683
 
685
684
  bool onlyOneKey = !m_isInterProcess && m_dic->size() == 1;
686
- if (likely(!m_enableKeyExpire)) {
685
+ if (mmkv_likely(!m_enableKeyExpire)) {
687
686
  KVHolderRet_t ret;
688
687
  if (onlyOneKey) {
689
688
  ret = overrideDataWithKey(data, itr->second, isDataHolder);
@@ -732,6 +731,14 @@ bool MMKV::setDataForKey(MMBuffer &&data, MMKVKey_t key, bool isDataHolder) {
732
731
  return true;
733
732
  }
734
733
 
734
+ template <typename T>
735
+ static void eraseHelper(T& container, std::string_view key) {
736
+ auto itr = container.find(key);
737
+ if (itr != container.end()) {
738
+ container.erase(itr);
739
+ }
740
+ }
741
+
735
742
  bool MMKV::removeDataForKey(MMKVKey_t key) {
736
743
  if (isKeyEmpty(key)) {
737
744
  return false;
@@ -745,7 +752,7 @@ bool MMKV::removeDataForKey(MMKVKey_t key) {
745
752
  # ifdef MMKV_APPLE
746
753
  auto ret = appendDataWithKey(nan, key, itr->second);
747
754
  if (ret.first) {
748
- if (unlikely(m_enableKeyExpire)) {
755
+ if (mmkv_unlikely(m_enableKeyExpire)) {
749
756
  // filterExpiredKeys() may invalid itr
750
757
  itr = m_dicCrypt->find(key);
751
758
  if (itr == m_dicCrypt->end()) {
@@ -759,8 +766,8 @@ bool MMKV::removeDataForKey(MMKVKey_t key) {
759
766
  # else
760
767
  auto ret = appendDataWithKey(nan, key);
761
768
  if (ret.first) {
762
- if (unlikely(m_enableKeyExpire)) {
763
- m_dicCrypt->erase(key);
769
+ if (mmkv_unlikely(m_enableKeyExpire)) {
770
+ eraseHelper(*m_dicCrypt, key);
764
771
  } else {
765
772
  m_dicCrypt->erase(itr);
766
773
  }
@@ -775,10 +782,10 @@ bool MMKV::removeDataForKey(MMKVKey_t key) {
775
782
  if (itr != m_dic->end()) {
776
783
  m_hasFullWriteback = false;
777
784
  static MMBuffer nan;
778
- auto ret = likely(!m_enableKeyExpire) ? appendDataWithKey(nan, itr->second) : appendDataWithKey(nan, key);
785
+ auto ret = mmkv_likely(!m_enableKeyExpire) ? appendDataWithKey(nan, itr->second) : appendDataWithKey(nan, key);
779
786
  if (ret.first) {
780
787
  #ifdef MMKV_APPLE
781
- if (unlikely(m_enableKeyExpire)) {
788
+ if (mmkv_unlikely(m_enableKeyExpire)) {
782
789
  // filterExpiredKeys() may invalid itr
783
790
  itr = m_dic->find(key);
784
791
  if (itr == m_dic->end()) {
@@ -789,9 +796,9 @@ bool MMKV::removeDataForKey(MMKVKey_t key) {
789
796
  m_dic->erase(itr);
790
797
  [oldKey release];
791
798
  #else
792
- if (unlikely(m_enableKeyExpire)) {
799
+ if (mmkv_unlikely(m_enableKeyExpire)) {
793
800
  // filterExpiredKeys() may invalid itr
794
- m_dic->erase(key);
801
+ eraseHelper(*m_dic, key);
795
802
  } else {
796
803
  m_dic->erase(itr);
797
804
  }
@@ -903,17 +910,22 @@ KVHolderRet_t MMKV::doOverrideDataWithKey(const MMBuffer &data,
903
910
  } else {
904
911
  m_crypter->resetIV();
905
912
  }
906
- if (KeyValueHolderCrypt::isValueStoredAsOffset(valueLength)) {
907
- m_crypter->getCurStatus(t_status);
908
- }
909
913
  }
910
914
  #endif
911
915
  try {
912
916
  // write ItemSizeHolder
913
917
  m_output->setPosition(0);
914
- m_output->writeRawVarint32(ItemSizeHolder);
918
+ m_output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
915
919
  m_actualSize = ItemSizeHolderSize;
916
-
920
+ #ifndef MMKV_DISABLE_CRYPT
921
+ if (m_crypter) {
922
+ auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size;
923
+ m_crypter->encrypt(ptr, ptr, m_actualSize);
924
+ if (KeyValueHolderCrypt::isValueStoredAsOffset(valueLength)) {
925
+ m_crypter->getCurStatus(t_status);
926
+ }
927
+ }
928
+ #endif
917
929
  if (isKeyEncoded) {
918
930
  m_output->writeRawData(keyData);
919
931
  } else {
@@ -933,13 +945,13 @@ KVHolderRet_t MMKV::doOverrideDataWithKey(const MMBuffer &data,
933
945
 
934
946
  auto offset = static_cast<uint32_t>(m_actualSize);
935
947
  m_actualSize += size;
936
- auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size;
937
948
  #ifndef MMKV_DISABLE_CRYPT
938
949
  if (m_crypter) {
939
- m_crypter->encrypt(ptr, ptr, m_actualSize);
950
+ auto ptr = (uint8_t *) m_file->getMemory() + Fixed32Size + offset;
951
+ m_crypter->encrypt(ptr, ptr, size);
940
952
  }
941
953
  #endif
942
- recaculateCRCDigestOnly();
954
+ recalculateCRCDigestOnly();
943
955
 
944
956
  return make_pair(true, KeyValueHolder(originKeyLength, valueLength, offset));
945
957
  }
@@ -1044,7 +1056,7 @@ bool MMKV::fullWriteback(AESCrypt *newCrypter, bool onlyWhileExpire) {
1044
1056
  return false;
1045
1057
  }
1046
1058
 
1047
- if (unlikely(m_enableKeyExpire)) {
1059
+ if (mmkv_unlikely(m_enableKeyExpire)) {
1048
1060
  auto expiredCount = filterExpiredKeys();
1049
1061
  if (onlyWhileExpire && expiredCount == 0) {
1050
1062
  return true;
@@ -1120,7 +1132,7 @@ memmoveDictionary(MMKVMap &dic, CodedOutputData *output, uint8_t *ptr, AESCrypt
1120
1132
  }
1121
1133
  }
1122
1134
  // hold the fake size of dictionary's serialization result
1123
- output->writeRawVarint32(ItemSizeHolder);
1135
+ output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
1124
1136
  auto writtenSize = static_cast<size_t>(writePtr - originOutputPtr);
1125
1137
  #ifndef MMKV_DISABLE_CRYPT
1126
1138
  if (encrypter) {
@@ -1151,14 +1163,16 @@ static void memmoveDictionary(MMKVMapCrypt &dic,
1151
1163
  }
1152
1164
  sort(vec.begin(), vec.end(), [](auto left, auto right) { return left->offset < right->offset; });
1153
1165
  }
1154
- auto sizeHolder = ItemSizeHolder, sizeHolderSize = ItemSizeHolderSize;
1166
+ auto sizeHolderSize = ItemSizeHolderSize;
1167
+ auto sizeHolder = AESCrypt::randomItemSizeHolder(sizeHolderSize);
1155
1168
  if (!vec.empty()) {
1156
1169
  auto smallestOffset = vec.front()->offset;
1157
1170
  if (smallestOffset != ItemSizeHolderSize && smallestOffset <= 5) {
1158
1171
  sizeHolderSize = smallestOffset;
1159
1172
  assert(sizeHolderSize != 0);
1160
1173
  static const uint32_t ItemSizeHolders[] = {0, 0x0f, 0xff, 0xffff, 0xffffff, 0xffffffff};
1161
- sizeHolder = ItemSizeHolders[sizeHolderSize];
1174
+ sizeHolder = AESCrypt::randomItemSizeHolder(sizeHolderSize);
1175
+ assert(sizeHolder >= ItemSizeHolders[sizeHolderSize] && sizeHolder <= ItemSizeHolders[sizeHolderSize]);
1162
1176
  }
1163
1177
  }
1164
1178
  output->writeRawVarint32(static_cast<int32_t>(sizeHolder));
@@ -1222,7 +1236,7 @@ static void memmoveDictionary(MMKVMapCrypt &dic,
1222
1236
 
1223
1237
  static void fullWriteBackWholeData(MMBuffer allData, size_t totalSize, CodedOutputData *output) {
1224
1238
  auto originOutputPtr = output->curWritePointer();
1225
- output->writeRawVarint32(ItemSizeHolder);
1239
+ output->writeUInt32(AESCrypt::randomItemSizeHolder(ItemSizeHolderSize));
1226
1240
  if (allData.length() > 0) {
1227
1241
  auto dataSize = CodedInputData(allData.getPtr(), allData.length()).readUInt32();
1228
1242
  if (dataSize > 0) {
@@ -1270,9 +1284,9 @@ bool MMKV::doFullWriteBack(pair<MMBuffer, size_t> prepared, AESCrypt *newCrypter
1270
1284
 
1271
1285
  m_actualSize = totalSize;
1272
1286
  if (encrypter) {
1273
- recaculateCRCDigestWithIV(newIV);
1287
+ recalculateCRCDigestWithIV(newIV);
1274
1288
  } else {
1275
- recaculateCRCDigestWithIV(nullptr);
1289
+ recalculateCRCDigestWithIV(nullptr);
1276
1290
  }
1277
1291
  m_hasFullWriteback = true;
1278
1292
  // make sure lastConfirmedMetaInfo is saved if needed
@@ -1305,7 +1319,7 @@ bool MMKV::doFullWriteBack(pair<MMBuffer, size_t> prepared, AESCrypt *, bool nee
1305
1319
  }
1306
1320
 
1307
1321
  m_actualSize = totalSize;
1308
- recaculateCRCDigestWithIV(nullptr);
1322
+ recalculateCRCDigestWithIV(nullptr);
1309
1323
  m_hasFullWriteback = true;
1310
1324
  // make sure lastConfirmedMetaInfo is saved if needed
1311
1325
  if (needSync) {
@@ -1751,7 +1765,7 @@ mmkv::MMBuffer MMKV::getDataWithoutMTimeForKey(MMKVKey_t key) {
1751
1765
  #ifdef MMKV_APPLE
1752
1766
  MMKVInfo("deleting expired key [%@] in mmkv [%s], due date %u", key, m_mmapID.c_str(), time);
1753
1767
  #else
1754
- MMKVInfo("deleting expired key [%s] in mmkv [%s], due date %u", key.c_str(), m_mmapID.c_str(), time);
1768
+ MMKVInfo("deleting expired key [%s] in mmkv [%s], due date %u", key.data(), m_mmapID.c_str(), time);
1755
1769
  #endif
1756
1770
  removeValueForKey(key);
1757
1771
  return MMBuffer();
@@ -35,6 +35,7 @@
35
35
  # include <sys/utsname.h>
36
36
  # include <sys/sysctl.h>
37
37
  # include "MMKV_OSX.h"
38
+ # include "MMKVLog.h"
38
39
 
39
40
  # ifdef MMKV_IOS
40
41
  # include <sys/mman.h>
@@ -139,7 +140,7 @@ bool MMKV::set(NSObject<NSCoding> *__unsafe_unretained obj, MMKVKey_t key, uint3
139
140
  if (tmpData) {
140
141
  // delay write the size needed for encoding tmpData
141
142
  // avoid memory copying
142
- if (likely(!m_enableKeyExpire)) {
143
+ if (mmkv_likely(!m_enableKeyExpire)) {
143
144
  return setDataForKey(MMBuffer(tmpData, MMBufferNoCopy), key, true);
144
145
  } else {
145
146
  MMBuffer data(tmpData, MMBufferNoCopy);
@@ -167,7 +168,7 @@ bool MMKV::set(NSObject<NSCoding> *__unsafe_unretained obj, MMKVKey_t key, uint3
167
168
  return false;
168
169
  }
169
170
  if (archived.length > 0) {
170
- if (likely(!m_enableKeyExpire)) {
171
+ if (mmkv_likely(!m_enableKeyExpire)) {
171
172
  return setDataForKey(MMBuffer(archived, MMBufferNoCopy), key);
172
173
  } else {
173
174
  MMBuffer data(archived, MMBufferNoCopy);
@@ -259,35 +260,21 @@ MMKV::appendDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolde
259
260
 
260
261
  pair<bool, KeyValueHolder>
261
262
  MMKV::overrideDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolderCrypt &kvHolder, bool isDataHolder) {
262
- size_t old_actualSize = m_actualSize;
263
- size_t old_position = m_output->getPosition();
264
- // only one key in dict, do not append, just rewrite from beginning
265
- m_actualSize = 0;
266
- m_output->setPosition(0);
267
-
268
- auto m_tmpDic = m_dic;
269
- auto m_tmpDicCrypt = m_dicCrypt;
270
- if (m_crypter) {
271
- m_dicCrypt = new MMKVMapCrypt();
272
- } else {
273
- m_dic = new MMKVMap();
263
+ if (kvHolder.type != KeyValueHolderType_Offset) {
264
+ return overrideDataWithKey(data, key, isDataHolder);
274
265
  }
266
+ SCOPED_LOCK(m_exclusiveProcessLock);
275
267
 
276
- auto ret = appendDataWithKey(data, key, kvHolder, isDataHolder);
277
- if (!ret.first) {
278
- // rollback
279
- m_actualSize = old_actualSize;
280
- m_output->setPosition(old_position);
281
- }
268
+ uint32_t keyLength = kvHolder.keySize;
269
+ // size needed to encode the key
270
+ size_t rawKeySize = keyLength + pbRawVarint32Size(keyLength);
282
271
 
283
- if (m_crypter) {
284
- delete m_dicCrypt;
285
- m_dicCrypt = m_tmpDicCrypt;
286
- } else {
287
- delete m_dic;
288
- m_dic = m_tmpDic;
289
- }
290
- return ret;
272
+ auto basePtr = (uint8_t *) m_file->getMemory() + Fixed32Size;
273
+ MMBuffer keyData(rawKeySize);
274
+ AESCrypt decrypter = m_crypter->cloneWithStatus(kvHolder.cryptStatus);
275
+ decrypter.decrypt(basePtr + kvHolder.offset, keyData.getPtr(), rawKeySize);
276
+
277
+ return doOverrideDataWithKey(data, keyData, isDataHolder, keyLength);
291
278
  }
292
279
  # endif
293
280
 
@@ -295,7 +282,7 @@ NSArray *MMKV::allKeys(bool filterExpire) {
295
282
  SCOPED_LOCK(m_lock);
296
283
  checkLoadData();
297
284
 
298
- if (unlikely(filterExpire && m_enableKeyExpire)) {
285
+ if (mmkv_unlikely(filterExpire && m_enableKeyExpire)) {
299
286
  SCOPED_LOCK(m_exclusiveProcessLock);
300
287
  fullWriteback(nullptr, true);
301
288
  }
@@ -135,32 +135,46 @@ typedef size_t (*AShmem_getSize_t)(int fd);
135
135
  #endif
136
136
 
137
137
  int ASharedMemory_create(const char *name, size_t size) {
138
- int fd = -1;
139
138
  #ifndef MMKV_OHOS
140
- if (g_android_api >= __ANDROID_API_O__) {
139
+ if (g_android_api >= __ANDROID_API_O__ || g_android_api >= __ANDROID_API_M__) {
141
140
  static auto handle = loadLibrary();
142
141
  static AShmem_create_t funcPtr =
143
142
  (handle != nullptr) ? reinterpret_cast<AShmem_create_t>(dlsym(handle, "ASharedMemory_create")) : nullptr;
144
143
  if (funcPtr) {
145
- fd = funcPtr(name, size);
144
+ int fd = funcPtr(name, size);
146
145
  if (fd < 0) {
147
146
  MMKVError("fail to ASharedMemory_create %s with size %zu, errno:%s", name, size, strerror(errno));
147
+ } else {
148
+ MMKVInfo("ASharedMemory_create %s with size %zu, fd:%d", name, size, fd);
149
+ return fd;
148
150
  }
149
- } else {
151
+ } else if (g_android_api >= __ANDROID_API_O__) {
150
152
  MMKVWarning("fail to locate ASharedMemory_create() from loading libandroid.so");
151
153
  }
154
+
155
+ static AShmem_create_t regionFuncPtr =
156
+ (handle != nullptr) ? reinterpret_cast<AShmem_create_t>(dlsym(handle, "ashmem_create_region")) : nullptr;
157
+ if (regionFuncPtr) {
158
+ int fd = regionFuncPtr(name, size);
159
+ if (fd < 0) {
160
+ MMKVError("fail to ashmem_create_region %s with size %zu, errno:%s", name, size, strerror(errno));
161
+ } else {
162
+ MMKVInfo("ashmem_create_region %s with size %zu, fd:%d", name, size, fd);
163
+ return fd;
164
+ }
165
+ } else {
166
+ MMKVWarning("fail to locate ashmem_create_region() from loading libandroid.so");
167
+ }
152
168
  }
153
169
  #endif
170
+ int fd = open(ASHMEM_NAME_DEF, O_RDWR | O_CLOEXEC);
154
171
  if (fd < 0) {
155
- fd = open(ASHMEM_NAME_DEF, O_RDWR | O_CLOEXEC);
156
- if (fd < 0) {
157
- MMKVError("fail to open ashmem:%s, %s", name, strerror(errno));
158
- } else {
159
- if (ioctl(fd, ASHMEM_SET_NAME, name) != 0) {
160
- MMKVError("fail to set ashmem name:%s, %s", name, strerror(errno));
161
- } else if (ioctl(fd, ASHMEM_SET_SIZE, size) != 0) {
162
- MMKVError("fail to set ashmem:%s, size %zu, %s", name, size, strerror(errno));
163
- }
172
+ MMKVError("fail to open ashmem:%s, %s", name, strerror(errno));
173
+ } else {
174
+ if (ioctl(fd, ASHMEM_SET_NAME, name) != 0) {
175
+ MMKVError("fail to set ashmem name:%s, %s", name, strerror(errno));
176
+ } else if (ioctl(fd, ASHMEM_SET_SIZE, size) != 0) {
177
+ MMKVError("fail to set ashmem:%s, size %zu, %s", name, size, strerror(errno));
164
178
  }
165
179
  }
166
180
  return fd;