aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/storages/portable_storage_base.h
blob: ae0be6a34e7131b4820da983fb46c9d9ad481cc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 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 <boost/variant.hpp>
#include <string>
#include <vector>
#include <deque>
#include <map>

#define PORTABLE_STORAGE_SIGNATUREA 0x01011101
#define PORTABLE_STORAGE_SIGNATUREB 0x01020101 // bender's nightmare 
#define PORTABLE_STORAGE_FORMAT_VER 1

#define PORTABLE_RAW_SIZE_MARK_MASK   0x03 
#define PORTABLE_RAW_SIZE_MARK_BYTE   0
#define PORTABLE_RAW_SIZE_MARK_WORD   1
#define PORTABLE_RAW_SIZE_MARK_DWORD  2
#define PORTABLE_RAW_SIZE_MARK_INT64  3

#ifndef MAX_STRING_LEN_POSSIBLE       
#define MAX_STRING_LEN_POSSIBLE       2000000000 //do not let string be so big
#endif

//data types 
#define SERIALIZE_TYPE_INT64                1
#define SERIALIZE_TYPE_INT32                2
#define SERIALIZE_TYPE_INT16                3
#define SERIALIZE_TYPE_INT8                 4
#define SERIALIZE_TYPE_UINT64               5
#define SERIALIZE_TYPE_UINT32               6
#define SERIALIZE_TYPE_UINT16               7
#define SERIALIZE_TYPE_UINT8                8
#define SERIALIZE_TYPE_DUOBLE               9
#define SERIALIZE_TYPE_STRING               10
#define SERIALIZE_TYPE_BOOL                 11
#define SERIALIZE_TYPE_OBJECT               12
#define SERIALIZE_TYPE_ARRAY                13

#define SERIALIZE_FLAG_ARRAY              0x80


namespace epee
{
  namespace serialization
  {
    struct section;

    template<typename T> struct entry_container { typedef std::vector<T> type; static void reserve(type &t, size_t n) { t.reserve(n); } };
    template<> struct entry_container<bool> { typedef std::deque<bool> type; static void reserve(type &t, size_t n) {} };

    /************************************************************************/
    /*                                                                      */
    /************************************************************************/
    template<class t_entry_type>
    struct array_entry_t
    {
      array_entry_t():m_it(m_array.end()){}        
      array_entry_t(const array_entry_t& other):m_array(other.m_array), m_it(m_array.end()){}

      array_entry_t& operator=(const array_entry_t& other)
      {
        m_array = other.m_array;
        m_it = m_array.end();
        return *this;
      }

      const t_entry_type* get_first_val() const 
      {
        m_it = m_array.begin();
        return get_next_val();
      }

      t_entry_type* get_first_val() 
      {
        m_it = m_array.begin();
        return get_next_val();
      }


      const t_entry_type* get_next_val() const 
      {
        if(m_it == m_array.end())
          return nullptr;
        return &(*(m_it++));
      }

      t_entry_type* get_next_val() 
      {
        if(m_it == m_array.end())
          return nullptr;
        return (t_entry_type*)&(*(m_it++));//fuckoff
      }

      t_entry_type& insert_first_val(t_entry_type&& v)
      {
        m_array.clear();
        m_it = m_array.end();
        return insert_next_value(std::move(v));
      }

      t_entry_type& insert_next_value(t_entry_type&& v)
      {
        m_array.push_back(std::move(v));
        return m_array.back();
      }

      void reserve(size_t n)
      {
        entry_container<t_entry_type>::reserve(m_array, n);
      }

      typename entry_container<t_entry_type>::type m_array;
      mutable typename entry_container<t_entry_type>::type::const_iterator m_it;
    };


    typedef  boost::make_recursive_variant<
      array_entry_t<section>, 
      array_entry_t<uint64_t>, 
      array_entry_t<uint32_t>, 
      array_entry_t<uint16_t>, 
      array_entry_t<uint8_t>, 
      array_entry_t<int64_t>, 
      array_entry_t<int32_t>, 
      array_entry_t<int16_t>, 
      array_entry_t<int8_t>, 
      array_entry_t<double>, 
      array_entry_t<bool>, 
      array_entry_t<std::string>,
      array_entry_t<section>, 
      array_entry_t<boost::recursive_variant_> 
    >::type array_entry;

    typedef boost::variant<uint64_t, uint32_t, uint16_t, uint8_t, int64_t, int32_t, int16_t, int8_t, double, bool, std::string, section, array_entry> storage_entry;

    typedef std::string binarybuffer;//it's ok      

    /************************************************************************/
    /*                                                                      */
    /************************************************************************/
    struct section
    {
      std::map<std::string, storage_entry> m_entries;
    };

    //handle-like aliases
    typedef section*      hsection;  
    typedef array_entry*  harray;
  }
}