Electroneum
portable_storage_val_converters.h
Go to the documentation of this file.
1 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the Andrey N. Sabelnikov nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 
28 
29 #pragma once
30 
31 #include <time.h>
32 #include <boost/regex.hpp>
33 
34 #include "misc_language.h"
35 #include "portable_storage_base.h"
36 #include "warnings.h"
37 
38 namespace epee
39 {
40  namespace serialization
41  {
42 #define ASSERT_AND_THROW_WRONG_CONVERSION() ASSERT_MES_AND_THROW("WRONG DATA CONVERSION: from type=" << typeid(from).name() << " to type " << typeid(to).name())
43 
44  template<typename from_type, typename to_type>
45  void convert_int_to_uint(const from_type& from, to_type& to)
46  {
49  CHECK_AND_ASSERT_THROW_MES(from >=0, "unexpected int value with signed storage value less than 0, and unsigned receiver value");
51  CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
52  to = static_cast<to_type>(from);
54  }
55  template<typename from_type, typename to_type>
56  void convert_int_to_int(const from_type& from, to_type& to)
57  {
58  CHECK_AND_ASSERT_THROW_MES(from >= boost::numeric::bounds<to_type>::lowest(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with lowest possible value = " << boost::numeric::bounds<to_type>::lowest());
60 DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
61  CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
63  to = static_cast<to_type>(from);
64  }
65  template<typename from_type, typename to_type>
66  void convert_uint_to_any_int(const from_type& from, to_type& to)
67  {
70 DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
71  CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "uint value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
72  to = static_cast<to_type>(from);
74  }
75 
76  template<typename from_type, typename to_type, bool, bool> //is from signed, is from to signed
78 
79  template<typename from_type, typename to_type>
80  struct convert_to_signed_unsigned<from_type, to_type, true, true>
81  {
82  static void convert(const from_type& from, to_type& to)
83  {//from signed to signed
84  convert_int_to_int(from, to);
85  }
86  };
87 
88  template<typename from_type, typename to_type>
89  struct convert_to_signed_unsigned<from_type, to_type, true, false>
90  {
91  static void convert(const from_type& from, to_type& to)
92  {//from signed to unsigned
93  convert_int_to_uint(from, to);
94  }
95  };
96 
97  template<typename from_type, typename to_type>
98  struct convert_to_signed_unsigned<from_type, to_type, false, true>
99  {
100  static void convert(const from_type& from, to_type& to)
101  {//from unsigned to signed
102  convert_uint_to_any_int(from, to);
103  }
104  };
105 
106  template<typename from_type, typename to_type>
107  struct convert_to_signed_unsigned<from_type, to_type, false, false>
108  {
109  static void convert(const from_type& from, to_type& to)
110  {
111  //from unsigned to unsigned
112  convert_uint_to_any_int(from, to);
113  }
114  };
115 
116  template<typename from_type, typename to_type, bool>
118 
119  template<typename from_type, typename to_type>
120  struct convert_to_integral<from_type, to_type, true>
121  {
122  static void convert(const from_type& from, to_type& to)
123  {
125  }
126  };
127 
128  template<typename from_type, typename to_type>
129  struct convert_to_integral<from_type, to_type, false>
130  {
131  static void convert(const from_type& from, to_type& to)
132  {
134  }
135  };
136 
137  // For MyMonero/OpenMonero backend compatibility
138  // MyMonero backend sends amount, fees and timestamp values as strings.
139  // Until MM backend is updated, this is needed for compatibility between OpenMonero and MyMonero.
140  template<>
142  {
143  static void convert(const std::string& from, uint64_t& to)
144  {
145  MTRACE("Converting std::string to uint64_t. Source: " << from);
146  // String only contains digits
147  if(std::all_of(from.begin(), from.end(), epee::misc_utils::parse::isdigit))
148  to = boost::lexical_cast<uint64_t>(from);
149  // MyMonero ISO 8061 timestamp (2017-05-06T16:27:06Z)
150  else if (boost::regex_match (from, boost::regex("\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\dZ")))
151  {
152  // Convert to unix timestamp
153 #ifdef HAVE_STRPTIME
154  struct tm tm;
155  if (strptime(from.c_str(), "%Y-%m-%dT%H:%M:%S", &tm))
156 #else
157  std::tm tm = {};
158  std::istringstream ss(from);
159  if (ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"))
160 #endif
161  to = std::mktime(&tm);
162  } else
164  }
165  };
166 
167  template<class from_type, class to_type>
168  struct is_convertable: std::integral_constant<bool,
169  std::is_integral<to_type>::value &&
170  std::is_integral<from_type>::value &&
171  !std::is_same<from_type, bool>::value &&
172  !std::is_same<to_type, bool>::value > {};
173 
174  template<typename from_type, typename to_type, bool>
176 
177  template<typename from_type, typename to_type>
178  struct convert_to_same<from_type, to_type, true>
179  {
180  static void convert(const from_type& from, to_type& to)
181  {
182  to = from;
183  }
184  };
185 
186  template<typename from_type, typename to_type>
187  struct convert_to_same<from_type, to_type, false>
188  {
189  static void convert(const from_type& from, to_type& to)
190  {
191  convert_to_integral<from_type, to_type, is_convertable<from_type, to_type>::value>::convert(from, to);// ASSERT_AND_THROW_WRONG_CONVERSION();
192  }
193  };
194 
195 
196  template<class from_type, class to_type>
197  void convert_t(const from_type& from, to_type& to)
198  {
200  }
201  }
202 }
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
#define ASSERT_AND_THROW_WRONG_CONVERSION()
#define DISABLE_GCC_AND_CLANG_WARNING(w)
Definition: warnings.h:28
PUSH_WARNINGS
Definition: hash-ops.h:54
#define MTRACE(x)
Definition: misc_log_ex.h:77
::std::string string
Definition: gtest-port.h:1097
#define DISABLE_CLANG_WARNING(w)
Definition: warnings.h:25
STL namespace.
void convert_t(const from_type &from, to_type &to)
int compare(MDB_val const *left, MDB_val const *right) noexcept
Definition: util.h:135
const char * name
void convert_int_to_int(const from_type &from, to_type &to)
return true
#define POP_WARNINGS
Definition: warnings.h:17
void convert_uint_to_any_int(const from_type &from, to_type &to)
unsigned __int64 uint64_t
Definition: stdint.h:136
#define false
Definition: stdbool.h:38
void convert_int_to_uint(const from_type &from, to_type &to)
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
DISABLE_VS_WARNINGS(4244 4345 4503) using namespace crypto