oxen-core/contrib/epee/include/epee/storages/portable_storage_base.h

137 lines
5.2 KiB
C++

// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <variant>
#include <string>
#include <vector>
#include <deque>
#include <cstdint>
#include <map>
#include "../misc_log_ex.h"
#include "../int-util.h"
namespace epee
{
namespace serialization
{
constexpr uint32_t PORTABLE_STORAGE_SIGNATUREA = SWAP32LE(0x01011101);
constexpr uint32_t PORTABLE_STORAGE_SIGNATUREB = SWAP32LE(0x01020101); // bender's nightmare
constexpr uint8_t PORTABLE_STORAGE_FORMAT_VER = 1;
// When sending a "varint" the binary serialization uses the bottom 2 bits to store the size,
// either 1, 2, 4, or 8 bytes for 6/14/30/62 bits of storage. God help you if you want to store
// something >= 2^62 (but don't worry, it throws an exception if you try).
constexpr uint8_t
PORTABLE_RAW_SIZE_MARK_MASK = 0b11,
PORTABLE_RAW_SIZE_MARK_6BIT = 0,
PORTABLE_RAW_SIZE_MARK_14BIT = 1,
PORTABLE_RAW_SIZE_MARK_30BIT = 2,
PORTABLE_RAW_SIZE_MARK_62BIT = 3;
constexpr size_t MAX_STRING_LEN_POSSIBLE = 2000000000; //do not let string be so big
struct section;
template <typename T>
using array_t = std::conditional_t<std::is_same_v<T, bool>, std::deque<bool>, std::vector<T>>;
using array_entry = std::variant<
array_t<uint64_t>,
array_t<uint32_t>,
array_t<uint16_t>,
array_t<uint8_t>,
array_t<int64_t>,
array_t<int32_t>,
array_t<int16_t>,
array_t<int8_t>,
array_t<double>,
array_t<bool>,
array_t<std::string>,
array_t<section>
>;
// FIXME: dropped recursive arrays -- is this okay?
using storage_entry = std::variant<
uint64_t,
uint32_t,
uint16_t,
uint8_t,
int64_t,
int32_t,
int16_t,
int8_t,
double,
bool,
std::string,
section,
array_entry
>;
template <typename T, typename = void>
constexpr bool variant_contains = false;
template <typename T, typename... Us>
constexpr bool variant_contains<T, std::variant<Us...>> = (... || std::is_same_v<T, Us>);
/************************************************************************/
/* */
/************************************************************************/
struct section
{
std::map<std::string, storage_entry> m_entries;
};
template <typename T> constexpr bool TYPE_IS_NOT_SERIALIZABLE = false;
template <typename T>
constexpr uint8_t no_such_type() { static_assert(TYPE_IS_NOT_SERIALIZABLE<T>); return 0; }
//data types
template <typename T> constexpr uint8_t SERIALIZE_TYPE_TAG = no_such_type<T>();
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<int64_t> = 1;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<int32_t> = 2;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<int16_t> = 3;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<int8_t> = 4;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<uint64_t> = 5;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<uint32_t> = 6;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<uint16_t> = 7;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<uint8_t> = 8;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<double> = 9;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<std::string> = 10;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<bool> = 11;
template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<section> = 12;
//template <> inline constexpr uint8_t SERIALIZE_TYPE_TAG<array> = 13; // nested array
constexpr uint8_t SERIALIZE_FLAG_ARRAY = 0x80;
}
}