moddef-c
Loading...
Searching...
No Matches
codec.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2
3/* Codec (spec §8–§15): pure functions over md_point_desc_t, kept in
4 * behavioral lockstep with the Go/TS/Rust/Python implementations (shared
5 * vector suite in tests/). Allocation-free; strings and bytes decode into
6 * caller buffers.
7 *
8 * The decimal path (§10) computes in double — the same value surface as
9 * every other implementation. md_decode_raw is the exact escape hatch for
10 * billing counters; FPU-less targets can stay on the raw/integer path. */
11#ifndef MODDEF_CODEC_H
12#define MODDEF_CODEC_H
13
14#include <stddef.h>
15
16#include "moddef/desc.h"
17#include "moddef/err.h"
18
19typedef enum md_val_kind {
20 MD_VAL_F64 = 0, /* scaled DECIMAL / FLOAT */
24 MD_VAL_FLAGS, /* raw mask; names via md_flag_iter / md_flags_has */
25 MD_VAL_FIELDS, /* raw window; extract via md_field_value */
26 MD_VAL_DATETIME, /* epoch seconds or millis per the point (§8.5) */
27 MD_VAL_UNAVAILABLE /* §8.4 sentinel; meaning in na_meaning */
29
30typedef struct md_value {
31 uint8_t kind; /* md_val_kind_t */
32 union {
33 double f64;
34 uint64_t u64;
35 int64_t i64;
36 bool b;
37 uint64_t bits; /* MD_VAL_FLAGS / MD_VAL_FIELDS */
38 int64_t epoch; /* MD_VAL_DATETIME */
39 } v;
40 md_str_t na_meaning; /* set for MD_VAL_UNAVAILABLE */
42
43static inline md_value_t md_value_f64(double f)
44{
45 md_value_t v = {MD_VAL_F64, {0}, {0, 0}};
46 v.v.f64 = f;
47 return v;
48}
49
50static inline md_value_t md_value_i64(int64_t i)
51{
52 md_value_t v = {MD_VAL_I64, {0}, {0, 0}};
53 v.v.i64 = i;
54 return v;
55}
56
57static inline md_value_t md_value_bool(bool b)
58{
59 md_value_t v = {MD_VAL_BOOL, {0}, {0, 0}};
60 v.v.b = b;
61 return v;
62}
63
64/* Cross-point context: integer values of scale_ref / selector_ref targets
65 * (spec §10.4/§10.5). A small array — lookups are O(n) over 1-2 refs. */
66typedef struct md_ctx_entry {
68 int64_t val;
70
71typedef struct md_ctx {
73 uint8_t n;
75
76#define MD_CTX_EMPTY ((md_ctx_t){0, 0})
77
78/* Decode a point's registers into a typed value. Strings/bytes are not
79 * handled here — use md_decode_string / md_decode_bytes. */
80md_err_t md_decode(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs,
81 const md_ctx_t *ctx, md_value_t *out);
82
83/* Pre-scale integer view (exactness escape hatch). */
84md_err_t md_decode_raw(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs,
85 uint64_t *raw, uint8_t *bits);
86
87/* Decode a string point (§15) into buf; NUL-terminated, *out_len excludes
88 * the NUL. cap must cover the trimmed content + NUL. */
89md_err_t md_decode_string(const md_point_desc_t *d, const uint16_t *regs,
90 uint16_t n_regs, char *buf, size_t cap, size_t *out_len);
91
92/* Decode a BYTES_RAW point into buf (*out_len = words * 2). */
93md_err_t md_decode_bytes(const md_point_desc_t *d, const uint16_t *regs,
94 uint16_t n_regs, uint8_t *buf, size_t cap, size_t *out_len);
95
96/* Serialize a typed value into out_regs (must be exactly md_point_words). */
97md_err_t md_encode(const md_point_desc_t *d, const md_value_t *v, const md_ctx_t *ctx,
98 uint16_t *out_regs, uint16_t n_regs);
99
100md_err_t md_encode_string(const md_point_desc_t *d, md_str_t s, uint16_t *out_regs,
101 uint16_t n_regs);
102
103/* §11.4 write constraint validation (engineering units); returns
104 * MD_ERR_CONSTRAINT_* on violation. */
106
107/* --- flag / field helpers --------------------------------------------------- */
108
109/* Is the named flag set in a decoded MD_VAL_FLAGS mask? */
110bool md_flags_has(const md_point_desc_t *d, uint64_t mask, md_str_t name);
111
112/* Extract one named sub-field from a decoded MD_VAL_FIELDS window (§13). */
113md_err_t md_field_value(const md_point_desc_t *d, uint64_t window, md_str_t field_id,
114 uint64_t *out);
115
116#endif /* MODDEF_CODEC_H */
md_err_t md_decode_bytes(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs, uint8_t *buf, size_t cap, size_t *out_len)
struct md_ctx_entry md_ctx_entry_t
md_err_t md_decode_raw(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs, uint64_t *raw, uint8_t *bits)
md_err_t md_decode(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs, const md_ctx_t *ctx, md_value_t *out)
md_err_t md_field_value(const md_point_desc_t *d, uint64_t window, md_str_t field_id, uint64_t *out)
struct md_value md_value_t
md_val_kind
Definition codec.h:19
@ MD_VAL_I64
Definition codec.h:22
@ MD_VAL_U64
Definition codec.h:21
@ MD_VAL_UNAVAILABLE
Definition codec.h:27
@ MD_VAL_F64
Definition codec.h:20
@ MD_VAL_FIELDS
Definition codec.h:25
@ MD_VAL_DATETIME
Definition codec.h:26
@ MD_VAL_FLAGS
Definition codec.h:24
@ MD_VAL_BOOL
Definition codec.h:23
md_err_t md_encode_string(const md_point_desc_t *d, md_str_t s, uint16_t *out_regs, uint16_t n_regs)
enum md_val_kind md_val_kind_t
struct md_ctx md_ctx_t
md_err_t md_validate_write(const md_point_desc_t *d, const md_value_t *v)
md_err_t md_decode_string(const md_point_desc_t *d, const uint16_t *regs, uint16_t n_regs, char *buf, size_t cap, size_t *out_len)
bool md_flags_has(const md_point_desc_t *d, uint64_t mask, md_str_t name)
md_err_t md_encode(const md_point_desc_t *d, const md_value_t *v, const md_ctx_t *ctx, uint16_t *out_regs, uint16_t n_regs)
enum md_err md_err_t
Definition codec.h:66
md_str_t id
Definition codec.h:67
int64_t val
Definition codec.h:68
Definition codec.h:71
const md_ctx_entry_t * refs
Definition codec.h:72
uint8_t n
Definition codec.h:73
Definition desc.h:79
Definition str.h:13
Definition codec.h:30
int64_t i64
Definition codec.h:35
md_str_t na_meaning
Definition codec.h:40
bool b
Definition codec.h:36
union md_value::@0 v
double f64
Definition codec.h:33
uint64_t u64
Definition codec.h:34
uint64_t bits
Definition codec.h:37
uint8_t kind
Definition codec.h:31
int64_t epoch
Definition codec.h:38