Goby v2
base_convert.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 #include <gmp.h>
24 
25 #include <string>
26 
27 namespace goby
28 {
29 namespace util
30 {
31 inline void base_convert(const std::string& source, std::string* sink, int source_base,
32  int sink_base)
33 {
34  mpz_t base10;
35  mpz_init(base10);
36 
37  // record number of most significant zeros, e.g. 0023 has two
38  int ms_zeros = 0;
39  // false until a non-zero byte is encountered
40  bool non_zero_byte = false;
41 
42  for (int i = source.size() - 1; i >= 0; --i)
43  {
44  int byte = 0xFF & source[i];
45  mpz_add_ui(base10, base10, byte);
46  if (i)
47  mpz_mul_ui(base10, base10, source_base);
48 
49  if (byte == 0 && !non_zero_byte)
50  ++ms_zeros;
51  else
52  non_zero_byte = true;
53  }
54  sink->clear();
55 
56  while (mpz_cmp_ui(base10, 0) != 0)
57  {
58  unsigned long int remainder = mpz_fdiv_q_ui(base10, base10, sink_base);
59  sink->push_back(0xFF & remainder);
60  }
61 
62  // preserve MS zeros by adding that number to the most significant end
63  for (int i = 0; i < ms_zeros; ++i) sink->push_back(0);
64 
65  mpz_clear(base10);
66 }
67 } // namespace util
68 } // namespace goby
The global namespace for the Goby project.