mesytec-mnode/src/internal/mana_lib.hpp

108 lines
3.4 KiB
C++
Raw Normal View History

2024-12-25 03:19:29 +01:00
#ifndef AAB5E4D2_A05B_4F2F_B76A_406A5A569D55
#define AAB5E4D2_A05B_4F2F_B76A_406A5A569D55
#include <cassert>
#include <mesytec-mnode/mnode_cpp_types.h>
2024-12-25 05:47:38 +01:00
#include <mesytec-mvlc/cpp_compat.h>
#include <mesytec-mvlc/util/data_filter.h>
#include <nlohmann/json.hpp>
#include "mana_api.h"
2024-12-25 03:19:29 +01:00
namespace mesytec::mnode::mana
{
2024-12-25 05:47:38 +01:00
namespace detail
{
inline void set(mana_offset_ptr_t &ptr, void *p)
2024-12-25 03:19:29 +01:00
{
assert(p != reinterpret_cast<u8 *>(&ptr) + 1);
if (p)
{
ptr.offset = reinterpret_cast<u8 *>(p) - reinterpret_cast<u8 *>(&ptr);
2024-12-25 05:47:38 +01:00
// spdlog::info("detail::set: &ptr={}, p={}, offset={}", fmt::ptr(&ptr), fmt::ptr(p),
// ptr.offset);
2024-12-25 03:19:29 +01:00
}
else
{
ptr.offset = 1;
}
}
2024-12-25 05:47:38 +01:00
} // namespace detail
inline bool is_null(const mana_offset_ptr_t &ptr) { return ptr.offset == 1; }
2024-12-25 03:19:29 +01:00
inline void *get(mana_offset_ptr_t &ptr)
{
2024-12-25 05:47:38 +01:00
return is_null(ptr) ? nullptr : reinterpret_cast<u8 *>(&ptr) + ptr.offset;
2024-12-25 03:19:29 +01:00
}
template <typename T> T *get(mana_offset_ptr_t &ptr); // to catch unsupported types
template <typename T> T *get_(mana_offset_ptr_t &ptr, mana_data_type_t expected)
{
if (ptr.data_type != expected)
return nullptr;
return reinterpret_cast<T *>(get(ptr));
}
template <> u32 *get(mana_offset_ptr_t &ptr) { return get_<u32>(ptr, mana_uint32); }
template <> u64 *get(mana_offset_ptr_t &ptr) { return get_<u64>(ptr, mana_uint64); }
template <> s8 *get(mana_offset_ptr_t &ptr) { return get_<s8>(ptr, mana_sint8); }
template <> char *get(mana_offset_ptr_t &ptr) { return get_<char>(ptr, mana_sint8); }
template <> float *get(mana_offset_ptr_t &ptr) { return get_<float>(ptr, mana_float); }
template <> double *get(mana_offset_ptr_t &ptr) { return get_<double>(ptr, mana_double); }
inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
{
ptr.data_type = data_type;
2024-12-25 05:47:38 +01:00
detail::set(ptr, p);
2024-12-25 03:19:29 +01:00
}
inline void set(mana_offset_ptr_t &ptr, std::nullptr_t) { set(ptr, mana_uint32, nullptr); }
inline void set(mana_offset_ptr_t &ptr, u32 *p) { set(ptr, mana_uint32, p); }
inline void set(mana_offset_ptr_t &ptr, u64 *p) { set(ptr, mana_uint64, p); }
2024-12-25 05:47:38 +01:00
inline void set(mana_offset_ptr_t &ptr, s8 *p) { set(ptr, mana_sint8, p); }
2024-12-25 03:19:29 +01:00
inline void set(mana_offset_ptr_t &ptr, char *p) { set(ptr, mana_sint8, p); }
inline void set(mana_offset_ptr_t &ptr, float *p) { set(ptr, mana_float, p); }
inline void set(mana_offset_ptr_t &ptr, double *p) { set(ptr, mana_double, p); }
2024-12-25 05:47:38 +01:00
template <typename T> mvlc::util::span<T> get_span(mana_offset_array_t &array)
{
auto ptr = reinterpret_cast<T *>(get(array.ptr));
auto size = array.size_bytes / sizeof(T);
return { ptr, size };
}
inline nlohmann::json make_array_descriptor(const std::string &name, mana_data_type_t data_type,
size_t size, size_t bits = 0)
{
nlohmann::json j;
j["name"] = name;
j["data_type"] = data_type;
j["size"] = size;
j["bits"] = bits;
return j;
2024-12-25 03:19:29 +01:00
}
2024-12-25 05:47:38 +01:00
inline nlohmann::json make_array_descriptor(const std::string &name, const std::string &bit_filter)
{
auto f = mvlc::util::make_filter_with_caches(bit_filter);
size_t size = 1;
if (auto c = mvlc::util::get_cache_entry(f, 'A'))
size = 1u << c->extractBits;
size_t bits = 0;
if (auto c = mvlc::util::get_cache_entry(f, 'D'))
bits = c->extractBits;
return make_array_descriptor(name, mana_float, size, bits);
}
} // namespace mesytec::mnode::mana
2024-12-25 03:19:29 +01:00
#endif /* AAB5E4D2_A05B_4F2F_B76A_406A5A569D55 */