CCash/fbe/user_model/fbe_models.cpp
EntireTwix 0130f3c971 🎉 FBE
2021-07-14 22:56:10 -07:00

514 lines
19 KiB
C++

// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#include "fbe_models.h"
namespace FBE {
uint64_t FieldModel<decimal_t>::extract(double a) noexcept
{
uint64_t result;
std::memcpy(&result, &a, sizeof(double));
return result;
}
uint64_t FieldModel<decimal_t>::uint32x32(uint32_t a, uint32_t b) noexcept
{
return (uint64_t)a * (uint64_t)b;
}
void FieldModel<decimal_t>::uint64x64(uint64_t a, uint64_t b, uint64_t& low64, uint32_t& high32) noexcept
{
uint64_t low = uint32x32((uint32_t)a, (uint32_t)b);
uint64_t mid = uint32x32((uint32_t)a, (uint32_t)(b >> 32));
uint64_t high = uint32x32((uint32_t)(a >> 32), (uint32_t)(b >> 32));
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
mid = uint32x32((uint32_t)(a >> 32), (uint32_t)b);
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
if (high > 0xFFFFFFFFu)
{
low64 = 0;
high32 = 0;
}
low64 = low;
high32 = (uint32_t)high;
}
void FieldModel<decimal_t>::get(decimal_t& value, decimal_t defaults) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
{
value = defaults;
return;
}
// Value taken via reverse engineering the double that corresponds to 2^64
const double ds2to64 = 1.8446744073709552e+019;
// Read decimal parts
uint64_t low = *((const uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
uint32_t high = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8));
uint32_t flags = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12));
// Calculate decimal value
double dValue = ((double)low + (double)high * ds2to64) / pow(10.0, (uint8_t)(flags >> 16));
if (flags & 0x80000000)
dValue = -dValue;
value = dValue;
}
void FieldModel<decimal_t>::set(decimal_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
// The most we can scale by is 10^28, which is just slightly more
// than 2^93. So a float with an exponent of -94 could just
// barely reach 0.5, but smaller exponents will always round to zero.
const uint32_t DBLBIAS = 1022;
// Get exponent value
double dValue = (double)value;
int32_t iExp = (int32_t)(((uint32_t)(extract(dValue) >> 52) & 0x7FFu) - DBLBIAS);
if ((iExp < -94) || (iExp > 96))
{
// Value too big for .NET Decimal (exponent is limited to [-94, 96])
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return;
}
uint32_t flags = 0;
if (dValue < 0)
{
dValue = -dValue;
flags = 0x80000000;
}
// Round the input to a 15-digit integer. The R8 format has
// only 15 digits of precision, and we want to keep garbage digits
// out of the Decimal were making.
// Calculate max power of 10 input value could have by multiplying
// the exponent by log10(2). Using scaled integer multiplcation,
// log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
int32_t iPower = 14 - ((iExp * 19728) >> 16);
// iPower is between -14 and 43
if (iPower >= 0)
{
// We have less than 15 digits, scale input up.
if (iPower > 28)
iPower = 28;
dValue *= pow(10.0, iPower);
}
else
{
if ((iPower != -1) || (dValue >= 1E15))
dValue /= pow(10.0, -iPower);
else
iPower = 0; // didn't scale it
}
assert(dValue < 1E15);
if ((dValue < 1E14) && (iPower < 28))
{
dValue *= 10;
iPower++;
assert(dValue >= 1E14);
}
// Round to int64
uint64_t ulMant;
ulMant = (uint64_t)(int64_t)dValue;
dValue -= (int64_t)ulMant; // difference between input & integer
if ((dValue > 0.5) || ((dValue == 0.5) && ((ulMant & 1) != 0)))
ulMant++;
if (ulMant == 0)
{
// Mantissa is 0
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return;
}
if (iPower < 0)
{
// Add -iPower factors of 10, -iPower <= (29 - 15) = 14
iPower = -iPower;
if (iPower < 10)
{
double pow10 = (double)powl(10.0, iPower);
uint64_t low64 = uint32x32((uint32_t)ulMant, (uint32_t)pow10);
uint64_t high64 = uint32x32((uint32_t)(ulMant >> 32), (uint32_t)pow10);
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)low64;
high64 += low64 >> 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4)) = (uint32_t)high64;
high64 >>= 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = (uint32_t)high64;
}
else
{
// Have a big power of 10.
assert(iPower <= 14);
uint64_t low64;
uint32_t high32;
uint64x64(ulMant, (uint64_t)pow(10.0, iPower), low64, high32);
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = low64;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = high32;
}
}
else
{
// Factor out powers of 10 to reduce the scale, if possible.
// The maximum number we could factor out would be 14. This
// comes from the fact we have a 15-digit number, and the
// MSD must be non-zero -- but the lower 14 digits could be
// zero. Note also the scale factor is never negative, so
// we can't scale by any more than the power we used to
// get the integer.
int lmax = iPower;
if (lmax > 14)
lmax = 14;
if ((((uint8_t)ulMant) == 0) && (lmax >= 8))
{
const uint32_t den = 100000000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 8;
lmax -= 8;
}
}
if ((((uint32_t)ulMant & 0xF) == 0) && (lmax >= 4))
{
const uint32_t den = 10000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 4;
lmax -= 4;
}
}
if ((((uint32_t)ulMant & 3) == 0) && (lmax >= 2))
{
const uint32_t den = 100;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 2;
lmax -= 2;
}
}
if ((((uint32_t)ulMant & 1) == 0) && (lmax >= 1))
{
const uint32_t den = 10;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower--;
}
}
flags |= (uint32_t)iPower << 16;
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = ulMant;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = 0;
}
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12)) = flags;
}
void FieldModel<uuid_t>::get(uuid_t& value, uuid_t defaults) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
{
value = defaults;
return;
}
std::memcpy(value.data().data(), (const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), fbe_size());
}
void FieldModel<uuid_t>::set(uuid_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
std::memcpy((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), value.data().data(), fbe_size());
}
size_t FieldModel<buffer_t>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_bytes_offset == 0) || ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
return (size_t)(4 + fbe_bytes_size);
}
bool FieldModel<buffer_t>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return true;
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return false;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return false;
return true;
}
size_t FieldModel<buffer_t>::get(void* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return 0;
assert(((_buffer.offset() + fbe_bytes_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
assert(((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return 0;
size_t result = std::min(size, (size_t)fbe_bytes_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4), result);
return result;
}
void FieldModel<buffer_t>::get(std::vector<uint8_t>& value) const noexcept
{
value.clear();
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return;
assert(((_buffer.offset() + fbe_bytes_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
assert(((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return;
const char* fbe_bytes = (const char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4);
value.assign(fbe_bytes, fbe_bytes + fbe_bytes_size);
}
void FieldModel<buffer_t>::set(const void* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return;
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_bytes_size = (uint32_t)size;
uint32_t fbe_bytes_offset = (uint32_t)(_buffer.allocate(4 + fbe_bytes_size) - _buffer.offset());
assert(((fbe_bytes_offset > 0) && ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_bytes_offset == 0) || ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_bytes_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset)) = fbe_bytes_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4), data, fbe_bytes_size);
}
size_t FieldModel<std::string>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
return (size_t)(4 + fbe_string_size);
}
bool FieldModel<std::string>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_string_offset == 0)
return true;
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return false;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return false;
return true;
}
size_t FieldModel<std::string>::get(char* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_string_offset == 0)
return 0;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return 0;
size_t result = std::min(size, (size_t)fbe_string_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), result);
return result;
}
void FieldModel<std::string>::get(std::string& value) const noexcept
{
value.clear();
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + _offset));
if (fbe_string_offset == 0)
return;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return;
value.assign((const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), fbe_string_size);
}
void FieldModel<std::string>::get(std::string& value, const std::string& defaults) const noexcept
{
value = defaults;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + _offset));
if (fbe_string_offset == 0)
return;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return;
value.assign((const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), fbe_string_size);
}
void FieldModel<std::string>::set(const char* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return;
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_size = (uint32_t)size;
uint32_t fbe_string_offset = (uint32_t)(_buffer.allocate(4 + fbe_string_size) - _buffer.offset());
assert(((fbe_string_offset > 0) && ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset)) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), data, fbe_string_size);
}
void FieldModel<std::string>::set(const std::string& value)
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_size = (uint32_t)value.size();
uint32_t fbe_string_offset = (uint32_t)(_buffer.allocate(4 + fbe_string_size) - _buffer.offset());
assert(((fbe_string_offset > 0) && ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset)) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), value.data(), fbe_string_size);
}
} // namespace FBE