libcryfs/src/cpp-utils/data/FixedSizeData.h

136 lines
3.8 KiB
C
Raw Normal View History

2015-04-25 02:21:39 +02:00
#pragma once
#ifndef MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
#define MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
#include <vendor_cryptopp/hex.h>
2015-04-25 02:21:39 +02:00
#include <string>
#include <array>
2015-04-25 02:21:39 +02:00
#include <cstring>
2015-07-22 13:38:36 +02:00
#include "../assert/assert.h"
2015-04-25 02:21:39 +02:00
namespace cpputils {
template<size_t SIZE>
2015-10-22 17:36:03 +02:00
class FixedSizeData final {
2015-04-25 02:21:39 +02:00
public:
//Non-virtual destructor because we want objects to be small
2017-09-09 15:40:34 +02:00
~FixedSizeData() = default;
2015-04-25 02:21:39 +02:00
static constexpr size_t BINARY_LENGTH = SIZE;
static constexpr size_t STRING_LENGTH = 2 * BINARY_LENGTH; // Hex encoding
2015-04-25 02:21:39 +02:00
2015-10-04 17:14:32 +02:00
//TODO Test Null()
static FixedSizeData<SIZE> Null();
2015-04-25 02:21:39 +02:00
static FixedSizeData<SIZE> FromString(const std::string &data);
std::string ToString() const;
static FixedSizeData<SIZE> FromBinary(const void *source);
void ToBinary(void *target) const;
const unsigned char *data() const;
2015-10-22 17:36:03 +02:00
unsigned char *data();
2015-04-25 02:21:39 +02:00
2015-10-26 12:15:11 +01:00
template<size_t size> FixedSizeData<size> take() const;
template<size_t size> FixedSizeData<SIZE-size> drop() const;
2015-04-25 02:21:39 +02:00
private:
FixedSizeData(): _data() {}
2021-04-21 08:09:00 +02:00
template<size_t SIZE_> friend class FixedSizeData;
2015-04-25 02:21:39 +02:00
std::array<unsigned char, BINARY_LENGTH> _data;
2015-04-25 02:21:39 +02:00
};
template<size_t SIZE> bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
template<size_t SIZE> bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
2015-04-25 02:21:39 +02:00
// ----- Implementation -----
template<size_t SIZE> constexpr size_t FixedSizeData<SIZE>::BINARY_LENGTH;
template<size_t SIZE> constexpr size_t FixedSizeData<SIZE>::STRING_LENGTH;
2015-04-25 02:21:39 +02:00
template<size_t SIZE>
2015-10-04 17:14:32 +02:00
FixedSizeData<SIZE> FixedSizeData<SIZE>::Null() {
FixedSizeData<SIZE> result;
std::memset(result._data.data(), 0, BINARY_LENGTH);
2015-10-04 17:14:32 +02:00
return result;
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
2015-07-22 13:38:36 +02:00
ASSERT(data.size() == STRING_LENGTH, "Wrong string size for parsing FixedSizeData");
2015-04-25 02:21:39 +02:00
FixedSizeData<SIZE> result;
2018-10-14 22:26:30 +02:00
{
CryptoPP::StringSource _1(data, true,
new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(result._data.data(), BINARY_LENGTH)
2018-10-14 22:26:30 +02:00
)
);
}
2015-04-25 02:21:39 +02:00
return result;
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
std::string FixedSizeData<SIZE>::ToString() const {
std::string result;
CryptoPP::ArraySource(_data.data(), BINARY_LENGTH, true,
2015-04-25 02:21:39 +02:00
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result)
)
);
2015-07-22 13:38:36 +02:00
ASSERT(result.size() == STRING_LENGTH, "Created wrongly sized string");
2015-04-25 02:21:39 +02:00
return result;
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
const unsigned char *FixedSizeData<SIZE>::data() const {
return _data.data();
2015-04-25 02:21:39 +02:00
}
template<size_t SIZE>
2015-10-22 17:36:03 +02:00
unsigned char *FixedSizeData<SIZE>::data() {
return const_cast<unsigned char*>(const_cast<const FixedSizeData<SIZE>*>(this)->data());
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
void FixedSizeData<SIZE>::ToBinary(void *target) const {
std::memcpy(target, _data.data(), BINARY_LENGTH);
2015-04-25 02:21:39 +02:00
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromBinary(const void *source) {
FixedSizeData<SIZE> result;
std::memcpy(result._data.data(), source, BINARY_LENGTH);
2015-04-25 02:21:39 +02:00
return result;
}
template<size_t SIZE> template<size_t size>
2015-10-26 12:15:11 +01:00
FixedSizeData<size> FixedSizeData<SIZE>::take() const {
static_assert(size <= SIZE, "Out of bounds");
FixedSizeData<size> result;
std::memcpy(result._data.data(), _data.data(), size);
2015-10-26 12:15:11 +01:00
return result;
}
template<size_t SIZE> template<size_t size>
2015-10-26 12:15:11 +01:00
FixedSizeData<SIZE-size> FixedSizeData<SIZE>::drop() const {
static_assert(size <= SIZE, "Out of bounds");
FixedSizeData<SIZE-size> result;
std::memcpy(result._data.data(), _data.data()+size, SIZE-size);
2015-10-26 12:15:11 +01:00
return result;
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
return 0 == std::memcmp(lhs.data(), rhs.data(), FixedSizeData<SIZE>::BINARY_LENGTH);
}
template<size_t SIZE>
2015-04-25 02:21:39 +02:00
bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
return !operator==(lhs, rhs);
}
}
#endif