Goby v2
binary.h
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Goby Underwater Autonomy Project Libraries
8 // ("The Goby Libraries").
9 //
10 // The Goby Libraries are free software: you can redistribute them and/or modify
11 // them 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 // The Goby Libraries are distributed in the hope that they 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 Goby. If not, see <http://www.gnu.org/licenses/>.
22 
23 #ifndef BINARY20100713H
24 #define BINARY20100713H
25 
26 #include <cmath>
27 #include <iomanip>
28 #include <iostream>
29 #include <sstream>
30 
31 #include <bitset>
32 #include <boost/dynamic_bitset.hpp>
33 
34 namespace goby
35 {
36 namespace util
37 {
39 
40 
45 inline void hex_decode(const std::string& in, std::string* out)
46 {
47  static const short char0_9_to_number = 48;
48  static const short charA_F_to_number = 55;
49  static const short chara_f_to_number = 87;
50 
51  int in_size = in.size();
52  int out_size = in_size >> 1;
53  if (in_size & 1)
54  ++out_size;
55 
56  out->assign(out_size, '\0');
57  for (int i = (in_size & 1) ? -1 : 0, n = in_size; i < n; i += 2)
58  {
59  int out_i = (in_size & 1) ? (i + 1) / 2 : i / 2;
60 
61  if (i >= 0)
62  {
63  if (in[i] >= '0' && in[i] <= '9')
64  (*out)[out_i] |= ((in[i] - char0_9_to_number) & 0x0f) << 4;
65  else if (in[i] >= 'A' && in[i] <= 'F')
66  (*out)[out_i] |= ((in[i] - charA_F_to_number) & 0x0f) << 4;
67  else if (in[i] >= 'a' && in[i] <= 'f')
68  (*out)[out_i] |= ((in[i] - chara_f_to_number) & 0x0f) << 4;
69  }
70 
71  if (in[i + 1] >= '0' && in[i + 1] <= '9')
72  (*out)[out_i] |= (in[i + 1] - char0_9_to_number) & 0x0f;
73  else if (in[i + 1] >= 'A' && in[i + 1] <= 'F')
74  (*out)[out_i] |= (in[i + 1] - charA_F_to_number) & 0x0f;
75  else if (in[i + 1] >= 'a' && in[i + 1] <= 'f')
76  (*out)[out_i] |= (in[i + 1] - chara_f_to_number) & 0x0f;
77  }
78 }
79 
80 inline std::string hex_decode(const std::string& in)
81 {
82  std::string out;
83  hex_decode(in, &out);
84  return out;
85 }
86 
92 inline void hex_encode(const std::string& in, std::string* out, bool upper_case = false)
93 {
94  static const short char0_9_to_number = 48;
95  static const short charA_F_to_number = 55;
96  static const short chara_f_to_number = 87;
97 
98  int in_size = in.size();
99  int out_size = in_size << 1;
100 
101  out->resize(out_size);
102  for (int i = 0, n = in_size; i < n; ++i)
103  {
104  short msn = (in[i] >> 4) & 0x0f;
105  short lsn = in[i] & 0x0f;
106 
107  if (msn >= 0 && msn <= 9)
108  (*out)[2 * i] = msn + char0_9_to_number;
109  else if (msn >= 10 && msn <= 15)
110  (*out)[2 * i] = msn + (upper_case ? charA_F_to_number : chara_f_to_number);
111 
112  if (lsn >= 0 && lsn <= 9)
113  (*out)[2 * i + 1] = lsn + char0_9_to_number;
114  else if (lsn >= 10 && lsn <= 15)
115  (*out)[2 * i + 1] = lsn + (upper_case ? charA_F_to_number : chara_f_to_number);
116  }
117 }
118 
119 inline std::string hex_encode(const std::string& in)
120 {
121  std::string out;
122  hex_encode(in, &out);
123  return out;
124 }
125 
129 template <typename T> bool hex_string2number(const std::string& s, T& t)
130 {
131  std::stringstream ss;
132  ss << s;
133  ss >> std::hex >> t;
134  return !ss.fail();
135 }
136 
143 template <typename T> bool number2hex_string(std::string& s, const T& t, unsigned int width = 2)
144 {
145  std::stringstream ss;
146  ss << std::hex << std::setw(width) << std::setfill('0') << static_cast<unsigned int>(t);
147  s = ss.str();
148  return !ss.fail();
149 }
150 
156 template <typename T> std::string number2hex_string(const T& t, unsigned int width = 2)
157 {
158  std::string s;
159  number2hex_string(s, t, width);
160  return s;
161 }
162 
164 } // namespace util
165 } // namespace goby
166 
167 #endif
bool number2hex_string(std::string &s, const T &t, unsigned int width=2)
converts a decimal number of type T into a hex string
bool hex_string2number(const std::string &s, T &t)
converts a hex string ("8AAA") into a dynamic_bitset
The global namespace for the Goby project.