15#if PC_ENABLE_CONFIG_IO
28bool field_type(
const pc_cfg_field *fields,
size_t n,
const char *key, pc_cfg_type *out)
30 for (
size_t i = 0; i < n; i++)
32 if (fields[i].key && strcmp(fields[i].key, key) == 0)
34 *out = fields[i].type;
42bool append_kv(
char *out,
size_t cap,
size_t *pos,
const char *key,
const char *val)
44 size_t kn = strnlen(key, cap + 1), vn = strnlen(val, cap + 1);
45 size_t need = kn + 1 + vn + 1;
46 if (*pos + need >= cap)
50 memcpy(out + *pos, key, kn);
53 memcpy(out + *pos, val, vn);
61int pc_config_export(
const char *ns,
const pc_cfg_field *fields,
size_t n,
char *out,
size_t cap)
68 if (!fields || !pc_config_begin(ns))
74 for (
size_t i = 0; i < n; i++)
77 if (fields[i].type == pc_cfg_type::PC_CFG_U32)
79 pc_sb sb_val = {val,
sizeof(val), 0,
true};
80 pc_sb_u32(&sb_val, (uint32_t)((
unsigned)pc_config_get_u32(fields[i].key, 0)));
88 pc_config_get_str(fields[i].key, val,
sizeof(val),
"");
91 if (!append_kv(out, cap, &pos, fields[i].key, val))
102static bool config_apply_field(
const pc_cfg_field *fields,
size_t n,
const char *key,
const char *val)
105 if (!field_type(fields, n, key, &t))
109 if (t == pc_cfg_type::PC_CFG_U32)
111 return pc_config_set_u32(key, (uint32_t)
pc_strtoul(val,
nullptr));
113 if (t == pc_cfg_type::PC_CFG_STR)
115 return pc_config_set_str(key, val);
120int pc_config_import(
const char *ns,
const pc_cfg_field *fields,
size_t n,
const char *text,
size_t len)
122 if (!text || !fields || !pc_config_begin(ns))
133 while (eol < len && text[eol] !=
'\n')
140 while (eq < eol && text[eq] !=
'=')
150 size_t klen = eq - i;
151 size_t vlen = eol - (eq + 1);
152 if (klen > 0 && klen < PC_KEY_MAX && vlen < PC_VAL_MAX)
154 char key[PC_KEY_MAX];
155 char val[PC_VAL_MAX];
156 memcpy(key, text + i, klen);
158 memcpy(val, text + eq + 1, vlen);
160 if (config_apply_field(fields, n, key, val))
Schema-driven config export / restore (PC_ENABLE_CONFIG_IO).
Typed NVS configuration store (PC_ENABLE_CONFIG_STORE).
Tiny no-stdlib base-10 number parsers (strtol/strtoul/strtof replacements).
unsigned long pc_strtoul(const char *s, const char **end)
Parse a base-10 unsigned long; sets end past the digits (or to s).
Bounded no-heap string builder that fails closed on overflow (one shared copy).
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
void pc_sb_u32(pc_sb *b, uint32_t v)
Append v as decimal (no leading zeros; "0" for zero).
Bump-append target; ok latches false once an append would overflow cap.