YPC  0.2.0
byte.h
Go to the documentation of this file.
1 
9 #pragma once
10 #include "ypc/common/byte.h"
11 #include <boost/endian/conversion.hpp>
12 #include <boost/property_tree/ptree.hpp>
13 #include <ff/network.h>
14 #include <glog/logging.h>
15 #include <iostream>
16 #include <utility>
17 
18 namespace ypc {
19 
20 using byte_t = uint8_t;
22 using hex_bytes = bytes::hex_bytes_t;
23 using base58_bytes = bytes::base58_bytes_t;
24 using base64_bytes = bytes::base64_bytes_t;
25 
26 template <typename T>
27 auto byte_to_number(byte_t *bytes, size_t len) ->
28  typename std::enable_if<std::is_arithmetic<T>::value, T>::type {
29  if (len < sizeof(T)) {
30  return T();
31  }
32 
33  T *val = (T *)bytes;
34  T ret = boost::endian::big_to_native(*val);
35  return ret;
36 }
37 
38 template <typename T>
39 auto number_to_byte(T val, byte_t *bytes, size_t len) ->
40  typename std::enable_if<std::is_arithmetic<T>::value, void>::type {
41  if (len < sizeof(T)) {
42  return;
43  }
44 
45  T v = boost::endian::native_to_big(val);
46  T *p = (T *)bytes;
47  *p = v;
48  return;
49 }
50 
51 template <typename T, typename BytesType>
52 auto byte_to_number(const BytesType &v) ->
53  typename std::enable_if<std::is_arithmetic<T>::value, T>::type {
54  if (v.size() < sizeof(T)) {
55  return T();
56  }
57 
58  T *val = (T *)v.data();
59  T ret = boost::endian::big_to_native(*val);
60  return ret;
61 }
62 
63 template <typename BytesType, typename T>
64 auto number_to_byte(T val) ->
65  typename std::enable_if<std::is_arithmetic<T>::value &&
66  utc::is_bytes<BytesType>::value,
67  BytesType>::type {
68  T v = boost::endian::native_to_big(val);
69  BytesType b((byte_t *)&v, sizeof(v));
70  return b;
71 }
72 
73 template <typename BytesType, typename T>
74 auto number_to_byte(T val) ->
75  typename std::enable_if<std::is_arithmetic<T>::value &&
76  utc::is_fix_bytes<BytesType>::value,
77  BytesType>::type {
78  T v = boost::endian::native_to_big(val);
79  BytesType b;
80  T *rval = (T *)b.data();
81  *rval = v;
82  return b;
83 }
84 } // namespace ypc
85 
86 template <typename ByteType, ::ypc::utc::byte_encode Format>
87 auto operator<<(std::ostream &out,
88  const ::ypc::utc::bytes<ByteType, Format> &data) ->
89  typename std::enable_if<Format == ::ypc::utc::byte_encode::raw_bytes,
90  std::ostream &>::type {
91 
92  using hex_bytes_t = typename ::ypc::utc::bytes<ByteType, Format>::hex_bytes_t;
93  hex_bytes_t hex = data.template as<hex_bytes_t>();
94  std::string s((const char *)hex.data(), hex.size());
95  out << s;
96  return out;
97 }
98 
99 template <typename ByteType, ::ypc::utc::byte_encode Format>
100 auto operator<<(std::ostream &out,
101  const ::ypc::utc::bytes<ByteType, Format> &data) ->
102  typename std::enable_if<Format != ::ypc::utc::byte_encode::raw_bytes,
103  std::ostream &>::type {
104 
105  std::string s((const char *)data.data(), data.size());
106  out << s;
107  return out;
108 }
109 
110 template <typename ByteType, ::ypc::utc::byte_encode Format>
111 auto operator>>(std::istream &is, ::ypc::utc::bytes<ByteType, Format> &obj) ->
112  typename std::enable_if<Format == ::ypc::utc::byte_encode::raw_bytes,
113  std::istream &>::type {
114  using hex_bytes_t = typename ::ypc::utc::bytes<ByteType, Format>::hex_bytes_t;
115  std::string s;
116  is >> s;
117  hex_bytes_t hex(s.c_str(), s.size());
118  obj = hex.template as<::ypc::utc::bytes<ByteType, Format>>();
119  return is;
120 }
121 
122 template <typename ByteType, ::ypc::utc::byte_encode Format>
123 auto operator>>(std::istream &is, ::ypc::utc::bytes<ByteType, Format> &obj) ->
124  typename std::enable_if<Format != ::ypc::utc::byte_encode::raw_bytes,
125  std::istream &>::type {
126  std::string s;
127  is >> s;
128  obj = ::ypc::utc::bytes<ByteType, Format>(s.c_str(), s.size());
129  return is;
130 }
131 
132 
133 namespace boost {
134 namespace property_tree {
135 template <typename String, typename T> struct serialization_translator {};
136 
137 template <typename String, typename ByteType, ::ypc::utc::byte_encode Format>
138 struct serialization_translator<String, ::ypc::utc::bytes<ByteType, Format>> {
139  using internal_type = String;
141 
142  boost::optional<external_type> get_value(const internal_type &str) {
143  std::istringstream stream(str);
144  external_type result;
145  istream(stream, result);
146  if (stream.rdstate() == std::ios::failbit) {
147  return boost::none;
148  }
149  return result;
150  }
151 
152  boost::optional<internal_type> put_value(const external_type &obj) {
153  std::ostringstream result;
154  ostream(result, obj);
155  return result.str();
156  }
157 
158 protected:
159  template <typename BT, ::ypc::utc::byte_encode F>
160  static auto ostream(std::ostream &out, const ::ypc::utc::bytes<BT, F> &data)
161  -> typename std::enable_if<F == ::ypc::utc::byte_encode::raw_bytes,
162  std::ostream &>::type {
163 
164  using hex_bytes_t = typename ::ypc::utc::bytes<BT, F>::hex_bytes_t;
165  hex_bytes_t hex = data.template as<hex_bytes_t>();
166  std::string s((const char *)hex.data(), hex.size());
167  out << s;
168  return out;
169  }
170 
171  template <typename BT, ::ypc::utc::byte_encode F>
172  static auto ostream(std::ostream &out, const ::ypc::utc::bytes<BT, F> &data)
173  -> typename std::enable_if<F != ::ypc::utc::byte_encode::raw_bytes,
174  std::ostream &>::type {
175 
176  std::string s((const char *)data.data(), data.size());
177  out << s;
178  return out;
179  }
180 
181  template <typename BT, ::ypc::utc::byte_encode F>
182  static auto istream(std::istream &is, ::ypc::utc::bytes<BT, F> &obj) ->
183  typename std::enable_if<F == ::ypc::utc::byte_encode::raw_bytes,
184  std::istream &>::type {
185  using hex_bytes_t = typename ::ypc::utc::bytes<BT, F>::hex_bytes_t;
186  std::string s;
187  is >> s;
188  hex_bytes_t hex(s.c_str(), s.size());
189  obj = hex.template as<::ypc::utc::bytes<BT, F>>();
190  return is;
191  }
192 
193  template <typename BT, ::ypc::utc::byte_encode F>
194  static auto istream(std::istream &is, ::ypc::utc::bytes<BT, F> &obj) ->
195  typename std::enable_if<F != ::ypc::utc::byte_encode::raw_bytes,
196  std::istream &>::type {
197  std::string s;
198  is >> s;
199  obj = ::ypc::utc::bytes<BT, F>(s.c_str(), s.size());
200  return is;
201  }
202 };
203 
204 using string_type = std::string;
205 
206 template <typename ByteType, ::ypc::utc::byte_encode Format>
207 struct translator_between<string_type, ::ypc::utc::bytes<ByteType, Format>> {
208  using type = serialization_translator<string_type,
210 };
211 
212 template <> struct translator_between<string_type, string_type> {
213  using type = id_translator<string_type>;
214 };
215 
216 } // namespace property_tree
217 } // namespace boost
boost::property_tree::serialization_translator
Definition: byte.h:135
ypc::utc::bytes< byte_t, ::ypc::utc::byte_encode::raw_bytes >