DCCL v5
Loading...
Searching...
No Matches
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#include "thirdparty/base64/base64.hpp"
36
37namespace dccl
38{
40
41
46inline void hex_decode(const std::string& in, std::string* out)
47{
48 static constexpr short char0_9_to_number = 48;
49 static constexpr short charA_F_to_number = 55;
50 static constexpr short chara_f_to_number = 87;
51
52 int in_size = in.size();
53 int out_size = in_size >> 1;
54 if (in_size & 1)
55 ++out_size;
56
57 out->assign(out_size, '\0');
58 for (int i = (in_size & 1) ? -1 : 0, n = in_size; i < n; i += 2)
59 {
60 int out_i = (in_size & 1) ? (i + 1) / 2 : i / 2;
61
62 if (i >= 0)
63 {
64 if (in[i] >= '0' && in[i] <= '9')
65 (*out)[out_i] |= ((in[i] - char0_9_to_number) & 0x0f) << 4;
66 else if (in[i] >= 'A' && in[i] <= 'F')
67 (*out)[out_i] |= ((in[i] - charA_F_to_number) & 0x0f) << 4;
68 else if (in[i] >= 'a' && in[i] <= 'f')
69 (*out)[out_i] |= ((in[i] - chara_f_to_number) & 0x0f) << 4;
70 }
71
72 if (in[i + 1] >= '0' && in[i + 1] <= '9')
73 (*out)[out_i] |= (in[i + 1] - char0_9_to_number) & 0x0f;
74 else if (in[i + 1] >= 'A' && in[i + 1] <= 'F')
75 (*out)[out_i] |= (in[i + 1] - charA_F_to_number) & 0x0f;
76 else if (in[i + 1] >= 'a' && in[i + 1] <= 'f')
77 (*out)[out_i] |= (in[i + 1] - chara_f_to_number) & 0x0f;
78 }
79}
80
81inline std::string hex_decode(const std::string& in)
82{
83 std::string out;
84 hex_decode(in, &out);
85 return out;
86}
87
94template <typename CharIterator>
95inline void hex_encode(CharIterator begin, CharIterator end, std::string* out,
96 bool upper_case = false)
97{
98 static constexpr short char0_9_to_number = 48;
99 static constexpr short charA_F_to_number = 55;
100 static constexpr short chara_f_to_number = 87;
101
102 size_t in_size = std::distance(begin, end);
103 size_t out_size = in_size << 1;
104
105 out->clear();
106 out->resize(out_size);
107
108 size_t i = 0;
109 for (CharIterator it = begin; it != end; ++it)
110 {
111 short msn = (*it >> 4) & 0x0f;
112 short lsn = *it & 0x0f;
113
114 if (msn >= 0 && msn <= 9)
115 (*out)[2 * i] = msn + char0_9_to_number;
116 else if (msn >= 10 && msn <= 15)
117 (*out)[2 * i] = msn + (upper_case ? charA_F_to_number : chara_f_to_number);
118
119 if (lsn >= 0 && lsn <= 9)
120 (*out)[2 * i + 1] = lsn + char0_9_to_number;
121 else if (lsn >= 10 && lsn <= 15)
122 (*out)[2 * i + 1] = lsn + (upper_case ? charA_F_to_number : chara_f_to_number);
123
124 i++;
125 }
126}
127
128template <typename CharIterator> inline std::string hex_encode(CharIterator begin, CharIterator end)
129{
130 std::string out;
131 hex_encode(begin, end, &out);
132 return out;
133}
134
140inline void hex_encode(const std::string& in, std::string* out, bool upper_case = false)
141{
142 hex_encode(in.begin(), in.end(), out, upper_case);
143}
144
145inline std::string hex_encode(const std::string& in)
146{
147 std::string out;
148 hex_encode(in, &out);
149 return out;
150}
151
152inline std::string b64_encode(const std::string& in)
153{
154 return base64::to_base64(in);
155}
156
157inline std::string b64_decode(const std::string& in)
158{
159 return base64::from_base64(in);
160}
161
163inline unsigned ceil_log2(dccl::uint64 v)
164{
165 // r will be one greater (ceil) if v is not a power of 2
166 unsigned r = ((v & (v - 1)) == 0) ? 0 : 1;
167 while (v >>= 1) r++;
168 return r;
169}
170
171inline unsigned long ceil_log2(double d)
172{
173 return ceil_log2(static_cast<dccl::uint64>(std::ceil(d)));
174}
175
176inline unsigned long ceil_log2(int i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
177
178inline unsigned long ceil_log2(long i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
179
180inline unsigned long ceil_log2(unsigned i) { return ceil_log2(static_cast<dccl::uint64>(i)); }
181
182inline double log2(double d) { return std::log2(d); }
183
185} // namespace dccl
186
187#endif
Dynamic Compact Control Language namespace.
Definition any.h:28
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition common.h:60
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:95
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:46
unsigned ceil_log2(dccl::uint64 v)
Definition binary.h:163