Skip to content

Commit

Permalink
fix BCD + simplified buffer and contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
cppden committed Aug 24, 2024
1 parent d8981c4 commit e9bcbf7
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 169 deletions.
53 changes: 25 additions & 28 deletions med/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ Distributed under the MIT License

namespace med {

template <typename PTR, std::size_t LEN_DEPTH = 16>
template <typename T, std::size_t LEN_DEPTH = 16> requires (sizeof(T) == 1 && std::is_integral_v<T>)
class buffer
{
using eob_index_t = uint8_t;
static constexpr eob_index_t MAX_EOB_INDEX = std::numeric_limits<eob_index_t>::max();

public:
using pointer = PTR;
using value_type = std::remove_const_t<std::remove_pointer_t<pointer>>;
using pointer = T*;
using value_type = std::remove_const_t<T>;
static constexpr auto is_const_v = std::is_const_v<T>;

constexpr buffer() noexcept = default;

Expand Down Expand Up @@ -129,24 +130,20 @@ class buffer
}
}

constexpr void reset() { m_state.reset(get_start()); }

constexpr void reset(std::span<value_type> chunk)
{
m_start = chunk.data();
m_state.reset(m_start);
end(m_start + chunk.size());
}

constexpr void reset(pointer p, std::size_t s)
constexpr void reset() noexcept { m_state.reset(get_start()); }
constexpr void reset(void const* p, std::size_t s) noexcept
{
m_start = p;
m_start = static_cast<pointer>(const_cast<void*>(p));
m_state.reset(m_start);
end(m_start + s);
}
template <typename U> requires (std::is_integral_v<U>)
constexpr void reset(std::span<U> p) noexcept { reset(p.data(), p.size_bytes()); }
template <typename U, size_t SZ>
constexpr void reset(U (&p)[SZ]) noexcept { reset(p, sizeof(p)); }

constexpr state_type get_state() const { return m_state; }
constexpr void set_state(state_type const& st) { m_state = st; }
constexpr state_type get_state() const noexcept { return m_state; }
constexpr void set_state(state_type const& st) noexcept { m_state = st; }

constexpr bool push_state()
{
Expand All @@ -172,20 +169,20 @@ class buffer
}
}

constexpr pointer get_start() const { return m_start; }
constexpr std::size_t get_offset() const { return begin() - get_start(); }
constexpr std::span<value_type> used() const { return {get_start(), get_offset()}; }
constexpr std::size_t size() const { return end() - begin(); }
constexpr bool empty() const { return begin() >= end(); }
explicit constexpr operator bool() const { return !empty(); }
constexpr pointer get_start() const noexcept { return m_start; }
constexpr size_t get_offset() const noexcept { return begin() - get_start(); }
constexpr std::span<value_type> used() const noexcept { return {get_start(), get_offset()}; }
constexpr size_t size() const noexcept { return end() - begin(); }
constexpr bool empty() const noexcept { return begin() >= end(); }
explicit constexpr operator bool() const noexcept { return !empty(); }

template <class IE> constexpr void push(value_type v)
template <class IE> constexpr void push(value_type v) requires (!is_const_v)
{
if (not empty()) { *m_state.cursor++ = v; }
else { MED_THROW_EXCEPTION(overflow, name<IE>(), sizeof(value_type), *this) }
}

template <class IE> constexpr value_type pop()
template <class IE> constexpr value_type pop() requires (is_const_v)
{
if (not empty()) { return *m_state.cursor++; }
else { MED_THROW_EXCEPTION(overflow, name<IE>(), sizeof(value_type), *this) }
Expand Down Expand Up @@ -229,9 +226,9 @@ class buffer
}

/// similar to advance but no bounds check
constexpr void offset(int delta) { m_state.cursor += delta; }
constexpr void offset(int delta) noexcept { m_state.cursor += delta; }

template <class IE> constexpr void fill(std::size_t count, uint8_t value)
template <class IE> constexpr void fill(std::size_t count, uint8_t value) requires (!is_const_v)
{
//CODEC_TRACE("padding %zu bytes=%u", count, value);
if (size() >= count)
Expand All @@ -244,8 +241,8 @@ class buffer
}
}

