Files
MMKV/Core/MMKVPredef.h
T
2025-04-18 21:52:05 +08:00

331 lines
8.3 KiB
C++
Executable File

/*
* 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.
*/
#ifndef MMKV_SRC_MMKVPREDEF_H
#define MMKV_SRC_MMKVPREDEF_H
// disable encryption & decryption to reduce some code
// #define MMKV_DISABLE_CRYPT
//#define MMKV_DISABLE_FLUTTER
// using POSIX implementation
//#define FORCE_POSIX
#ifdef __cplusplus
#include <string>
#include <vector>
#include <unordered_map>
constexpr auto MMKV_VERSION = "v2.1.0";
#ifdef DEBUG
# define MMKV_DEBUG
#endif
#ifdef NDEBUG
# undef MMKV_DEBUG
#endif
#if __cplusplus>=202002L
# define MMKV_HAS_CPP20
#endif
#ifdef __ANDROID__
# ifdef FORCE_POSIX
# define MMKV_POSIX
# else
# define MMKV_ANDROID
# endif
#elif __OHOS__
# ifdef FORCE_POSIX
# define MMKV_POSIX
# else
# define MMKV_ANDROID
# define MMKV_OHOS
#endif
#elif __APPLE__
# ifdef FORCE_POSIX
# define MMKV_POSIX
# else
# define MMKV_APPLE
# ifdef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
# define MMKV_IOS
# elif __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__
# define MMKV_WATCH
# else
# define MMKV_MAC
# endif
# endif // FORCE_POSIX
#elif __linux__ || __unix__
# define MMKV_POSIX
# if __linux__
# define MMKV_LINUX
# endif
#elif _WIN32
# define MMKV_WIN32
#endif
#ifdef MMKV_WIN32
# if !defined(_WIN32_WINNT)
# define _WIN32_WINNT _WIN32_WINNT_WINXP
# endif
# include <SDKDDKVer.h>
// Exclude rarely-used stuff from Windows headers
# define WIN32_LEAN_AND_MEAN
// Windows Header Files
# include <windows.h>
constexpr auto MMKV_PATH_SLASH = L"\\";
# define MMKV_PATH_FORMAT "%ls"
using MMKVFileHandle_t = HANDLE;
#define MMKVFileHandleInvalidValue INVALID_HANDLE_VALUE
using MMKVPath_t = std::wstring;
extern MMKVPath_t string2MMKVPath_t(const std::string &str);
extern std::string MMKVPath_t2String(const MMKVPath_t &str);
# ifndef MMKV_EMBED_ZLIB
# define MMKV_EMBED_ZLIB 1
# endif
#else // MMKV_WIN32
constexpr auto MMKV_PATH_SLASH = "/";
# define MMKV_PATH_FORMAT "%s"
using MMKVFileHandle_t = int;
constexpr MMKVFileHandle_t MMKVFileHandleInvalidValue = -1;
using MMKVPath_t = std::string;
# define string2MMKVPath_t(str) (str)
# define MMKVPath_t2String(str) (str)
# ifndef MMKV_EMBED_ZLIB
# define MMKV_EMBED_ZLIB 0
# endif
#endif // MMKV_WIN32
#ifdef MMKV_ANDROID
#define MMKV_EXPORT __attribute__((visibility("default")))
#else
#define MMKV_EXPORT
#endif
#ifdef MMKV_APPLE
#ifdef __OBJC__
# import <Foundation/Foundation.h>
using MMKVLog_t = NSString *;
#else
using MMKVLog_t = void *;
#endif
# define MMKV_NAMESPACE_BEGIN namespace mmkv {
# define MMKV_NAMESPACE_END }
# define MMKV_NAMESPACE_PREFIX mmkv
#else
# define MMKV_NAMESPACE_BEGIN
# define MMKV_NAMESPACE_END
# define MMKV_NAMESPACE_PREFIX
using MMKVLog_t = const std::string &;
#endif // MMKV_APPLE
MMKV_NAMESPACE_BEGIN
enum MMKVLogLevel : int {
MMKVLogDebug = 0, // not available for release/product build
MMKVLogInfo = 1, // default level
MMKVLogWarning,
MMKVLogError,
MMKVLogNone, // special level used to disable all log messages
};
enum MMKVRecoverStrategic : int {
OnErrorDiscard = 0,
OnErrorRecover,
};
enum MMKVErrorType : int {
MMKVCRCCheckFail = 0,
MMKVFileLength,
};
enum SyncFlag : bool { MMKV_SYNC = true, MMKV_ASYNC = false };
MMKV_NAMESPACE_END
namespace mmkv {
typedef void (*LogHandler)(MMKVLogLevel level, const char *file, int line, const char *function, MMKVLog_t message);
// by default MMKV will discard all datas on failure
// return `OnErrorRecover` to recover any data from file
typedef MMKVRecoverStrategic (*ErrorHandler)(const std::string &mmapID, MMKVErrorType errorType);
// called when content is changed by other process
// doesn't guarantee real-time notification
typedef void (*ContentChangeHandler)(const std::string &mmapID);
extern MMKV_EXPORT size_t DEFAULT_MMAP_SIZE;
#define DEFAULT_MMAP_ID "mmkv.default"
class MMBuffer;
struct KeyValueHolder;
#ifdef MMKV_DISABLE_CRYPT
using KeyValueHolderCrypt = KeyValueHolder;
#else
struct KeyValueHolderCrypt;
#endif
#ifdef MMKV_APPLE
#ifdef __OBJC__
struct HybridStringCP {
NSString *str;
HybridStringCP(std::string_view cpp);
~HybridStringCP();
};
struct HybridString {
NSString *str;
HybridString(std::string_view cpp);
~HybridString();
};
struct KeyHasher {
// enables heterogeneous lookup
using is_transparent = void;
size_t operator()(NSString *key) const { return key.hash; }
};
struct KeyEqualer {
// enables heterogeneous lookup
using is_transparent = void;
bool operator()(NSString *left, NSString *right) const {
if (left == right) {
return true;
}
return ([left isEqualToString:right] == YES);
}
};
using MMKVVector = std::vector<std::pair<NSString *, mmkv::MMBuffer>>;
using MMKVMap = std::unordered_map<NSString *, mmkv::KeyValueHolder, KeyHasher, KeyEqualer>;
using MMKVMapCrypt = std::unordered_map<NSString *, mmkv::KeyValueHolderCrypt, KeyHasher, KeyEqualer>;
#else // type erase for pure C++ users
using MMKVVector = std::vector<std::pair<void *, mmkv::MMBuffer>>;
using MMKVMap = std::unordered_map<void *, mmkv::KeyValueHolder>;
using MMKVMapCrypt = std::unordered_map<void *, mmkv::KeyValueHolderCrypt>;
#endif // __OBJC__
#else // !MMKV_APPLE
struct KeyHasher {
// enables heterogeneous lookup
using is_transparent = void;
std::size_t operator()(const std::string_view& str) const {
return std::hash<std::string_view>{}(str);
}
std::size_t operator()(const std::string& str) const {
return std::hash<std::string>{}(str);
}
};
struct KeyEqualer {
// enables heterogeneous lookup
using is_transparent = void;
bool operator()(const std::string_view& lhs, const std::string_view& rhs) const {
return lhs == rhs;
}
bool operator()(const std::string& lhs, const std::string& rhs) const {
return lhs == rhs;
}
};
using MMKVVector = std::vector<std::pair<std::string, mmkv::MMBuffer>>;
using MMKVMap = std::unordered_map<std::string, mmkv::KeyValueHolder, KeyHasher, KeyEqualer>;
using MMKVMapCrypt = std::unordered_map<std::string, mmkv::KeyValueHolderCrypt, KeyHasher, KeyEqualer>;
#endif // MMKV_APPLE
template <typename T>
void unused(const T &) {}
constexpr size_t AES_KEY_LEN = 16;
constexpr size_t AES_KEY_BITSET_LEN = 128;
} // namespace mmkv
#ifdef MMKV_DEBUG
# include <cassert>
# define MMKV_ASSERT(var) assert(var)
#else
# define MMKV_ASSERT(var) mmkv::unused(var)
#endif
#endif //cplus-plus
#ifndef MMKV_WIN32
# ifndef likely
# define mmkv_unlikely(x) (__builtin_expect(bool(x), 0))
# define mmkv_likely(x) (__builtin_expect(bool(x), 1))
# endif
#else
# ifndef likely
# define mmkv_unlikely(x) (x)
# define mmkv_likely(x) (x)
# endif
#endif
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define MMKV_ABI "armeabi-v7a/NEON (hard-float)"
#else
#define MMKV_ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define MMKV_ABI "armeabi-v7a (hard-float)"
#else
#define MMKV_ABI "armeabi-v7a"
#endif
#endif
#else
#define MMKV_ABI "armeabi"
#endif
#elif defined(__i386__) || defined(_M_IX86)
#define MMKV_ABI "x86"
#elif defined(__x86_64__) || defined(_M_X64)
#define MMKV_ABI "x86_64"
#elif defined(__mips64)
#define MMKV_ABI "mips64"
#elif defined(__mips__)
#define MMKV_ABI "mips"
#elif defined(__aarch64__) || defined(_M_ARM64)
#define MMKV_ABI "arm64-v8a"
#else
#define MMKV_ABI "unknown"
#endif
#endif //MMKV_SRC_MMKVPREDEF_H