DCCL v3
binary.h
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef DCCLBINARY20100713H
23 #define DCCLBINARY20100713H
24 
25 #include <iomanip>
26 #include <cmath>
27 #include <sstream>
28 
29 #include "dccl/common.h"
30 
31 #define DCCL_HAS_B64 1
32 
33 #if DCCL_HAS_B64
34 #include <cstdio>
35 #define BUFFERSIZE BUFSIZ
36 #include "b64/encode.h"
37 #include "b64/decode.h"
38 #endif
39 
40 namespace dccl
41 {
43 
44 
49  inline void hex_decode(const std::string& in, std::string* out)
50  {
51  static const short char0_9_to_number = 48;
52  static const short charA_F_to_number = 55;
53  static const short chara_f_to_number = 87;
54 
55  int in_size = in.size();
56  int out_size = in_size >> 1;
57  if(in_size & 1)
58  ++out_size;
59 
60  out->assign(out_size, '\0');
61  for(int i = (in_size & 1) ? -1 : 0, n = in_size;
62  i < n;
63  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, bool upper_case = false)
101  {
102  static const short char0_9_to_number = 48;
103  static const short charA_F_to_number = 55;
104  static const short chara_f_to_number = 87;
105 
106  size_t in_size = std::distance(begin, end);
107  size_t out_size = in_size << 1;
108 
109  out->clear();
110  out->resize(out_size);
111 
112  size_t i = 0;
113  for(CharIterator it = begin; it != end; ++it)
114  {
115  short msn = (*it >> 4) & 0x0f;
116  short lsn = *it & 0x0f;
117 
118  if(msn >= 0 && msn <= 9)
119  (*out)[2*i] = msn + char0_9_to_number;
120  else if(msn >= 10 && msn <= 15)
121  (*out)[2*i] = msn + (upper_case ? charA_F_to_number : chara_f_to_number);
122 
123  if(lsn >= 0 && lsn <= 9)
124  (*out)[2*i+1] = lsn + char0_9_to_number;
125  else if(lsn >= 10 && lsn <= 15)
126  (*out)[2*i+1] = lsn + (upper_case ? charA_F_to_number : chara_f_to_number);
127 
128  i++;
129  }
130  }
131 
132  template <typename CharIterator>
133  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  }
140 
146  inline void hex_encode(const std::string& in, std::string* out, bool upper_case = false)
147  {
148  hex_encode(in.begin(), in.end(), out, upper_case);
149  }
150 
151  inline std::string hex_encode(const std::string& in)
152  {
153  std::string out;
154  hex_encode(in, &out);
155  return out;
156  }
157 
158 
159 #if DCCL_HAS_B64
160  inline std::string b64_encode(const std::string& in)
161  {
162  std::stringstream instream(in);
163  std::stringstream outstream;
164  base64::encoder D;
165  D.encode(instream, outstream);
166  return outstream.str();
167  }
168 
169  inline std::string b64_decode(const std::string& in)
170  {
171  std::stringstream instream(in);
172  std::stringstream outstream;
173  base64::decoder D;
174  D.decode(instream, outstream);
175  return outstream.str();
176  }
177 #endif
178 
180  inline unsigned ceil_log2(dccl::uint64 v)
181  {
182  // r will be one greater (ceil) if v is not a power of 2
183  unsigned r = ((v & (v - 1)) == 0) ? 0 : 1;
184  while (v >>= 1)
185  r++;
186  return r;
187  }
188 
189  inline unsigned long ceil_log2(double d)
190  { return ceil_log2(static_cast<dccl::uint64>(std::ceil(d))); }
191 
192  inline unsigned long ceil_log2(int i)
193  { return ceil_log2(static_cast<dccl::uint64>(i)); }
194 
195  inline unsigned long ceil_log2(long i)
196  { return ceil_log2(static_cast<dccl::uint64>(i)); }
197 
198  inline unsigned long ceil_log2(unsigned i)
199  { return ceil_log2(static_cast<dccl::uint64>(i)); }
200 
201  inline double log2(double d)
202  {
203  static double log_2 = log(2);
204  return log(d)/log_2;
205  }
206 
207 
208 
210 }
211 
212 #endif
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:49
unsigned ceil_log2(dccl::uint64 v)
Definition: binary.h:180
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition: common.h:59
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
Dynamic Compact Control Language namespace.