constexpr pointer begin() const { return m_state.cursor; }
constexpr pointer end() const { return m_end; }
constexpr pointer begin() const noexcept { return m_state.cursor; }
constexpr pointer end() const noexcept { return m_end; }

/**
* Adjusts the end of buffer pointer
Expand Down
2 changes: 1 addition & 1 deletion med/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Distributed under the MIT License
#include <cstdio>
#include <string_view>

#define CODEC_TRACE_ENABLE
//#define CODEC_TRACE_ENABLE

#define CODEC_TRACE(FMT, ...) CODEC_TRACE_FL(__FILE__, __LINE__, FMT, __VA_ARGS__)

Expand Down
38 changes: 12 additions & 26 deletions med/decoder_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace med {

template <
class ALLOCATOR = const null_allocator,
class BUFFER = buffer<uint8_t const*>
class BUFFER = buffer<uint8_t const>
>
class decoder_context : public detail::allocator_holder<ALLOCATOR>
{
Expand All @@ -26,34 +26,20 @@ class decoder_context : public detail::allocator_holder<ALLOCATOR>
using buffer_type = BUFFER;
using state_t = typename buffer_type::state_type;

decoder_context(void const* data, std::size_t size, allocator_type* alloc = nullptr)
: detail::allocator_holder<allocator_type>{alloc}
{
reset(data, size);
}

decoder_context()
: decoder_context(nullptr, 0)
{
}

template <typename T, std::size_t SIZE>
decoder_context(T const (&data)[SIZE], allocator_type* alloc = nullptr)
: decoder_context(data, sizeof(data), alloc)
{
}

decoder_context() noexcept : decoder_context(nullptr, 0){}
decoder_context(void const* p, size_t s, allocator_type* a = nullptr) noexcept
: detail::allocator_holder<allocator_type>{a} { reset(p, s); }
template <typename T, size_t SIZE>
decoder_context(T const (&p)[SIZE], allocator_type* a = nullptr) noexcept
: decoder_context(p, sizeof(p), a) {}
template <typename T>
decoder_context(std::span<T> p, allocator_type* a = nullptr) noexcept
: decoder_context(p.data(), p.size_bytes(), a) {}

buffer_type& buffer() noexcept { return m_buffer; }

void reset(void const* data, std::size_t size)
{
buffer().reset(static_cast<typename buffer_type::pointer>(data), size);
}
template <typename T, std::size_t SIZE>
void reset(T const (&data)[SIZE]) { reset(data, sizeof(data)/sizeof(T)); }

void reset() { buffer().reset(); }
template <typename... Ts>
constexpr void reset(Ts&&... args)noexcept{ buffer().reset(std::forward<Ts>(args)...); }

private:
decoder_context(decoder_context const&) = delete;
Expand Down
35 changes: 12 additions & 23 deletions med/encoder_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace med {

template <
class ALLOCATOR = const null_allocator,
class BUFFER = buffer<uint8_t*>
class BUFFER = buffer<uint8_t>
>
class encoder_context : public detail::allocator_holder<ALLOCATOR>
{
Expand All @@ -40,31 +40,20 @@ class encoder_context : public detail::allocator_holder<ALLOCATOR>
encoder_context(encoder_context const&) = delete;
encoder_context& operator=(encoder_context const&) = delete;

constexpr encoder_context(void* data, std::size_t size, allocator_type* alloc = nullptr)
: detail::allocator_holder<allocator_type>{alloc}
{
reset(data, size);
}
constexpr encoder_context(void* p, size_t s, allocator_type* a = nullptr) noexcept
: detail::allocator_holder<allocator_type>{a} { reset(p, s); }

template <typename T, std::size_t SIZE>
explicit constexpr encoder_context(T (&buf)[SIZE], allocator_type* alloc = nullptr)
: encoder_context(buf, sizeof(buf), alloc) {}
template <typename T, size_t SIZE>
explicit constexpr encoder_context(T (&p)[SIZE], allocator_type* a = nullptr) noexcept
: encoder_context(p, sizeof(p), a) {}

constexpr buffer_type& buffer() noexcept { return m_buffer; }
constexpr buffer_type const& buffer()const noexcept { return m_buffer; }

template <typename T, std::size_t SIZE>
constexpr void reset(T (&data)[SIZE]) noexcept { reset(data, SIZE * sizeof(T)); }

constexpr void reset(void* data, std::size_t size) noexcept
{
m_buffer.reset({static_cast<typename buffer_type::pointer>(data), size});
m_snapshot = nullptr;
}

constexpr void reset()
template <typename... Ts>
constexpr void reset(Ts... args) noexcept
{
m_buffer.reset();
buffer().reset(args...);
m_snapshot = nullptr;
}

Expand All @@ -86,18 +75,18 @@ class encoder_context : public detail::allocator_holder<ALLOCATOR>
class snap_s : public state_t
{
public:
constexpr bool validate_length(std::size_t s) const
constexpr bool validate_length(size_t s) const
{
CODEC_TRACE("%s(%zu ? %zu)=%d", __FUNCTION__, m_length, s, m_length == s);
return m_length == s;
}

private:
friend class encoder_context;
constexpr snap_s(state_t const& st, std::size_t len) : state_t{st}, m_length{len} {}
constexpr snap_s(state_t const& st, size_t len) : state_t{st}, m_length{len} {}
constexpr snap_s() = default;

std::size_t m_length{};
size_t m_length{};
};

/**
Expand Down
3 changes: 1 addition & 2 deletions med/length.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,10 @@ constexpr std::size_t ie_length(IE const& ie, ENCODER& encoder) noexcept
else //data itself
{
CODEC_TRACE("%s[%s]<%s:%s> - DATA", __FUNCTION__, name<IE>(), name<EXP_TAG>(), name<EXP_LEN>());
using ie_type = typename IE::ie_type;
if constexpr (AContainer<IE>)
{
using ctx = type_context<typename TYPE_CTX::ie_type, meta::typelist<>, EXP_TAG, EXP_LEN>;
CODEC_TRACE("%s[%.30s]%s<%s:%s>: %s", __FUNCTION__, name<IE>(), AMultiField<IE>?"*":"", name<EXP_TAG>(), name<EXP_LEN>(), name<ie_type>());
CODEC_TRACE("%s[%.30s]%s<%s:%s>: %s", __FUNCTION__, name<IE>(), AMultiField<IE>?"*":"", name<EXP_TAG>(), name<EXP_LEN>(), name<typename IE::ie_type>());
len += ie.template calc_length<ctx>(encoder);
CODEC_TRACE("%s[%s] : len(SEQ) = %zu", __FUNCTION__, name<IE>(), len);
}
Expand Down
16 changes: 8 additions & 8 deletions med/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ struct numeric_value : IE<IE_VALUE>
using value_type = typename traits::value_type;
using base_t = numeric_value;

value_type get() const { return get_encoded(); }
auto set(value_type v) { return set_encoded(v); }
value_type get() const noexcept { return get_encoded(); }
auto set(value_type v) noexcept { return set_encoded(v); }

//NOTE: do not override!
static constexpr bool is_defined = false;
value_type get_encoded() const { return m_value; }
void set_encoded(value_type v) { m_value = v; m_set = true; }
void clear() { m_set = false; }
bool is_set() const { return m_set; }
explicit operator bool() const { return is_set(); }
value_type get_encoded() const noexcept { return m_value; }
void set_encoded(value_type v) noexcept { m_value = v; m_set = true; }
void clear() noexcept { m_set = false; }
bool is_set() const noexcept { return m_set; }
explicit operator bool() const noexcept { return is_set(); }
template <class... ARGS>
void copy(base_t const& from, ARGS&&...) { m_value = from.m_value; m_set = from.m_set; }
void copy(base_t const& from, ARGS&&...)noexcept{ m_value = from.m_value; m_set = from.m_set; }

#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ < 9)
#pragma GCC diagnostic push
Expand Down
Loading

0 comments on commit e9bcbf7

Please sign in to comment.