DCCL v4
binary.h
1 // Copyright 2012-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 // Nathan Knotts <nknotts@gmail.com>
8 //
9 //
10 // This file is part of the Dynamic Compact Control Language Library
11 // ("DCCL").
12 //
13 // DCCL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU Lesser General Public License as published by
15 // the Free Software Foundation, either version 2.1 of the License, or
16 // (at your option) any later version.
17 //
18 // DCCL is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Lesser General Public License for more details.
22 //
23 // You should have received a copy of the GNU Lesser General Public License
24 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
25 #ifndef DCCLBINARY20100713H
26 #define DCCLBINARY20100713H
27 
28 #include <cmath>
29 #include <iomanip>
30 #include <sstream>
31 
32 #include "common.h"
33 #include "dccl/def.h"
34 
35 #if DCCL_HAS_B64
36 #include <cstdio>
37 #define BUFFERSIZE BUFSIZ
38 #include "b64/decode.h"
39 #include "b64/encode.h"
40 #endif
41 
42 namespace dccl
43 {
45 
46 
51 inline void hex_decode(const std::string& in, std::string* out)
52 {
53  static constexpr short char0_9_to_number = 48;
54  static constexpr short charA_F_to_number = 55;
55  static constexpr short chara_f_to_number = 87;
56 
57  int in_size = in.size();
58  int out_size = in_size >> 1;
59  if (in_size & 1)
60  ++out_size;
61 
62  out->assign(out_size, '\0');
63  for (int i = (in_size & 1) ? -1 : 0, n = in_size; i < n; i += 2)
64  {
65  int out_i = (in_size & 1) ? (i + 1) / 2 : i / 2;
66 
67  if (i >= 0)
68  {
69  if (in[i] >= '0' && in[i] <= '9')
70  (*out)[out_i] |= ((in[i] - char0_9_to_number) & 0x0f) << 4;
71  else if (in[i] >= 'A' && in[i] <= 'F')
72  (*out)[out_i] |= ((in[i] - charA_F_to_number) & 0x0f) << 4;
73  else if (in[i] >= 'a' && in[i] <= 'f')
74  (*out)[out_i] |= ((in[i] - chara_f_to_number) & 0x0f) << 4;
75  }
76 
77  if (in[i + 1] >= '0' && in[i + 1] <= '9')
78  (*out)[out_i] |= (in[i + 1] - char0_9_to_number) & 0x0f;
79  else if (in[i + 1] >= 'A' && in[i + 1] <= 'F')
80  (*out)[out_i] |= (in[i + 1] - charA_F_to_number) & 0x0f;
81  else if (in[i + 1] >= 'a' && in[i + 1] <= 'f')
82  (*out)[out_i] |= (in[i + 1] - chara_f_to_number) & 0x0f;
83  }
84 }
85 
86 inline std::string hex_decode(const std::string& in)
87 {
88  std::string out;
89  hex_decode(in, &out);
90  return out;
91 }
92 
99 template <typename CharIterator>
100 inline void hex_encode(CharIterator begin, CharIterator end, std::string* out,
101  bool upper_case = false)
102 {
103  static constexpr short char0_9_to_number = 48;
104  static constexpr short charA_F_to_number = 55;
105  static constexpr short chara_f_to_number = 87;
106 
107  size_t in_size = std::distance(begin, end);
108  size_t out_size = in_size << 1;
109 
110  out->clear();
111  out->resize(out_size);
112 
113  size_t i = 0;
114  for (CharIterator it = begin; it != end; ++it)
115  {
116  short msn = (*it >> 4) & 0x0f;
117  short lsn = *it & 0x0f;
118 
119  if (msn >= 0 && msn <= 9)
120  (*out)[2 * i] = msn + char0_9_to_number;
121  else if (msn >= 10 && msn <= 15)
122  (*out)[2 * i] = msn + (upper_case ? charA_F_to_number : chara_f_to_number);
123 
124  if (lsn >= 0 && lsn <= 9)
125  (*out)[2 * i + 1] = lsn + char0_9_to_number;
126  else if (lsn >= 10 && lsn <= 15)
127  (*out)[2 * i + 1] = lsn + (upper_case ? charA_F_to_number : chara_f_to_number);
128 
129  i++;
130  }
131 }
132 
133 template <typename CharIterator> inline std::string hex_encode(CharIterator begin, CharIterator end)
134 {
135  std::string out;
136  hex_encode(begin, end, &out);
137  return out;
138 }
139 
145 inline void hex_encode(const std::string& in, std::string* out, bool upper_case = false)
146 {
147  hex_encode(in.begin(), in.end(), out, upper_case);
148 }
149 
150 inline std::string hex_encode(const std::string& in)
151 {
152  std::string out;
153  hex_encode(in, &out);
154  return out;
155 }
156 
157 #if DCCL_HAS_B64
158 inline std::string b64_encode(const std::string& in)
159 {
160  std::stringstream instream(in);
161  std::stringstream outstream;
162  base64::encoder D;
163  D.encode(instream, outstream);
164  return outstream.str();
165 }
166 
167 inline std::string b64_decode(const std::string& in)
168 {
169  std::stringstream instream(in);
170  std::stringstream outstream;
171  base64::decoder D;
172  D.decode(instream, outstream);
173  return outstream.str();
174 }
175 #endif
176 
178 inline unsigned ceil_log2(dccl::uint64 v)
179 {
180  // r will be one greater (ceil) if v is not a power of 2
181  unsigned r = ((v & (v - 1)) == 0) ? 0 : 1;
182  while (v >>= 1) r++;
183  return r;
184 }
185 
186 inline unsigned long ceil_log2(double d)
187 {
188  return ceil_log2(static_cast<dccl::uint64>(std::ceil(d)));
189 }
190 
191 inline unsigned long ceil_log2(int i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
192 
193 inline unsigned long ceil_log2(long i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
194 
195 inline unsigned long ceil_log2(unsigned i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
196 
197 inline double log2(double d) { return std::log2(d); }
198 
200 } // namespace dccl
201 
202 #endif
dccl::uint64
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition: common.h:60
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:46
dccl::ceil_log2
unsigned ceil_log2(dccl::uint64 v)
Definition: binary.h:178
dccl::hex_encode
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
Definition: binary.h:100
dccl::hex_decode
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition: binary.h:51