mirror of https://github.com/infosecn1nja/C3.git
131 lines
5.6 KiB
C++
131 lines
5.6 KiB
C++
#pragma once
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<typename UnderlyingIntegerType>
|
|
const FSecure::C3::Identifier<UnderlyingIntegerType> FSecure::C3::Identifier<UnderlyingIntegerType>::Null{ static_cast<UnderlyingIntegerType>(0) };
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
constexpr FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier()
|
|
: m_Id(0)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
constexpr FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier(UnderlyingIntegerType id)
|
|
: m_Id(id)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier(std::string_view textId)
|
|
{
|
|
// Sanity check.
|
|
//if (textId.size() != TextSize)
|
|
// throw std::runtime_error{ OBF("Invalid string Identifier size.") };
|
|
|
|
// Parse and return.
|
|
std::size_t pos;
|
|
m_Id = static_cast<UnderlyingIntegerType>(std::stoull(textId.data(), &pos, 16));
|
|
if (pos != textId.size())
|
|
throw std::runtime_error{ OBF("Invalid Identifier string characters.") };
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier(std::string const& textId)
|
|
: Identifier{ std::string_view{textId} }
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
FSecure::C3::Identifier<UnderlyingIntegerType> FSecure::C3::Identifier<UnderlyingIntegerType>::GenerateRandom()
|
|
{
|
|
return FSecure::Utils::GenerateRandomValue<UnderlyingIntegerType>();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
std::string FSecure::C3::Identifier<UnderlyingIntegerType>::ToString() const
|
|
{
|
|
// Initialize buffers and pointers.
|
|
std::string ret(sizeof(UnderlyingIntegerType) * 2 + 1, '0');
|
|
char* rp = ret.data();
|
|
|
|
// Note: this function adds a null terminator.
|
|
auto p = reinterpret_cast<const uint8_t*>(&m_Id);
|
|
for (int i = 0; i < sizeof(UnderlyingIntegerType); ++i)
|
|
sprintf_s(&rp[i * 2], 3, OBF("%02hhX"), p[sizeof(UnderlyingIntegerType) - i - 1]);
|
|
|
|
// Remove the trailing null.
|
|
return ret.substr(0, sizeof(UnderlyingIntegerType) * 2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator!() const
|
|
{
|
|
return IsNull();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator==(Identifier const& c) const
|
|
{
|
|
return c.m_Id == m_Id;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator!=(Identifier const& c) const
|
|
{
|
|
return !operator == (c);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator<(Identifier const& c) const
|
|
{
|
|
return m_Id < c.m_Id;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
template<typename UnderlyingIntegerType>
|
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::IsNull() const
|
|
{
|
|
return m_Id == 0;
|
|
}
|
|
|
|
template<typename UnderlyingIntegerType>
|
|
UnderlyingIntegerType FSecure::C3::Identifier<UnderlyingIntegerType>::ToUnderlyingType() const
|
|
{
|
|
return m_Id;
|
|
}
|
|
|
|
namespace FSecure
|
|
{
|
|
/// Specialize ByteConverter for identifiers.
|
|
template <typename T>
|
|
struct ByteConverter <C3::Identifier<T>>
|
|
{
|
|
static void To(C3::Identifier<T> const& obj, ByteVector& bv)
|
|
{
|
|
bv.Store(obj.ToUnderlyingType());
|
|
}
|
|
|
|
constexpr static size_t Size()
|
|
{
|
|
return sizeof(typename C3::Identifier<T>::UnderlyingIntegerType);
|
|
}
|
|
|
|
static C3::Identifier<T> From(ByteView& bv)
|
|
{
|
|
return bv.Read<typename C3::Identifier<T>::UnderlyingIntegerType>();
|
|
}
|
|
};
|
|
}
|