diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index e66f445e..72264201 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -55,22 +55,28 @@ add_library(core MMKVLog_Android.cpp CodedInputData.h CodedInputData.cpp + CodedInputData_OSX.cpp CodedOutputData.h CodedOutputData.cpp + CodedOutputData_OSX.cpp PBUtility.h PBUtility.cpp MiniPBCoder.h MiniPBCoder.cpp + MiniPBCoder_OSX.cpp MMBuffer.h MMBuffer.cpp InterProcessLock.h InterProcessLock.cpp + InterProcessLock_Win32.cpp MemoryFile.h MemoryFile.cpp MemoryFile_Android.cpp MemoryFile_Win32.cpp + MemoryFile_OSX.cpp ThreadLock.h ThreadLock.cpp + ThreadLock_Win32.cpp MMKVMetaInfo.hpp aes/AESCrypt.h aes/AESCrypt.cpp @@ -92,7 +98,6 @@ add_library(core crc32/zlib/crc32.h crc32/zlib/crc32.cpp MMKVPredef.h - ThreadLock_Win32.cpp InterProcessLock_Win32.cpp ) target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Core/CodedInputData.cpp b/Core/CodedInputData.cpp index d91901e2..44c169ed 100644 --- a/Core/CodedInputData.cpp +++ b/Core/CodedInputData.cpp @@ -85,6 +85,8 @@ bool CodedInputData::readBool() { return this->readRawVarint32() != 0; } +#ifndef MMKV_IOS_OR_MAC + string CodedInputData::readString() { int32_t size = this->readRawVarint32(); if (size <= (m_size - m_position) && size > 0) { @@ -98,6 +100,8 @@ string CodedInputData::readString() { } } +#endif + MMBuffer CodedInputData::readData() { int32_t size = this->readRawVarint32(); if (size < 0) { @@ -180,36 +184,6 @@ int8_t CodedInputData::readRawByte() { } #ifdef MMKV_IOS_OR_MAC -NSString *CodedInputData::readNSString() { - int32_t size = this->readRawVarint32(); - if (size <= (m_size - m_position) && size > 0) { - NSString *result = - [[[NSString alloc] initWithBytes:(m_ptr + m_position) length:size encoding:NSUTF8StringEncoding] - autorelease]; - m_position += size; - return result; - } else if (size == 0) { - return @""; - } else if (size < 0) { - throw length_error("InvalidProtocolBuffer negativeSize"); - } else { - throw out_of_range("InvalidProtocolBuffer truncatedMessage"); - } - return nil; -} - -NSData *CodedInputData::readNSData() { - int32_t size = this->readRawVarint32(); - if (size <= m_size - m_position && size > 0) { - NSData *result = [NSData dataWithBytes:(m_ptr + m_position) length:size]; - m_position += size; - return result; - } else if (size < 0) { - throw length_error("InvalidProtocolBuffer negativeSize"); - return nil; - } - return nil; -} #endif // MMKV_IOS_OR_MAC } // namespace mmkv diff --git a/Core/CodedInputData.h b/Core/CodedInputData.h index aeed5f47..b8150c04 100644 --- a/Core/CodedInputData.h +++ b/Core/CodedInputData.h @@ -65,12 +65,12 @@ public: int32_t readFixed32(); - std::string readString(); - MMBuffer readData(); -#ifdef MMKV_IOS_OR_MAC - NSString *readNSString(); +#ifndef MMKV_IOS_OR_MAC + std::string readString(); +#else + NSString *readString(); NSData *readNSData(); #endif }; diff --git a/Core/CodedInputData_OSX.cpp b/Core/CodedInputData_OSX.cpp new file mode 100644 index 00000000..64ed11de --- /dev/null +++ b/Core/CodedInputData_OSX.cpp @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making + * MMKV available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CodedInputData.h" + +#ifdef MMKV_IOS_OR_MAC + +# include "PBUtility.h" +# include +# include + +# if __has_feature(objc_arc) +# error This file must be compiled with MRC. Use -fno-objc-arc flag. +# endif + +using namespace std; + +namespace mmkv { + +NSString *CodedInputData::readString() { + int32_t size = this->readRawVarint32(); + if (size <= (m_size - m_position) && size > 0) { + NSString *result = + [[[NSString alloc] initWithBytes:(m_ptr + m_position) length:size encoding:NSUTF8StringEncoding] + autorelease]; + m_position += size; + return result; + } else if (size == 0) { + return @""; + } else if (size < 0) { + throw length_error("InvalidProtocolBuffer negativeSize"); + } else { + throw out_of_range("InvalidProtocolBuffer truncatedMessage"); + } + return nil; +} + +NSData *CodedInputData::readNSData() { + int32_t size = this->readRawVarint32(); + if (size <= m_size - m_position && size > 0) { + NSData *result = [NSData dataWithBytes:(m_ptr + m_position) length:size]; + m_position += size; + return result; + } else if (size < 0) { + throw length_error("InvalidProtocolBuffer negativeSize"); + return nil; + } + return nil; +} + +} // namespace mmkv + +#endif // MMKV_IOS_OR_MAC diff --git a/Core/CodedOutputData.cpp b/Core/CodedOutputData.cpp index cbceebce..d9404c87 100644 --- a/Core/CodedOutputData.cpp +++ b/Core/CodedOutputData.cpp @@ -74,6 +74,13 @@ void CodedOutputData::writeBool(bool value) { this->writeRawByte(static_cast(value ? 1 : 0)); } +void CodedOutputData::writeData(const MMBuffer &value) { + this->writeRawVarint32((int32_t) value.length()); + this->writeRawData(value); +} + +#ifndef MMKV_IOS_OR_MAC + void CodedOutputData::writeString(const string &value) { size_t numberOfBytes = value.size(); if (m_position + numberOfBytes > m_size) { @@ -86,25 +93,7 @@ void CodedOutputData::writeString(const string &value) { m_position += numberOfBytes; } -void CodedOutputData::writeData(const MMBuffer &value) { - this->writeRawVarint32((int32_t) value.length()); - this->writeRawData(value); -} - -#ifdef MMKV_IOS_OR_MAC -void CodedOutputData::writeString(__unsafe_unretained NSString *value) { - NSUInteger numberOfBytes = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - this->writeRawVarint32((int32_t) numberOfBytes); - [value getBytes:m_ptr + m_position - maxLength:numberOfBytes - usedLength:0 - encoding:NSUTF8StringEncoding - options:0 - range:NSMakeRange(0, value.length) - remainingRange:nullptr]; - m_position += numberOfBytes; -} -#endif +#endif // MMKV_IOS_OR_MAC size_t CodedOutputData::spaceLeft() { return int32_t(m_size - m_position); diff --git a/Core/CodedOutputData.h b/Core/CodedOutputData.h index 7db74b8d..a1207bd4 100644 --- a/Core/CodedOutputData.h +++ b/Core/CodedOutputData.h @@ -69,11 +69,11 @@ public: void writeBool(bool value); - void writeString(const std::string &value); - void writeData(const MMBuffer &value); -#ifdef MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + void writeString(const std::string &value); +#else void writeString(__unsafe_unretained NSString *value); #endif }; diff --git a/Core/CodedOutputData_OSX.cpp b/Core/CodedOutputData_OSX.cpp new file mode 100644 index 00000000..0b140e90 --- /dev/null +++ b/Core/CodedOutputData_OSX.cpp @@ -0,0 +1,53 @@ +/* + * Tencent is pleased to support the open source community by making + * MMKV available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CodedOutputData.h" + +#ifdef MMKV_IOS_OR_MAC + +# include "PBUtility.h" +# include +# include +# include + +# if __has_feature(objc_arc) +# error This file must be compiled with MRC. Use -fno-objc-arc flag. +# endif + +using namespace std; + +namespace mmkv { + +void CodedOutputData::writeString(__unsafe_unretained NSString *value) { + NSUInteger numberOfBytes = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + this->writeRawVarint32((int32_t) numberOfBytes); + [value getBytes:m_ptr + m_position + maxLength:numberOfBytes + usedLength:0 + encoding:NSUTF8StringEncoding + options:0 + range:NSMakeRange(0, value.length) + remainingRange:nullptr]; + m_position += numberOfBytes; +} + +} // namespace mmkv + +#endif // MMKV_IOS_OR_MAC diff --git a/Core/Core.xcodeproj/project.pbxproj b/Core/Core.xcodeproj/project.pbxproj index ae2089b7..10a8b982 100644 --- a/Core/Core.xcodeproj/project.pbxproj +++ b/Core/Core.xcodeproj/project.pbxproj @@ -38,6 +38,10 @@ CB95642A23AB2FCF00ACCD39 /* MemoryFile.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB95640E23AB2E9100ACCD39 /* MemoryFile.h */; }; CB95642B23AB2FDC00ACCD39 /* MMKVMetaInfo.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563EC23AB2E9100ACCD39 /* MMKVMetaInfo.hpp */; }; CBD723BF23B5C22800D3CDAF /* MMKV_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBD723F323B5E59800D3CDAF /* MemoryFile_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */; }; + CBD723F523B5E76200D3CDAF /* MiniPBCoder_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBD723F723B5FD9E00D3CDAF /* CodedInputData_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBD723F923B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -128,6 +132,10 @@ CB95641123AB2E9100ACCD39 /* MMKVLog.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MMKVLog.cpp; sourceTree = ""; }; CB95641223AB2E9100ACCD39 /* PBUtility.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = PBUtility.cpp; sourceTree = ""; }; CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = MMKV_OSX.cpp; sourceTree = ""; }; + CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = MemoryFile_OSX.cpp; sourceTree = ""; }; + CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = MiniPBCoder_OSX.cpp; sourceTree = ""; }; + CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = CodedInputData_OSX.cpp; sourceTree = ""; }; + CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = CodedOutputData_OSX.cpp; sourceTree = ""; }; CBF3450323B4BABA00168AC7 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ @@ -157,14 +165,18 @@ children = ( CB9563FC23AB2E9100ACCD39 /* aes */, CB9563E523AB2E9100ACCD39 /* crc32 */, + CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */, CB9563F923AB2E9100ACCD39 /* CodedInputData.cpp */, CB9563E423AB2E9100ACCD39 /* CodedInputData.h */, + CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */, CB9563EF23AB2E9100ACCD39 /* CodedOutputData.cpp */, CB95640C23AB2E9100ACCD39 /* CodedOutputData.h */, CB95641023AB2E9100ACCD39 /* InterProcessLock.cpp */, CB9563FB23AB2E9100ACCD39 /* InterProcessLock.h */, + CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */, CB9563F023AB2E9100ACCD39 /* MemoryFile.cpp */, CB95640E23AB2E9100ACCD39 /* MemoryFile.h */, + CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */, CB9563F523AB2E9100ACCD39 /* MiniPBCoder.cpp */, CB9563F123AB2E9100ACCD39 /* MiniPBCoder.h */, CB9563F823AB2E9100ACCD39 /* MMBuffer.cpp */, @@ -292,7 +304,9 @@ buildActionMask = 2147483647; files = ( CB95641823AB2E9100ACCD39 /* ThreadLock.cpp in Sources */, + CBD723F323B5E59800D3CDAF /* MemoryFile_OSX.cpp in Sources */, CB95641623AB2E9100ACCD39 /* MMKV.cpp in Sources */, + CBD723F523B5E76200D3CDAF /* MiniPBCoder_OSX.cpp in Sources */, CB95642023AB2E9100ACCD39 /* AESCrypt.cpp in Sources */, CB95641D23AB2E9100ACCD39 /* openssl_aes_cfb.cpp in Sources */, CB95641B23AB2E9100ACCD39 /* openssl_cfb128.cpp in Sources */, @@ -300,12 +314,14 @@ CB95641F23AB2E9100ACCD39 /* openssl_md5_dgst.cpp in Sources */, CB95641523AB2E9100ACCD39 /* MemoryFile.cpp in Sources */, CB95641A23AB2E9100ACCD39 /* CodedInputData.cpp in Sources */, + CBD723F923B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp in Sources */, CB95642223AB2E9100ACCD39 /* MMKVLog.cpp in Sources */, CB95642323AB2E9100ACCD39 /* PBUtility.cpp in Sources */, CB95641723AB2E9100ACCD39 /* MiniPBCoder.cpp in Sources */, CB95641E23AB2E9100ACCD39 /* openssl_md5_one.cpp in Sources */, CB95641C23AB2E9100ACCD39 /* openssl_aes_core.cpp in Sources */, CB95641923AB2E9100ACCD39 /* MMBuffer.cpp in Sources */, + CBD723F723B5FD9E00D3CDAF /* CodedInputData_OSX.cpp in Sources */, CBD723BF23B5C22800D3CDAF /* MMKV_OSX.cpp in Sources */, CB95642123AB2E9100ACCD39 /* InterProcessLock.cpp in Sources */, ); diff --git a/Core/MMKV.cpp b/Core/MMKV.cpp index 96067033..38249ee6 100644 --- a/Core/MMKV.cpp +++ b/Core/MMKV.cpp @@ -899,11 +899,12 @@ bool MMKV::reKey(const string &cryptKey) { return false; } +// TODO: this looks like wrong after iv changes void MMKV::checkReSetCryptKey(const string *cryptKey) { SCOPEDLOCK(m_lock); if (m_crypter) { - if (cryptKey) { + if (cryptKey && cryptKey->length() > 0) { string oldKey = this->cryptKey(); if (oldKey != *cryptKey) { MMKVInfo("setting new aes key"); @@ -923,7 +924,7 @@ void MMKV::checkReSetCryptKey(const string *cryptKey) { checkLoadData(); } } else { - if (cryptKey) { + if (cryptKey && cryptKey->length() > 0) { MMKVInfo("setting new aes key"); auto ptr = cryptKey->data(); m_crypter = new AESCrypt(ptr, cryptKey->length()); @@ -977,30 +978,6 @@ void MMKV::updateCRCDigest(const uint8_t *ptr, size_t length) { // set & get -bool MMKV::set(const char *value, MMKV_KEY_TYPE key) { - if (!value) { - removeValueForKey(key); - return true; - } - return set(string(value), key); -} - -bool MMKV::set(const string &value, MMKV_KEY_TYPE key) { - if (MMKV_IS_KEY_EMPTY(key)) { - return false; - } - auto data = MiniPBCoder::encodeDataWithObject(value); - return setDataForKey(std::move(data), key); -} - -bool MMKV::set(const MMBuffer &value, MMKV_KEY_TYPE key) { - if (MMKV_IS_KEY_EMPTY(key)) { - return false; - } - auto data = MiniPBCoder::encodeDataWithObject(value); - return setDataForKey(std::move(data), key); -} - bool MMKV::set(bool value, MMKV_KEY_TYPE key) { if (MMKV_IS_KEY_EMPTY(key)) { return false; @@ -1085,6 +1062,32 @@ bool MMKV::set(double value, MMKV_KEY_TYPE key) { return setDataForKey(std::move(data), key); } +#ifndef MMKV_IOS_OR_MAC + +bool MMKV::set(const char *value, MMKV_KEY_TYPE key) { + if (!value) { + removeValueForKey(key); + return true; + } + return set(string(value), key); +} + +bool MMKV::set(const string &value, MMKV_KEY_TYPE key) { + if (MMKV_IS_KEY_EMPTY(key)) { + return false; + } + auto data = MiniPBCoder::encodeDataWithObject(value); + return setDataForKey(std::move(data), key); +} + +bool MMKV::set(const MMBuffer &value, MMKV_KEY_TYPE key) { + if (MMKV_IS_KEY_EMPTY(key)) { + return false; + } + auto data = MiniPBCoder::encodeDataWithObject(value); + return setDataForKey(std::move(data), key); +} + bool MMKV::set(const vector &v, MMKV_KEY_TYPE key) { if (MMKV_IS_KEY_EMPTY(key)) { return false; @@ -1126,6 +1129,25 @@ MMBuffer MMKV::getBytes(MMKV_KEY_TYPE key) { return MMBuffer(0); } +bool MMKV::getVector(MMKV_KEY_TYPE key, vector &result) { + if (MMKV_IS_KEY_EMPTY(key)) { + return false; + } + SCOPEDLOCK(m_lock); + auto &data = getDataForKey(key); + if (data.length() > 0) { + try { + result = MiniPBCoder::decodeSet(data); + return true; + } catch (std::exception &exception) { + MMKVError("%s", exception.what()); + } + } + return false; +} + +#endif // MMKV_IOS_OR_MAC + bool MMKV::getBool(MMKV_KEY_TYPE key, bool defaultValue) { if (MMKV_IS_KEY_EMPTY(key)) { return defaultValue; @@ -1245,23 +1267,6 @@ double MMKV::getDouble(MMKV_KEY_TYPE key, double defaultValue) { return defaultValue; } -bool MMKV::getVector(MMKV_KEY_TYPE key, vector &result) { - if (MMKV_IS_KEY_EMPTY(key)) { - return false; - } - SCOPEDLOCK(m_lock); - auto &data = getDataForKey(key); - if (data.length() > 0) { - try { - result = MiniPBCoder::decodeSet(data); - return true; - } catch (std::exception &exception) { - MMKVError("%s", exception.what()); - } - } - return false; -} - size_t MMKV::getValueSize(MMKV_KEY_TYPE key, bool actualSize) { if (MMKV_IS_KEY_EMPTY(key)) { return 0; diff --git a/Core/MMKV.h b/Core/MMKV.h index 19db3b82..78a50670 100644 --- a/Core/MMKV.h +++ b/Core/MMKV.h @@ -202,14 +202,6 @@ public: bool set(double value, MMKV_KEY_TYPE key); - bool set(const char *value, MMKV_KEY_TYPE key); - - bool set(const std::string &value, MMKV_KEY_TYPE key); - - bool set(const mmkv::MMBuffer &value, MMKV_KEY_TYPE key); - - bool set(const std::vector &vector, MMKV_KEY_TYPE key); - // avoid unexpected type conversion (pointer to bool, etc) template bool set(T value, MMKV_KEY_TYPE key) = delete; @@ -218,6 +210,20 @@ public: bool set(NSObject *__unsafe_unretained obj, MMKV_KEY_TYPE key); NSObject *getObject(MMKV_KEY_TYPE key, Class cls); +#else + bool set(const char *value, MMKV_KEY_TYPE key); + + bool set(const std::string &value, MMKV_KEY_TYPE key); + + bool set(const mmkv::MMBuffer &value, MMKV_KEY_TYPE key); + + bool set(const std::vector &vector, MMKV_KEY_TYPE key); + + bool getString(MMKV_KEY_TYPE key, std::string &result); + + mmkv::MMBuffer getBytes(MMKV_KEY_TYPE key); + + bool getVector(MMKV_KEY_TYPE key, std::vector &result); #endif bool getBool(MMKV_KEY_TYPE key, bool defaultValue = false); @@ -234,12 +240,6 @@ public: double getDouble(MMKV_KEY_TYPE key, double defaultValue = 0); - bool getString(MMKV_KEY_TYPE key, std::string &result); - - mmkv::MMBuffer getBytes(MMKV_KEY_TYPE key); - - bool getVector(MMKV_KEY_TYPE key, std::vector &result); - size_t getValueSize(MMKV_KEY_TYPE key, bool acutalSize); int32_t writeValueToBuffer(MMKV_KEY_TYPE key, void *ptr, int32_t size); diff --git a/Core/MemoryFile.cpp b/Core/MemoryFile.cpp index 3b605560..3538a79d 100644 --- a/Core/MemoryFile.cpp +++ b/Core/MemoryFile.cpp @@ -299,27 +299,6 @@ int getPageSize() { return getpagesize(); } -# ifdef MMKV_IOS -void tryResetFileProtection(const string &path) { - @autoreleasepool { - NSString *nsPath = [NSString stringWithUTF8String:path.c_str()]; - NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:nsPath error:nullptr]; - NSString *protection = [attr valueForKey:NSFileProtectionKey]; - MMKVInfo("protection on [%@] is %@", nsPath, protection); - if ([protection isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] == NO) { - NSMutableDictionary *newAttr = [NSMutableDictionary dictionaryWithDictionary:attr]; - [newAttr setObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey]; - NSError *err = nil; - [[NSFileManager defaultManager] setAttributes:newAttr ofItemAtPath:nsPath error:&err]; - if (err != nil) { - MMKVError("fail to set attribute %@ on [%@]: %@", NSFileProtectionCompleteUntilFirstUserAuthentication, - nsPath, err); - } - } - } -} -# endif - } // namespace mmkv #endif // MMKV_WIN32 diff --git a/Core/MemoryFile_OSX.cpp b/Core/MemoryFile_OSX.cpp new file mode 100644 index 00000000..3235dc7f --- /dev/null +++ b/Core/MemoryFile_OSX.cpp @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making + * MMKV available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MemoryFile.h" + +#ifdef MMKV_IOS + +# include "MMKVLog.h" + +using namespace std; + +namespace mmkv { + +void tryResetFileProtection(const string &path) { + @autoreleasepool { + NSString *nsPath = [NSString stringWithUTF8String:path.c_str()]; + NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:nsPath error:nullptr]; + NSString *protection = [attr valueForKey:NSFileProtectionKey]; + MMKVInfo("protection on [%@] is %@", nsPath, protection); + if ([protection isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] == NO) { + NSMutableDictionary *newAttr = [NSMutableDictionary dictionaryWithDictionary:attr]; + [newAttr setObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey]; + NSError *err = nil; + [[NSFileManager defaultManager] setAttributes:newAttr ofItemAtPath:nsPath error:&err]; + if (err != nil) { + MMKVError("fail to set attribute %@ on [%@]: %@", NSFileProtectionCompleteUntilFirstUserAuthentication, + nsPath, err); + } + } + } +} + +} // namespace mmkv + +#endif // MMKV_IOS diff --git a/Core/MiniPBCoder.cpp b/Core/MiniPBCoder.cpp index 6f984990..c1f4cd3e 100644 --- a/Core/MiniPBCoder.cpp +++ b/Core/MiniPBCoder.cpp @@ -65,10 +65,6 @@ void MiniPBCoder::writeRootObject() { for (size_t index = 0, total = m_encodeItems->size(); index < total; index++) { PBEncodeItem *encodeItem = &(*m_encodeItems)[index]; switch (encodeItem->type) { - case PBEncodeItemType_String: { - m_outputData->writeString(*(encodeItem->value.strValue)); - break; - } case PBEncodeItemType_Data: { m_outputData->writeData(*(encodeItem->value.bufferValue)); break; @@ -77,7 +73,12 @@ void MiniPBCoder::writeRootObject() { m_outputData->writeRawVarint32(encodeItem->valueSize); break; } -#ifdef MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + case PBEncodeItemType_String: { + m_outputData->writeString(*(encodeItem->value.strValue)); + break; + } +#else case PBEncodeItemType_NSString: { m_outputData->writeRawVarint32(encodeItem->valueSize); if (encodeItem->valueSize > 0 && encodeItem->value.tmpObjectValue != nullptr) { @@ -110,20 +111,6 @@ void MiniPBCoder::writeRootObject() { } } -size_t MiniPBCoder::prepareObjectForEncode(const string &str) { - m_encodeItems->push_back(PBEncodeItem()); - PBEncodeItem *encodeItem = &(m_encodeItems->back()); - size_t index = m_encodeItems->size() - 1; - { - encodeItem->type = PBEncodeItemType_String; - encodeItem->value.strValue = &str; - encodeItem->valueSize = static_cast(str.size()); - } - encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; - - return index; -} - size_t MiniPBCoder::prepareObjectForEncode(const MMBuffer &buffer) { m_encodeItems->push_back(PBEncodeItem()); PBEncodeItem *encodeItem = &(m_encodeItems->back()); @@ -138,35 +125,13 @@ size_t MiniPBCoder::prepareObjectForEncode(const MMBuffer &buffer) { return index; } -size_t MiniPBCoder::prepareObjectForEncode(const vector &v) { - m_encodeItems->push_back(PBEncodeItem()); - PBEncodeItem *encodeItem = &(m_encodeItems->back()); - size_t index = m_encodeItems->size() - 1; - { - encodeItem->type = PBEncodeItemType_Container; - encodeItem->value.strValue = nullptr; - - for (const auto &str : v) { - size_t itemIndex = prepareObjectForEncode(str); - if (itemIndex < m_encodeItems->size()) { - (*m_encodeItems)[index].valueSize += (*m_encodeItems)[itemIndex].compiledSize; - } - } - - encodeItem = &(*m_encodeItems)[index]; - } - encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; - - return index; -} - size_t MiniPBCoder::prepareObjectForEncode(const MMKVMap &map) { m_encodeItems->push_back(PBEncodeItem()); PBEncodeItem *encodeItem = &(m_encodeItems->back()); size_t index = m_encodeItems->size() - 1; { encodeItem->type = PBEncodeItemType_Container; - encodeItem->value.strValue = nullptr; + encodeItem->value.bufferValue = nullptr; for (const auto &itr : map) { const auto &key = itr.first; @@ -198,47 +163,9 @@ size_t MiniPBCoder::prepareObjectForEncode(const MMKVMap &map) { return index; } -#ifdef MMKV_IOS_OR_MAC - -size_t MiniPBCoder::prepareObjectForEncode(__unsafe_unretained NSObject *obj) { - if (!obj) { - return m_encodeItems->size(); - } - m_encodeItems->push_back(PBEncodeItem()); - PBEncodeItem *encodeItem = &(m_encodeItems->back()); - size_t index = m_encodeItems->size() - 1; - - if ([obj isKindOfClass:[NSString class]]) { - NSString *str = (NSString *) obj; - encodeItem->type = PBEncodeItemType_NSString; - NSData *buffer = [[str dataUsingEncoding:NSUTF8StringEncoding] retain]; - encodeItem->value.tmpObjectValue = (__bridge void *) buffer; - encodeItem->valueSize = static_cast(buffer.length); - } else if ([obj isKindOfClass:[NSDate class]]) { - NSDate *oDate = (NSDate *) obj; - encodeItem->type = PBEncodeItemType_NSDate; - encodeItem->value.objectValue = (__bridge void *) oDate; - encodeItem->valueSize = pbDoubleSize(oDate.timeIntervalSince1970); - encodeItem->compiledSize = encodeItem->valueSize; - return index; // double has fixed compilesize - } else if ([obj isKindOfClass:[NSData class]]) { - NSData *oData = (NSData *) obj; - encodeItem->type = PBEncodeItemType_NSData; - encodeItem->value.objectValue = (__bridge void *) oData; - encodeItem->valueSize = static_cast(oData.length); - } else { - m_encodeItems->pop_back(); - MMKVError("%@ not recognized", NSStringFromClass(obj.class)); - return m_encodeItems->size(); - } - encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; - - return index; -} - -MMBuffer MiniPBCoder::getEncodeData(__unsafe_unretained NSObject *obj) { +MMBuffer MiniPBCoder::getEncodeData(const MMKVMap &map) { m_encodeItems = new vector(); - size_t index = prepareObjectForEncode(obj); + size_t index = prepareObjectForEncode(map); PBEncodeItem *oItem = (index < m_encodeItems->size()) ? &(*m_encodeItems)[index] : nullptr; if (oItem && oItem->compiledSize > 0) { m_outputBuffer = new MMBuffer(oItem->compiledSize); @@ -247,10 +174,46 @@ MMBuffer MiniPBCoder::getEncodeData(__unsafe_unretained NSObject *obj) { writeRootObject(); } - return move(*m_outputBuffer); + return std::move(*m_outputBuffer); } -#endif // MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + +size_t MiniPBCoder::prepareObjectForEncode(const string &str) { + m_encodeItems->push_back(PBEncodeItem()); + PBEncodeItem *encodeItem = &(m_encodeItems->back()); + size_t index = m_encodeItems->size() - 1; + { + encodeItem->type = PBEncodeItemType_String; + encodeItem->value.strValue = &str; + encodeItem->valueSize = static_cast(str.size()); + } + encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; + + return index; +} + +size_t MiniPBCoder::prepareObjectForEncode(const vector &v) { + m_encodeItems->push_back(PBEncodeItem()); + PBEncodeItem *encodeItem = &(m_encodeItems->back()); + size_t index = m_encodeItems->size() - 1; + { + encodeItem->type = PBEncodeItemType_Container; + encodeItem->value.bufferValue = nullptr; + + for (const auto &str : v) { + size_t itemIndex = prepareObjectForEncode(str); + if (itemIndex < m_encodeItems->size()) { + (*m_encodeItems)[index].valueSize += (*m_encodeItems)[itemIndex].compiledSize; + } + } + + encodeItem = &(*m_encodeItems)[index]; + } + encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; + + return index; +} MMBuffer MiniPBCoder::getEncodeData(const string &str) { m_encodeItems = new vector(); @@ -294,22 +257,6 @@ MMBuffer MiniPBCoder::getEncodeData(const vector &v) { return move(*m_outputBuffer); } -MMBuffer MiniPBCoder::getEncodeData(const MMKVMap &map) { - m_encodeItems = new vector(); - size_t index = prepareObjectForEncode(map); - PBEncodeItem *oItem = (index < m_encodeItems->size()) ? &(*m_encodeItems)[index] : nullptr; - if (oItem && oItem->compiledSize > 0) { - m_outputBuffer = new MMBuffer(oItem->compiledSize); - m_outputData = new CodedOutputData(m_outputBuffer->getPtr(), m_outputBuffer->length()); - - writeRootObject(); - } - - return std::move(*m_outputBuffer); -} - -// decode - string MiniPBCoder::decodeOneString() { return m_inputData->readString(); } @@ -339,22 +286,6 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t size, bool greedy) { unused(length); } while (!m_inputData->isAtEnd()) { -#ifdef MMKV_IOS_OR_MAC - const auto &key = m_inputData->readNSString(); - if (key.length > 0) { - auto value = m_inputData->readData(); - if (value.length() > 0) { - dictionary[key] = move(value); - [key retain]; - } else { - auto itr = dictionary.find(key); - if (itr != dictionary.end()) { - dictionary.erase(itr); - [itr->first release]; - } - } - } -#else const auto &key = m_inputData->readString(); if (key.length() > 0) { auto value = m_inputData->readData(); @@ -364,7 +295,6 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t size, bool greedy) { dictionary.erase(key); } } -#endif } }; @@ -379,11 +309,6 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t size, bool greedy) { MMKVMap tmpDic; block(tmpDic); dic.swap(tmpDic); -#ifdef MMKV_IOS_OR_MAC - for (auto &pair : tmpDic) { - [pair.first release]; - } -#endif } catch (std::exception &exception) { MMKVError("%s", exception.what()); } @@ -400,6 +325,13 @@ MMBuffer MiniPBCoder::decodeBytes(const MMBuffer &oData) { return oCoder.decodeOneBytes(); } +vector MiniPBCoder::decodeSet(const MMBuffer &oData) { + MiniPBCoder oCoder(&oData); + return oCoder.decodeOneSet(); +} + +#endif // MMKV_IOS_OR_MAC + void MiniPBCoder::decodeMap(MMKVMap &dic, const MMBuffer &oData, size_t size) { MiniPBCoder oCoder(&oData); oCoder.decodeOneMap(dic, size, false); @@ -410,69 +342,4 @@ void MiniPBCoder::greedyDecodeMap(MMKVMap &dic, const MMBuffer &oData, size_t si oCoder.decodeOneMap(dic, size, true); } -vector MiniPBCoder::decodeSet(const MMBuffer &oData) { - MiniPBCoder oCoder(&oData); - return oCoder.decodeOneSet(); -} - -#ifdef MMKV_IOS_OR_MAC - -NSObject *MiniPBCoder::decodeObject(const MMBuffer &oData, Class cls) { - if (!cls || oData.length() == 0) { - return nil; - } - CodedInputData input(oData.getPtr(), static_cast(oData.length())); - if (cls == [NSString class]) { - return input.readNSString(); - } else if (cls == [NSMutableString class]) { - return [NSMutableString stringWithString:input.readNSString()]; - } else if (cls == [NSData class]) { - return input.readNSData(); - } else if (cls == [NSMutableData class]) { - return [NSMutableData dataWithData:input.readNSData()]; - } else if (cls == [NSDate class]) { - return [NSDate dateWithTimeIntervalSince1970:input.readDouble()]; - } else { - MMKVError("%@ not recognized", NSStringFromClass(cls)); - } - - return nil; -} - -bool MiniPBCoder::isCompatibleObject(NSObject *obj) { - if ([obj isKindOfClass:[NSString class]]) { - return true; - } - if ([obj isKindOfClass:[NSData class]]) { - return true; - } - if ([obj isKindOfClass:[NSDate class]]) { - return true; - } - - return false; -} - -bool MiniPBCoder::isCompatibleClass(Class cls) { - if (cls == [NSString class]) { - return true; - } - if (cls == [NSMutableString class]) { - return true; - } - if (cls == [NSData class]) { - return true; - } - if (cls == [NSMutableData class]) { - return true; - } - if (cls == [NSDate class]) { - return true; - } - - return false; -} - -#endif // MMKV_IOS_OR_MAC - } // namespace mmkv diff --git a/Core/MiniPBCoder.h b/Core/MiniPBCoder.h index f43397e8..76dc8331 100644 --- a/Core/MiniPBCoder.h +++ b/Core/MiniPBCoder.h @@ -50,22 +50,26 @@ private: ~MiniPBCoder(); void writeRootObject(); - size_t prepareObjectForEncode(const std::string &str); - size_t prepareObjectForEncode(const MMBuffer &buffer); - size_t prepareObjectForEncode(const std::vector &vector); + size_t prepareObjectForEncode(const MMKVMap &map); + size_t prepareObjectForEncode(const MMBuffer &buffer); + + MMBuffer getEncodeData(const MMKVMap &map); + + void decodeOneMap(MMKVMap &dic, size_t size, bool greedy); + +#ifndef MMKV_IOS_OR_MAC + size_t prepareObjectForEncode(const std::string &str); + size_t prepareObjectForEncode(const std::vector &vector); MMBuffer getEncodeData(const std::string &str); MMBuffer getEncodeData(const MMBuffer &buffer); MMBuffer getEncodeData(const std::vector &vector); - MMBuffer getEncodeData(const MMKVMap &map); std::string decodeOneString(); MMBuffer decodeOneBytes(); std::vector decodeOneSet(); - void decodeOneMap(MMKVMap &dic, size_t size, bool greedy); - -#ifdef MMKV_IOS_OR_MAC +#else // NSString, NSData, NSDate size_t prepareObjectForEncode(__unsafe_unretained NSObject *obj); MMBuffer getEncodeData(__unsafe_unretained NSObject *obj); @@ -83,19 +87,19 @@ public: } } - static std::string decodeString(const MMBuffer &oData); - - static MMBuffer decodeBytes(const MMBuffer &oData); - - static std::vector decodeSet(const MMBuffer &oData); - // return empty result if there's any error static void decodeMap(MMKVMap &dic, const MMBuffer &oData, size_t size = 0); // decode as much data as possible before any error happens static void greedyDecodeMap(MMKVMap &dic, const MMBuffer &oData, size_t size = 0); -#ifdef MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + static std::string decodeString(const MMBuffer &oData); + + static MMBuffer decodeBytes(const MMBuffer &oData); + + static std::vector decodeSet(const MMBuffer &oData); +#else // NSString, NSData, NSDate static NSObject *decodeObject(const MMBuffer &oData, Class cls); diff --git a/Core/MiniPBCoder_OSX.cpp b/Core/MiniPBCoder_OSX.cpp new file mode 100644 index 00000000..f181448b --- /dev/null +++ b/Core/MiniPBCoder_OSX.cpp @@ -0,0 +1,193 @@ +/* + * Tencent is pleased to support the open source community by making + * MMKV available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MiniPBCoder.h" + +#ifdef MMKV_IOS_OR_MAC + +# include "CodedInputData.h" +# include "CodedOutputData.h" +# include "MMBuffer.h" +# include "PBEncodeItem.hpp" +# include "PBUtility.h" +# include +# include + +# if __has_feature(objc_arc) +# error This file must be compiled with MRC. Use -fno-objc-arc flag. +# endif + +using namespace std; + +namespace mmkv { + +size_t MiniPBCoder::prepareObjectForEncode(__unsafe_unretained NSObject *obj) { + if (!obj) { + return m_encodeItems->size(); + } + m_encodeItems->push_back(PBEncodeItem()); + PBEncodeItem *encodeItem = &(m_encodeItems->back()); + size_t index = m_encodeItems->size() - 1; + + if ([obj isKindOfClass:[NSString class]]) { + NSString *str = (NSString *) obj; + encodeItem->type = PBEncodeItemType_NSString; + NSData *buffer = [[str dataUsingEncoding:NSUTF8StringEncoding] retain]; + encodeItem->value.tmpObjectValue = (__bridge void *) buffer; + encodeItem->valueSize = static_cast(buffer.length); + } else if ([obj isKindOfClass:[NSDate class]]) { + NSDate *oDate = (NSDate *) obj; + encodeItem->type = PBEncodeItemType_NSDate; + encodeItem->value.objectValue = (__bridge void *) oDate; + encodeItem->valueSize = pbDoubleSize(oDate.timeIntervalSince1970); + encodeItem->compiledSize = encodeItem->valueSize; + return index; // double has fixed compilesize + } else if ([obj isKindOfClass:[NSData class]]) { + NSData *oData = (NSData *) obj; + encodeItem->type = PBEncodeItemType_NSData; + encodeItem->value.objectValue = (__bridge void *) oData; + encodeItem->valueSize = static_cast(oData.length); + } else { + m_encodeItems->pop_back(); + MMKVError("%@ not recognized", NSStringFromClass(obj.class)); + return m_encodeItems->size(); + } + encodeItem->compiledSize = pbRawVarint32Size(encodeItem->valueSize) + encodeItem->valueSize; + + return index; +} + +void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t size, bool greedy) { + auto block = [size, this](MMKVMap &dictionary) { + if (size == 0) { + auto length = m_inputData->readInt32(); + unused(length); + } + while (!m_inputData->isAtEnd()) { + const auto &key = m_inputData->readString(); + if (key.length > 0) { + auto value = m_inputData->readData(); + if (value.length() > 0) { + dictionary[key] = move(value); + [key retain]; + } else { + auto itr = dictionary.find(key); + if (itr != dictionary.end()) { + dictionary.erase(itr); + [itr->first release]; + } + } + } + } + }; + + if (greedy) { + try { + block(dic); + } catch (std::exception &exception) { + MMKVError("%s", exception.what()); + } + } else { + try { + MMKVMap tmpDic; + block(tmpDic); + dic.swap(tmpDic); + for (auto &pair : tmpDic) { + [pair.first release]; + } + } catch (std::exception &exception) { + MMKVError("%s", exception.what()); + } + } +} + +MMBuffer MiniPBCoder::getEncodeData(__unsafe_unretained NSObject *obj) { + m_encodeItems = new vector(); + size_t index = prepareObjectForEncode(obj); + PBEncodeItem *oItem = (index < m_encodeItems->size()) ? &(*m_encodeItems)[index] : nullptr; + if (oItem && oItem->compiledSize > 0) { + m_outputBuffer = new MMBuffer(oItem->compiledSize); + m_outputData = new CodedOutputData(m_outputBuffer->getPtr(), m_outputBuffer->length()); + + writeRootObject(); + } + + return move(*m_outputBuffer); +} + +NSObject *MiniPBCoder::decodeObject(const MMBuffer &oData, Class cls) { + if (!cls || oData.length() == 0) { + return nil; + } + CodedInputData input(oData.getPtr(), static_cast(oData.length())); + if (cls == [NSString class]) { + return input.readString(); + } else if (cls == [NSMutableString class]) { + return [NSMutableString stringWithString:input.readString()]; + } else if (cls == [NSData class]) { + return input.readNSData(); + } else if (cls == [NSMutableData class]) { + return [NSMutableData dataWithData:input.readNSData()]; + } else if (cls == [NSDate class]) { + return [NSDate dateWithTimeIntervalSince1970:input.readDouble()]; + } else { + MMKVError("%@ not recognized", NSStringFromClass(cls)); + } + + return nil; +} + +bool MiniPBCoder::isCompatibleObject(NSObject *obj) { + if ([obj isKindOfClass:[NSString class]]) { + return true; + } + if ([obj isKindOfClass:[NSData class]]) { + return true; + } + if ([obj isKindOfClass:[NSDate class]]) { + return true; + } + + return false; +} + +bool MiniPBCoder::isCompatibleClass(Class cls) { + if (cls == [NSString class]) { + return true; + } + if (cls == [NSMutableString class]) { + return true; + } + if (cls == [NSData class]) { + return true; + } + if (cls == [NSMutableData class]) { + return true; + } + if (cls == [NSDate class]) { + return true; + } + + return false; +} + +} // namespace mmkv + +#endif // MMKV_IOS_OR_MAC diff --git a/Core/PBEncodeItem.hpp b/Core/PBEncodeItem.hpp index e8e31d6b..8920dd20 100644 --- a/Core/PBEncodeItem.hpp +++ b/Core/PBEncodeItem.hpp @@ -32,10 +32,11 @@ namespace mmkv { enum PBEncodeItemType { PBEncodeItemType_None, - PBEncodeItemType_String, PBEncodeItemType_Data, PBEncodeItemType_Container, -#ifdef MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + PBEncodeItemType_String, +#else PBEncodeItemType_NSString, PBEncodeItemType_NSData, PBEncodeItemType_NSDate, @@ -47,9 +48,10 @@ struct PBEncodeItem { uint32_t compiledSize; uint32_t valueSize; union { - const std::string *strValue; const MMBuffer *bufferValue; -#ifdef MMKV_IOS_OR_MAC +#ifndef MMKV_IOS_OR_MAC + const std::string *strValue; +#else void *objectValue; void *tmpObjectValue; // this object should release on dealloc #endif diff --git a/iOS/MMKV/MMKV/MMKV.h b/iOS/MMKV/MMKV/MMKV.h index e705a0b5..334b266e 100644 --- a/iOS/MMKV/MMKV/MMKV.h +++ b/iOS/MMKV/MMKV/MMKV.h @@ -75,6 +75,9 @@ NS_ASSUME_NONNULL_BEGIN /// @param relativePath custom path of the file, `NSDocumentDirectory/mmkv` by default + (nullable instancetype)mmkvWithID:(NSString *)mmapID cryptKey:(nullable NSData *)cryptKey relativePath:(nullable NSString *)relativePath NS_SWIFT_NAME(init(mmapID:cryptKey:relativePath:)); +// call this on applicationWillTerminate, it is fine if you don't call ++ (void)onExit; + + (NSString *)mmkvBasePath; // if you want to change the base path, do it BEFORE getting any MMKV instance @@ -84,6 +87,10 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)reKey:(nullable NSData *)newKey NS_SWIFT_NAME(reset(cryptKey:)); - (nullable NSData *)cryptKey; +// just reset cryptKey (will not encrypt or decrypt anything) +// usually you should call this method after other process reKey() the inter-process mmkv +- (void)checkReSetCryptKey:(nullable NSData *)cryptKey NS_SWIFT_NAME(checkReSet(cryptKey:)); + - (BOOL)setObject:(nullable NSObject *)object forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); - (BOOL)setBool:(BOOL)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); @@ -142,6 +149,10 @@ NS_ASSUME_NONNULL_BEGIN // Note: might be a little bigger than value's length - (size_t)getValueSizeForKey:(NSString *)key NS_SWIFT_NAME(valueSize(forKey:)); +// return size written into buffer +// return -1 on any error +- (int32_t)writeValueForKey:(NSString *)key toBuffer:(NSMutableData *)buffer NS_SWIFT_NAME(writeValue(forKey:buffer:)); + - (BOOL)containsKey:(NSString *)key NS_SWIFT_NAME(contains(key:)); - (size_t)count; @@ -177,6 +188,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)sync; - (void)async; +// check if content changed by other process +- (void)checkContentChanged; + // for CrashProtected Only!! + (BOOL)isFileValid:(NSString *)mmapID NS_SWIFT_NAME(isFileValid(for:)); + (BOOL)isFileValid:(NSString *)mmapID relativePath:(nullable NSString *)path NS_SWIFT_NAME(isFileValid(for:relativePath:)); diff --git a/iOS/MMKV/MMKV/libMMKV.mm b/iOS/MMKV/MMKV/libMMKV.mm index c91a3305..71615637 100644 --- a/iOS/MMKV/MMKV/libMMKV.mm +++ b/iOS/MMKV/MMKV/libMMKV.mm @@ -264,6 +264,14 @@ static BOOL g_hasCalledInitializeMMKV = NO; return m_mmkv->reKey(key); } +- (void)checkReSetCryptKey:(nullable NSData *)cryptKey { + string key; + if (cryptKey.length > 0) { + key = string((char *) cryptKey.bytes, cryptKey.length); + } + m_mmkv->checkReSetCryptKey(&key); +} + #pragma mark - set & get - (BOOL)setObject:(nullable NSObject *)object forKey:(NSString *)key { @@ -409,6 +417,10 @@ static BOOL g_hasCalledInitializeMMKV = NO; return m_mmkv->getValueSize(key, false); } +- (int32_t)writeValueForKey:(NSString *)key toBuffer:(NSMutableData *)buffer { + return m_mmkv->writeValueToBuffer(key, buffer.mutableBytes, static_cast(buffer.length)); +} + #pragma mark - enumerate - (BOOL)containsKey:(NSString *)key { @@ -453,6 +465,18 @@ static BOOL g_hasCalledInitializeMMKV = NO; m_mmkv->sync(MMKV_ASYNC); } +- (void)checkContentChanged { + m_mmkv->checkContentChanged(); +} + ++ (void)onExit { + SCOPEDLOCK(g_lock); + + [g_instanceDic removeAllObjects]; + + mmkv::MMKV::onExit(); +} + + (NSString *)mmkvBasePath { if (g_basePath.length > 0) { return g_basePath;