Program Listing for File struct_receiver.h

Program Listing for File struct_receiver.h#

Return to documentation for file (src/generated/custom/struct_receiver.h)

#pragma once
#ifndef HAL_RP2XXX_CUSTOM_STRUCT_RECEIVER_H
#define HAL_RP2XXX_CUSTOM_STRUCT_RECEIVER_H

#include <functional>

namespace hal_rp2xxx
{

template <ifgen_struct T>
using struct_handler = std::function<void(const T &)>;

using non_struct_handler =
    std::function<std::size_t(const std::byte *, std::size_t)>;

struct StructReceiver
{
    non_struct_handler non_struct = nullptr;

    std::size_t dropped_messages = 0;
    std::size_t dropped_bytes = 0;

    inline void drop_message(std::size_t &len)
    {
        if (len)
        {
            dropped_messages++;
            dropped_bytes += len;
            len = 0;
        }
    }

    template <std::endian endianness = default_endian>
    void handle_message(const std::byte *data, std::size_t len)
    {
        if (len < sizeof(struct_id_t))
        {
            drop_message(len);
            return;
        }

        /* Read identifier and advance buffer. */
        struct_id_t ident = handle_endian<endianness>(
            *reinterpret_cast<const struct_id_t *>(data));
        data += sizeof(struct_id_t);
        len -= sizeof(struct_id_t);

        switch (ident)
        {
        case 0:
            if (non_struct)
            {
                auto result = non_struct(data, len);
                if (result)
                {
                    data += result;
                    len -= result;
                }
                else
                {
                    drop_message(len);
                }
            }
            else
            {
                drop_message(len);
            }
            break;
        default:
            /* Couldn't match any identifier. */
            drop_message(len);
        }

        /* Continue if more bytes remain. */
        if (len)
        {
            handle_message<endianness>(data, len);
        }
    }
};

}; // namespace hal_rp2xxx

#endif