libxcks  0.1.0.1
ckformatter.cpp
Go to the documentation of this file.
1 /*
2  * libxcks
3  * Copyright (C) 2022 Julien Couot
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 //---------------------------------------------------------------------------
26 #include <sstream>
27 #include <algorithm>
28 #include <regex>
29 
30 #include "libxcks/ckformatter.hpp"
31 #include "libxcks/ckfactory.hpp"
32 //---------------------------------------------------------------------------
33 
34 
36 using namespace std;
37 
38 
39 namespace libxcks
40 {
41 //###########################################################################
42 // A checksum' formatter
43 //###########################################################################
44 
54 ChecksumFormatter::ChecksumFormatter(const ConfigurationProvider& provider,
55  const std::string& algoName, const bool lookInAltNames)
56 {
57  ChecksumAlgoId id;
58 
59  if (!ChecksumFactory::getAlgorithmId(id, algoName, lookInAltNames))
60  id = ChecksumAlgoId::Invalid;
61 
62  initialise(provider, id);
63 }
64 //---------------------------------------------------------------------------
65 
66 
73 ChecksumFormatter::ChecksumFormatter(const ConfigurationProvider& provider,
74  const ChecksumAlgoId type)
75 {
76  initialise(provider, type);
77 }
78 //---------------------------------------------------------------------------
79 
80 
88 ChecksumFormatter::ChecksumFormatter(const bool uc, const NumericBase nb,
89  const Positions& sp)
90 {
91  setUpperCase(uc);
92  setNumericBase(nb);
93  setSpacesPositions(sp);
94 }
95 //---------------------------------------------------------------------------
96 
97 
104 void ChecksumFormatter::initialise(const ConfigurationProvider& provider,
105  const ChecksumAlgoId type)
106 {
107  setUpperCase(provider.getUpperCase(type));
108  setNumericBase(provider.getNumericBase(type));
109  setSpacesPositions(provider.getSpacesPositions(type));
110 }
111 //---------------------------------------------------------------------------
112 
113 
120 string ChecksumFormatter::format(const uint8_t* value, const size_t size)
121 {
122  if (value == nullptr || size == 0)
123  return string();
124 
125  string byteFormatter;
126  switch (getNumericBase())
127  {
128  case NumericBase::octal :
129  byteFormatter = "%03o";
130  break;
131  case NumericBase::decimal :
132  byteFormatter = "%03u";
133  break;
134  default : // hexadecimal
135  byteFormatter = (getUpperCase()) ? "%02X" : "%02x";
136  }
137 
138  ostringstream ss;
139  size_t lastSpacePos = size - 1;
140  constexpr size_t bufSize = 4;
141  char buf[bufSize];
142  for (size_t i = 0; i < size; i++)
143  {
144  snprintf(buf, bufSize, byteFormatter.c_str(), static_cast<uint_fast16_t>(value[i]));
145  ss << buf;
146 
147  if (i < lastSpacePos && std::find(spacesPos.begin(), spacesPos.end(), static_cast<unsigned int>(i)) != spacesPos.end())
148  ss << ' ';
149  }
150 
151  return ss.str();
152 }
153 //---------------------------------------------------------------------------
154 
155 
161 bool ChecksumFormatter::getUpperCase() const
162 {
163  return upperCase;
164 }
165 //---------------------------------------------------------------------------
166 
167 
174 void ChecksumFormatter::setUpperCase(const bool isUpperCase)
175 {
176  upperCase = isUpperCase;
177 }
178 //---------------------------------------------------------------------------
179 
180 
186 ChecksumFormatter::NumericBase ChecksumFormatter::getNumericBase() const
187 {
188  return numericBase;
189 }
190 //---------------------------------------------------------------------------
191 
192 
200 void ChecksumFormatter::setNumericBase(const NumericBase base)
201 {
202  switch (base)
203  {
204  case NumericBase::hexadecimal :
205  case NumericBase::octal :
206  case NumericBase::decimal :
207  numericBase = base;
208  break;
209  default :
210  numericBase = NumericBase::hexadecimal;
211  }
212 }
213 //---------------------------------------------------------------------------
214 
215 
221 ChecksumFormatter::Positions ChecksumFormatter::getSpacesPositions() const
222 {
223  return spacesPos;
224 }
225 //---------------------------------------------------------------------------
226 
227 
237 void ChecksumFormatter::setSpacesPositions(const std::string& spacesPositions)
238 {
239  Positions sp = toSpacesPositions(spacesPositions);
240 
241  setSpacesPositions(sp);
242 }
243 //---------------------------------------------------------------------------
244 
245 
251 void ChecksumFormatter::setSpacesPositions(const Positions& spacesPositions)
252 {
253  spacesPos = spacesPositions;
254 }
255 //---------------------------------------------------------------------------
256 
257 
269 string ChecksumFormatter::format(const ConfigurationProvider& provider,
270  const uint8_t* value, const size_t size,
271  const std::string& algoName,
272  const bool lookInAltNames)
273 {
274  ChecksumAlgoId id;
275 
276  if (!ChecksumFactory::getAlgorithmId(id, algoName, lookInAltNames))
277  id = ChecksumAlgoId::Invalid;
278 
279  return format(provider, value, size, id);
280 }
281 //---------------------------------------------------------------------------
282 
283 
293 string ChecksumFormatter::format(const ConfigurationProvider& provider,
294  const uint8_t* value, const size_t size,
295  const ChecksumAlgoId type)
296 {
297  ChecksumFormatter ckf(provider, type);
298  return ckf.format(value, size);
299 }
300 //---------------------------------------------------------------------------
301 
302 
310 string ChecksumFormatter::format(const ConfigurationProvider& provider,
311  const ChecksumValue& value)
312 {
313  return format(provider, value.getValue(), value.getSize(), value.getType());
314 }
315 //---------------------------------------------------------------------------
316 
317 
328 ChecksumFormatter::Positions ChecksumFormatter::toSpacesPositions(const std::string& spacesPositions)
329 {
330  const regex re(R"(\s*[,]\s*)"); // R"([\s|,]+)"
331  sregex_token_iterator it{ spacesPositions.begin(), spacesPositions.end(), re, -1 };
332  ArrayString ssp{ it, {} };
333  ssp.erase(std::remove_if(ssp.begin(), ssp.end(), [](string const& s) {
334  return s.empty(); }),
335  ssp.end());
336 
337  Positions sp;
338  for (string token : ssp)
339  {
340  unsigned long lPos;
341  try
342  {
343  lPos = stoul(token);
344  sp.insert(static_cast<uint_fast16_t>(lPos));
345  }
346  catch (logic_error&)
347  {
348  // Ignore conversion error.
349  }
350  }
351 
352  return sp;
353 }
354 //---------------------------------------------------------------------------
355 
356 } // namespace libxcks
357 //---------------------------------------------------------------------------
Classes for enumerate and create all the checksums' algorithms that the application knows.
Format checksum and hash values.
Configuration provider for ChecksumFormatter.
Definition: ckformatter.hpp:69
virtual NumericBase getNumericBase(const ChecksumAlgoId type) const =0
Returns the numeric base for a given type of algorithm of checksums.
virtual const Positions & getSpacesPositions(const ChecksumAlgoId type) const =0
Returns the positions of the spaces between two bytes for a given type of algorithm of checksums.
virtual bool getUpperCase(const ChecksumAlgoId type) const =0
Returns whether the output will be in uppercase for a given type of algorithm of checksums.
This class provides some convenient tools to format checksum and hash values.
Definition: ckformatter.hpp:52
std::string format(const uint8_t *value, const size_t size)
Format the given checksum's value.
std::set< uint_fast16_t > Positions
Set of unsigned integers.
Definition: ckformatter.hpp:55
NumericBase
The available numeric bases.
Definition: ckformatter.hpp:59
Stores the value of a checksum.
Definition: ckvalue.hpp:45
ChecksumAlgoId getType() const
Gets the type of the checksum.
Definition: ckvalue.cpp:436
const uint8_t * getValue() const
Gets the value of the checksum.
Definition: ckvalue.cpp:270
size_t getSize() const
Gets the size of the checksum's value.
Definition: ckvalue.cpp:424
ChecksumAlgoId
Ids of algorithms of checksums.
Definition: types.hpp:65
std::vector< std::string > ArrayString
Array of strings.
Definition: types.hpp:44