libxcks  0.1.0.1
ckvalue.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 <algorithm>
27 #include <utility>
28 #include <stdexcept>
29 #include <cstring>
30 #include <cassert>
31 #include <cctype>
32 
33 #include "libxcks/ckvalue.hpp"
34 #include "libxcks/ckfactory.hpp"
35 //---------------------------------------------------------------------------
36 
37 
39 using namespace std;
40 
41 
42 namespace libxcks
43 {
47 ChecksumValue::ChecksumValue()
48 {
49  value = nullptr;
50  valueSize = 0;
51  type = ChecksumAlgoId::Invalid;
52 }
53 //---------------------------------------------------------------------------
54 
55 
61 void ChecksumValue::clone(const ChecksumValue& source)
62 {
63  if (this != &source)
64  setValue(source.value, source.valueSize, source.type);
65 }
66 //---------------------------------------------------------------------------
67 
68 
74 ChecksumValue::ChecksumValue(const ChecksumValue& source) : value(nullptr)
75 {
76  clone(source);
77 }
78 //---------------------------------------------------------------------------
79 
80 
86 ChecksumValue::ChecksumValue(ChecksumValue&& rhs) : value(exchange(rhs.value, nullptr)),
87  valueSize(exchange(rhs.valueSize, 0)),
88  type(exchange(rhs.type, ChecksumAlgoId::Invalid))
89 {
90 }
91 //---------------------------------------------------------------------------
92 
93 
101 {
102  clone(source);
103  return *this;
104 }
105 //---------------------------------------------------------------------------
106 
107 
114 {
115  if (this != &rhs)
116  {
117  if (value != nullptr)
118  delete[] value;
119  value = exchange(rhs.value, nullptr);
120  valueSize = exchange(rhs.valueSize, 0);
121  type = exchange(rhs.type, ChecksumAlgoId::Invalid);
122  }
123  return *this;
124 }
125 //---------------------------------------------------------------------------
126 
127 
135 ChecksumValue::ChecksumValue(const uint8_t* value, const size_t size, const ChecksumAlgoId type)
136 {
137  this->value = nullptr;
138  setValue(value, size, type);
139 }
140 //---------------------------------------------------------------------------
141 
142 
153 ChecksumValue::ChecksumValue(const std::string& strValue, const ChecksumAlgoId type)
154 {
155  this->value = nullptr;
156  setValue(strValue, type);
157 }
158 //---------------------------------------------------------------------------
159 
160 
167 {
168  valueSize = checksum.getSize();
169  value = new uint8_t[valueSize];
170  if (value == nullptr)
171  {
172  valueSize = 0;
173  type = ChecksumAlgoId::Invalid;
174  }
175  else
176  {
177  checksum.getValue(value);
178  type = checksum.getID();
179  }
180 }
181 //---------------------------------------------------------------------------
182 
183 
188 {
189  if (value != nullptr)
190  setValue(nullptr, 0, ChecksumAlgoId::Invalid);
191 }
192 //---------------------------------------------------------------------------
193 
194 
203 {
204  if ((this->valueSize != cmp.valueSize) || (this->type != cmp.type))
205  return false;
206 
207  bool equal = true;
208  size_t i = 0;
209  while (equal && i < this->valueSize)
210  {
211  if (this->value[i] != cmp.value[i])
212  equal = false;
213  i++;
214  }
215 
216  return equal;
217 }
218 //---------------------------------------------------------------------------
219 
220 
229 {
230  return !((*this) == cmp);
231 }
232 //---------------------------------------------------------------------------
233 
234 
245 {
246  assert((this->valueSize == cmp.valueSize) && (this->type == cmp.type));
247 
248  int res = 0;
249  size_t i = 0;
250  while ((res == 0) && i < this->valueSize)
251  {
252  res = this->value[i] - cmp.value[i];
253  i++;
254  }
255 
256  return res;
257 }
258 //---------------------------------------------------------------------------
259 
260 
270 const uint8_t* ChecksumValue::getValue() const
271 {
272  return value;
273 }
274 //---------------------------------------------------------------------------
275 
276 
287 bool ChecksumValue::getValue(uint8_t* value, const size_t size) const
288 {
289  if (size < valueSize)
290  return false;
291 
292  memcpy(value, this->value, valueSize);
293  return true;
294 }
295 //---------------------------------------------------------------------------
296 
297 
305 void ChecksumValue::setValue(const uint8_t* value, const size_t size, const ChecksumAlgoId type)
306 {
307  if ((this->value != nullptr) && (this->value != value))
308  {
309  // Free the old value.
310  delete[] this->value;
311  this->value = nullptr;
312  }
313 
314  if (value == nullptr || size == 0)
315  {
316  this->value = nullptr;
317  this->valueSize = 0;
318  this->type = ChecksumAlgoId::Invalid;
319  }
320  else
321  {
322  this->value = new uint8_t[size];
323  if (this->value == nullptr)
324  {
325  this->valueSize = 0;
326  this->type = ChecksumAlgoId::Invalid;
327  }
328  else
329  {
330  memcpy(this->value, value, size);
331  this->valueSize = size;
332  this->type = type;
333  }
334  }
335 }
336 //---------------------------------------------------------------------------
337 
338 
349 void ChecksumValue::setValue(const std::string& strValue, const ChecksumAlgoId type)
350 {
351  if (strValue.empty())
352  {
353  setValue(nullptr, 0, ChecksumAlgoId::Invalid);
354  return;
355  }
356 
357  size_t size = 0;
358  uint8_t* buf = new uint8_t[strValue.length() / 2];
359  uint8_t* res = buf;
360 
361  const size_t l = strValue.length();
362  size_t i = 0;
363  string b; // buffer string for a byte value
364  int sc = 0; // space count
365  unsigned char c; // the last read character
366  while (res != nullptr && i < l)
367  {
368  c = strValue[i];
369 
370  if (isxdigit(c))
371  {
372  if (sc > 0 && b.length() > 0) // not allowed
373  res = nullptr;
374  else
375  {
376  sc = 0;
377  b += c;
378  if (b.length() == 2)
379  {
380  unsigned long lVal;
381  try
382  {
383  lVal = stoul(b, nullptr, 16);
384  }
385  catch (logic_error&)
386  {
387  res = nullptr;
388  }
389  b.clear();
390  buf[size] = static_cast<uint8_t>(lVal);
391  size++;
392  }
393  }
394  }
395  else if (isspace(c)) // it is a space ?
396  {
397  sc++;
398  if (sc > 1 || i == 0 || i == l - 1) // can't begin or end by a space
399  res = nullptr;
400  }
401  else // not a legal character
402  res = nullptr;
403 
404  i++;
405  }
406  if (!b.empty()) // the last byte isn't complete
407  res = nullptr;
408 
409  if (res == nullptr)
410  setValue(nullptr, 0, ChecksumAlgoId::Invalid);
411  else
412  setValue(res, size, type);
413 
414  delete[] buf;
415 }
416 //---------------------------------------------------------------------------
417 
418 
425 {
426  return valueSize;
427 }
428 //---------------------------------------------------------------------------
429 
430 
437 {
438  return type;
439 }
440 //---------------------------------------------------------------------------
441 
442 
443 
444 //###########################################################################
445 // Helper functions
446 //###########################################################################
447 
457 {
458  bool notFound = true;
459  ArrayChecksumValue::const_iterator it = ckvalues.cbegin();
460 
461  while (notFound && it != ckvalues.cend())
462  {
463  if (it->getType() == type)
464  notFound = false;
465  else
466  it++;
467  }
468 
469  return !notFound;
470 }
471 //---------------------------------------------------------------------------
472 
473 
483 {
484  values.clear();
485  for (const ChecksumAlgoId id : ids)
486  {
487  if (ChecksumFactory::exists(id))
488  values.emplace_back(ChecksumFactory::getNullValue(id));
489  }
490 }
491 //---------------------------------------------------------------------------
492 
493 
494 } // namespace libxcks
495 //---------------------------------------------------------------------------
Classes for enumerate and create all the checksums' algorithms that the application knows.
Stores the value of a checksum.
void LIBXCKS_SO_EXPORT getNullValues(ArrayChecksumValue &values, const ArrayChecksumAlgoId &ids)
Gets an array of null checksums' values from an array of checksums ids.
Definition: ckvalue.cpp:482
std::vector< ChecksumValue > ArrayChecksumValue
Array of values of checksum.
Definition: ckvalue.hpp:113
bool LIBXCKS_SO_EXPORT hasChecksumValueWithAlgoId(const ArrayChecksumValue &ckvalues, const ChecksumAlgoId type)
Checks if the array as a value of the given type.
Definition: ckvalue.cpp:456
static ChecksumValue getNullValue(const ChecksumAlgoId id)
Gives null value of the specified checksum or hash identifier.
Definition: ckfactory.cpp:327
static bool exists(const ChecksumAlgoId id)
Returns true if the given identifier of the checksum or hash algorithm exists.
Definition: ckfactory.cpp:409
Stores the value of a checksum.
Definition: ckvalue.hpp:45
virtual ~ChecksumValue()
Destructor.
Definition: ckvalue.cpp:187
ChecksumValue()
Default constructor.
Definition: ckvalue.cpp:47
ChecksumAlgoId type
Type of the checksum.
Definition: ckvalue.hpp:49
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
ChecksumValue & operator=(const ChecksumValue &source)
Assignment operator.
Definition: ckvalue.cpp:100
int compare(const ChecksumValue &cmp) const
Compares this value with the value of another checksum.
Definition: ckvalue.cpp:244
bool operator!=(const ChecksumValue &cmp) const
Tests if two checksum's values are differents.
Definition: ckvalue.cpp:228
bool operator==(const ChecksumValue &cmp) const
Tests if two checksum's values are equals.
Definition: ckvalue.cpp:202
void setValue(const uint8_t *value, const size_t size, const ChecksumAlgoId type)
Sets the value of the checksum.
Definition: ckvalue.cpp:305
void clone(const ChecksumValue &source)
Clones the source instance in this instance.
Definition: ckvalue.cpp:61
size_t getSize() const
Gets the size of the checksum's value.
Definition: ckvalue.cpp:424
size_t valueSize
Size of the checksum's value.
Definition: ckvalue.hpp:48
uint8_t * value
Value of the checksum.
Definition: ckvalue.hpp:47
Computes a checksum from a byte stream.
Definition: checksum.hpp:54
virtual ChecksumAlgoId getID() const =0
Returns an unique identifier for the checksum or the hash algorithm.
virtual size_t getSize() const =0
Returns the minimal size to allocate in memory to store the checksum with the getValue(buffer) metho...
virtual uint8_t * getValue(uint8_t *buffer) const =0
Returns the checksum value in the first bytes of the given address.
std::vector< ChecksumAlgoId > ArrayChecksumAlgoId
Array of ids of algorithms of checksums.
Definition: types.hpp:92
ChecksumAlgoId
Ids of algorithms of checksums.
Definition: types.hpp:65
@ Invalid
Invalid algorithm id.