rlp/endian.cpp¶
Namespaces¶
| Name |
|---|
| rlp |
| rlp::endian |
Functions¶
| Name | |
|---|---|
| template <typename T > std::enable_if_t< is_unsigned_integral_v< T >, Bytes > |
to_big_compact(const T & n) |
| template <typename T > std::enable_if_t< is_unsigned_integral_v< T >, DecodingResult > |
from_big_compact(ByteView bytes, T & out) |
| Bytes | to_big_compact(const intx::uint256 & n) |
| DecodingResult | from_big_compact(ByteView bytes, intx::uint256 & out) |
| template auto | to_big_compact< uint8_t >(const uint8_t & ) |
| template auto | to_big_compact< uint16_t >(const uint16_t & ) |
| template auto | to_big_compact< uint32_t >(const uint32_t & ) |
| template auto | to_big_compact< uint64_t >(const uint64_t & ) |
| template auto | from_big_compact< uint8_t >(ByteView , uint8_t & ) |
| template auto | from_big_compact< uint16_t >(ByteView , uint16_t & ) |
| template auto | from_big_compact< uint32_t >(ByteView , uint32_t & ) |
| template auto | from_big_compact< uint64_t >(ByteView , uint64_t & ) |
Functions Documentation¶
function to_big_compact¶
template <typename T >
std::enable_if_t< is_unsigned_integral_v< T >, Bytes > to_big_compact(
const T & n
)
function from_big_compact¶
template <typename T >
std::enable_if_t< is_unsigned_integral_v< T >, DecodingResult > from_big_compact(
ByteView bytes,
T & out
)
function to_big_compact¶
function from_big_compact¶
function to_big_compact< uint8_t >¶
function to_big_compact< uint16_t >¶
function to_big_compact< uint32_t >¶
function to_big_compact< uint64_t >¶
function from_big_compact< uint8_t >¶
function from_big_compact< uint16_t >¶
function from_big_compact< uint32_t >¶
function from_big_compact< uint64_t >¶
Source code¶
#include <rlp/endian.hpp> // Direct include
#include <rlp/common.hpp> // Direct include (for outcome)
#include <rlp/intx.hpp> // Include intx header
#include <algorithm>
#include <stdexcept> // For errors potentially not covered by DecodingError
#include <limits>
namespace rlp::endian {
// --- Implementation for standard unsigned types ---
// Signature now matches the header's SFINAE-on-return-type style
template <typename T>
auto to_big_compact(const T& n) noexcept -> std::enable_if_t<is_unsigned_integral_v<T>, Bytes> {
if ( n == 0 ) {
return {};
}
intx::uint256 val{n};
size_t num_bytes = intx::count_significant_bytes(val);
// Create a temporary buffer large enough for the full uint256
uint8_t temp_buffer[32] = {0};
// Store the full value in the temporary buffer
intx::be::store(temp_buffer, val);
// Only copy the significant bytes to the result
Bytes bytes(&temp_buffer[32 - num_bytes], num_bytes);
return bytes;
}
template <typename T>
auto from_big_compact(ByteView bytes, T& out) noexcept -> std::enable_if_t<is_unsigned_integral_v<T>, DecodingResult> {
if ( bytes.empty() ) {
out = 0;
return outcome::success();
}
if ( bytes[0] == 0 && bytes.length() > 1 ) {
return DecodingError::kLeadingZero;
}
if ( bytes.length() == 1 && bytes[0] == 0 ) {
out = 0;
return outcome::success();
}
// Check if bytes might be too large for the target type
if ( bytes.length() > sizeof(intx::uint256) ) {
return DecodingError::kOverflow;
}
// Create a properly padded buffer with zeros
uint8_t padded[32] = {0};
// Copy the input bytes to the end of the padded buffer for big-endian format
std::memcpy(padded + (32 - bytes.length()), bytes.data(), bytes.length());
// Use the safe load function
intx::uint256 val = intx::be::load<intx::uint256>(padded);
// Check if the value fits in the target type
if ( val > std::numeric_limits<T>::max() ) {
return DecodingError::kOverflow;
}
out = static_cast<T>(val);
return outcome::success();
}
// --- Implementation for intx::uint256 --- (Signatures unchanged)
// --- Implementation for intx::uint256 --- (Signatures unchanged)
Bytes to_big_compact(const intx::uint256& n) noexcept {
if ( n == 0 ) {
return {};
}
size_t num_bytes = intx::count_significant_bytes(n);
// Create a temporary buffer large enough for the full uint256
uint8_t temp_buffer[32] = {0};
// Store the full value in the temporary buffer
intx::be::store(temp_buffer, n);
// Only copy the significant bytes to the result
Bytes bytes(&temp_buffer[32 - num_bytes], num_bytes);
return bytes;
}
DecodingResult from_big_compact(ByteView bytes, intx::uint256& out) noexcept {
if ( bytes.empty() ) {
out = 0;
return outcome::success();
}
if ( bytes[0] == 0 && bytes.length() > 1 ) {
return DecodingError::kLeadingZero;
}
if ( bytes.length() == 1 && bytes[0] == 0 ) {
out = 0;
return outcome::success();
}
if ( bytes.length() > sizeof(intx::uint256) ) {
return DecodingError::kOverflow;
}
// Create a properly padded buffer with zeros
uint8_t padded[32] = {0};
// Copy the input bytes to the end of the padded buffer
// For big-endian, we need to copy to the last bytes
// (32 - bytes.length()) gives us the offset where the significant bytes start
std::memcpy(padded + (32 - bytes.length()), bytes.data(), bytes.length());
// Use the safe load function
out = intx::be::load<intx::uint256>(padded);
return outcome::success();
}
// --- Explicit Template Instantiations ---
// The signature MUST exactly match the definition signature, including the SFINAE part
template auto to_big_compact<uint8_t>(const uint8_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint8_t>, Bytes>;
template auto to_big_compact<uint16_t>(const uint16_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint16_t>, Bytes>;
template auto to_big_compact<uint32_t>(const uint32_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint32_t>, Bytes>;
template auto to_big_compact<uint64_t>(const uint64_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint64_t>, Bytes>;
template auto from_big_compact<uint8_t>(ByteView, uint8_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint8_t>, DecodingResult>;
template auto from_big_compact<uint16_t>(ByteView, uint16_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint16_t>, DecodingResult>;
template auto from_big_compact<uint32_t>(ByteView, uint32_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint32_t>, DecodingResult>;
template auto from_big_compact<uint64_t>(ByteView, uint64_t&) noexcept -> std::enable_if_t<is_unsigned_integral_v<uint64_t>, DecodingResult>;
} // namespace rlp::endian
Updated on 2026-04-13 at 23:22:46 -0700