bej: add deferred binding substitution support

Add DSP0218 Table 42 deferred binding substitution to the BEJ encoder
and decoder so resource-specific values (URIs, instance ids, action
targets, containing-resource links) travel as placeholders and bind
from a caller-supplied map.

Bindings are keyed by the placeholder token -- the text after the '%'
marker, with no leading '%' -- and map to the substitution value:

'''
using BejDeferredBindingMap = std::unordered_map<std::string, std::string>;
'''

A single flat map holds id-bearing markers (%L<id>, %I<id>,
%T<id>.<action>) and id-less markers (%C, %S) alike, with no
per-resource struct and no empty unused fields. Keys are built with the
bejBinding helpers (resourceLink, instanceId, action, chassis, system)
so the caller and libbej share one token grammar.

Supported markers (a subset of Table 42): %L, %I, %T, %C, %S, and the
%% escape. The remaining markers (multi-symbol %PD/%PF/%PI,
%P<id>.PAGE<offset>, %M, %U, %B, and the %. terminator) are not handled
yet and pass through unchanged. The decode side models markers as a
data table (marker, parameter arity, invalid form), so adding one is a
table row rather than a new branch.

Encoder: encode() takes an optional BejDeferredBindingMap, builds a
value->placeholder reverse map once, rewrites matching bejString leaves
to placeholders for the encode, then restores the caller's tree (value
pointers and format flags) so encode() has no side effect on the input.

Decoder: decode() takes the same map and runs in one of two modes. An
empty map (the default) disables resolution: deferred binding strings
and bejResourceLink ids are left raw (e.g. %L<id>), preserving the
input. A non-empty map enables resolution: a recognized token is
substituted, an unrecognized id becomes its Table 42 invalid form
(%L -> /invalid.PDR<id>, %I -> invalid, %T -> /invalid.<id>.<n>), and an
id-less marker with no binding stays raw. Substitution is gated on the
per-string SFLV deferred-binding bit, so ordinary data is never touched.
Placeholder parsing uses std::from_chars so malformed input cannot throw
across the C decoder frames. Resource ids are 32-bit; a numeric
bejResourceLink id beyond that range is treated as unrecognized rather
than truncated.

The token-key map type and marker constants live in
bej_deferred_binding.hpp; the bejBinding key builders live in
bej_deferred_binding_format.hpp, keeping <format> out of the core type
header. Both encode and decode share these so the directions stay in
sync.

Change-Id: Id7aa215fc1dc701d60418d9ee92cd73f5629df87
Signed-off-by: Ryan CJ Huang <ryan_huang@jabil.com>
16 files changed
tree: daf0b6b40a6425975a2fb34904b66e62e9f8726a
  1. include/
  2. src/
  3. subprojects/
  4. test/
  5. .clang-format
  6. .clang-tidy
  7. .gitignore
  8. LICENSE
  9. MAINTAINERS
  10. meson.build
  11. meson.options
  12. OWNERS
  13. README.md
README.md

libbej

This library can be used to decode RDE bej data. More details on how to use the library will be added in the future.