/* * Tencent is pleased to support the open source community by making * MMKV available. * * Copyright (C) 2020 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 KeyValueHolder_hpp #define KeyValueHolder_hpp #ifdef __cplusplus #include "MMBuffer.h" #include "aes/AESCrypt.h" namespace mmkv { #pragma pack(push, 1) struct KeyValueHolder { uint16_t computedKVSize; // internal use only uint16_t keySize; uint32_t valueSize; uint32_t offset; KeyValueHolder() = default; KeyValueHolder(uint32_t keyLength, uint32_t valueLength, uint32_t offset); MMBuffer toMMBuffer(const void *basePtr) const; }; #ifndef MMKV_DISABLE_CRYPT enum KeyValueHolderType : uint8_t { KeyValueHolderType_Direct, // store value directly KeyValueHolderType_Memory, // store value in the heap memory KeyValueHolderType_Offset, // store value by offset }; // kv holder for encrypted mmkv struct KeyValueHolderCrypt { KeyValueHolderType type = KeyValueHolderType_Direct; union { // store value by offset struct { uint8_t pbKeyValueSize; // size needed to encode keySize & valueSize uint16_t keySize; uint32_t valueSize; uint32_t offset; AESCryptStatus cryptStatus; }; // store value directly struct { uint8_t paddedSize; uint8_t paddedValue[1]; }; // store value in the heap memory struct { uint32_t memSize; void *memPtr; }; }; static constexpr size_t SmallBufferSize() { return sizeof(KeyValueHolderCrypt) - offsetof(KeyValueHolderCrypt, paddedValue); } static bool isValueStoredAsOffset(size_t valueSize) { return valueSize >= 256; } KeyValueHolderCrypt() = default; KeyValueHolderCrypt(const void *valuePtr, size_t valueLength); explicit KeyValueHolderCrypt(MMBuffer &&data); KeyValueHolderCrypt(uint32_t keyLength, uint32_t valueLength, uint32_t offset); KeyValueHolderCrypt(KeyValueHolderCrypt &&other) noexcept; KeyValueHolderCrypt &operator=(KeyValueHolderCrypt &&other) noexcept; void move(KeyValueHolderCrypt &&other) noexcept; ~KeyValueHolderCrypt(); MMBuffer toMMBuffer(const void *basePtr, const AESCrypt *crypter) const; std::tuple toTuple() { return std::make_tuple(offset, pbKeyValueSize + keySize + valueSize, &cryptStatus); } // those are expensive, just forbid it for possibly misuse explicit KeyValueHolderCrypt(const KeyValueHolderCrypt &other) = delete; KeyValueHolderCrypt &operator=(const KeyValueHolderCrypt &other) = delete; #ifndef NDEBUG static void testAESToMMBuffer(); #endif }; #endif // MMKV_DISABLE_CRYPT #pragma pack(pop) } // namespace mmkv #endif #endif /* KeyValueHolder_hpp */