Goby3  3.1.5a
2024.05.23
binary.h
Go to the documentation of this file.
1 // Copyright 2010-2021:
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 //
8 //
9 // This file is part of the Goby Underwater Autonomy Project Libraries
10 // ("The Goby Libraries").
11 //
12 // The Goby Libraries are free software: you can redistribute them and/or modify
13 // them under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation, either version 2.1 of the License, or
15 // (at your option) any later version.
16 //
17 // The Goby Libraries are distributed in the hope that they will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef GOBY_UTIL_BINARY_H
26 #define GOBY_UTIL_BINARY_H
27 
28 #include <cmath>
29 #include <iomanip>
30 #include <iostream>
31 #include <sstream>
32 
33 #include <bitset>
34 #include <boost/dynamic_bitset.hpp>
35 
36 namespace goby
37 {
38 namespace util
39 {
41 
42 
47 inline void hex_decode(const std::string& in, std::string* out)
48 {
49  static const short char0_9_to_number = 48;
50  static const short charA_F_to_number = 55;
51  static const short chara_f_to_number = 87;
52 
53  int in_size = in.size();
54  int out_size = in_size >> 1;
55  if (in_size & 1)
56  ++out_size;
57 
58  out->assign(out_size, '\0');
59  for (int i = (in_size & 1) ? -1 : 0, n = in_size; i < n; i += 2)
60  {
61  int out_i = (in_size & 1) ? (i + 1) / 2 : i / 2;
62 
63  if (i >= 0)
64  {
65  if (in[i] >= '0' && in[i] <= '9')
66  (*out)[out_i] |= ((in[i] - char0_9_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  else if (in[i] >= 'a' && in[i] <= 'f')
70  (*out)[out_i] |= ((in[i] - chara_f_to_number) & 0x0f) << 4;
71  }
72 
73  if (in[i + 1] >= '0' && in[i + 1] <= '9')
74  (*out)[out_i] |= (in[i + 1] - char0_9_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  else if (in[i + 1] >= 'a' && in[i + 1] <= 'f')
78  (*out)[out_i] |= (in[i + 1] - chara_f_to_number) & 0x0f;
79  }
80 }
81 
82 inline std::string hex_decode(const std::string& in)
83 {
84  std::string out;
85  hex_decode(in, &out);
86  return out;
87 }
88 
94 inline void hex_encode(const std::string& in, std::string* out, bool upper_case = false)
95 {
96  static const short char0_9_to_number = 48;
97  static const short charA_F_to_number = 55;
98  static const short chara_f_to_number = 87;
99 
100  int in_size = in.size();
101  int out_size = in_size << 1;
102 
103  out->resize(out_size);
104  for (int i = 0, n = in_size; i < n; ++i)
105  {
106  short msn = (in[i] >> 4) & 0x0f;
107  short lsn = in[i] & 0x0f;
108 
109  if (msn >= 0 && msn <= 9)
110  (*out)[2 * i] = msn + char0_9_to_number;
111  else if (msn >= 10 && msn <= 15)
112  (*out)[2 * i] = msn + (upper_case ? charA_F_to_number : chara_f_to_number);
113 
114  if (lsn >= 0 && lsn <= 9)
115  (*out)[2 * i + 1] = lsn + char0_9_to_number;
116  else if (lsn >= 10 && lsn <= 15)
117  (*out)[2 * i + 1] = lsn + (upper_case ? charA_F_to_number : chara_f_to_number);
118  }
119 }
120 
121 inline std::string hex_encode(const std::string& in)
122 {
123  std::string out;
124  hex_encode(in, &out);
125  return out;
126 }
127 
131 template <typename T> bool hex_string2number(const std::string& s, T& t)
132 {
133  std::stringstream ss;
134  ss << s;
135  ss >> std::hex >> t;
136  return !ss.fail();
137 }
138 
145 template <typename T> bool number2hex_string(std::string& s, const T& t, unsigned int width = 2)
146 {
147  std::stringstream ss;
148  ss << std::hex << std::setw(width) << std::setfill('0') << static_cast<unsigned int>(t);
149  s = ss.str();
150  return !ss.fail();
151 }
152 
158 template <typename T> std::string number2hex_string(const T& t, unsigned int width = 2)
159 {
160  std::string s;
161  number2hex_string(s, t, width);
162  return s;
163 }
164 
166 } // namespace util
167 } // namespace goby
168 
169 #endif
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::util::hex_string2number
bool hex_string2number(const std::string &s, T &t)
attempts to convert a hex string into a numerical representation (of type T)
Definition: binary.h:131
goby::util::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:47
goby::util::hex_encode
void hex_encode(const std::string &in, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of in is written to index 0 ...
Definition: binary.h:94
goby::util::number2hex_string
bool number2hex_string(std::string &s, const T &t, unsigned int width=2)
converts a decimal number of type T into a hex string
Definition: binary.h:145