Lely core libraries  2.3.4
val.c
Go to the documentation of this file.
1 
24 #include "co.h"
25 #include <lely/co/sdo.h>
26 #include <lely/co/val.h>
27 #include <lely/libc/string.h>
28 // This include is required for <inttypes.h> when using Newlib.
29 #include <lely/libc/sys/types.h>
30 #include <lely/util/cmp.h>
31 #include <lely/util/diag.h>
32 #include <lely/util/endian.h>
33 #if !LELY_NO_STDIO
34 #include <lely/util/frbuf.h>
35 #include <lely/util/fwbuf.h>
36 #include <lely/util/lex.h>
37 #include <lely/util/print.h>
38 #endif
39 #include <lely/util/ustring.h>
40 
41 #include <assert.h>
42 #if !LELY_NO_STDIO
43 #include <inttypes.h>
44 #endif
45 #if !LELY_NO_MALLOC
46 #include <stdlib.h>
47 #endif
48 
49 #define CO_ARRAY_HDR_OFFSET \
50  ALIGN(sizeof(struct co_array_hdr), _Alignof(union co_val))
51 
52 static inline struct co_array_hdr *co_array_get_hdr(const void *val);
53 
54 static int co_array_alloc(void *val, size_t size);
55 static void co_array_free(void *val);
56 static void co_array_init(void *val, size_t size);
57 static void co_array_fini(void *val);
58 
59 static size_t co_array_sizeof(const void *val);
60 
61 int
62 co_val_init(co_unsigned16_t type, void *val)
63 {
64  union co_val *u = val;
65  assert(u);
66 
67 #if LELY_NO_MALLOC
68  if (co_type_is_array(type)) {
69  co_array_init(val, 0);
70  return 0;
71  }
72 #endif
73 
74  switch (type) {
75 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
76  case CO_DEFTYPE_##a: \
77  u->c = (co_##b##_t)CO_##a##_INIT; \
78  return 0;
79 #include <lely/co/def/basic.def>
80 #include <lely/co/def/time.def>
81 #if !LELY_NO_MALLOC
82 #include <lely/co/def/array.def>
83 #endif // !LELY_NO_MALLOC
84 #undef LELY_CO_DEFINE_TYPE
85  default: set_errnum(ERRNUM_INVAL); return -1;
86  }
87 }
88 
89 int
90 co_val_init_min(co_unsigned16_t type, void *val)
91 {
92  union co_val *u = val;
93  assert(u);
94 
95 #if LELY_NO_MALLOC
96  if (co_type_is_array(type)) {
97  co_array_init(val, 0);
98  return 0;
99  }
100 #endif
101 
102  switch (type) {
103 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
104  case CO_DEFTYPE_##a: \
105  u->c = (co_##b##_t)CO_##a##_MIN; \
106  return 0;
107 #include <lely/co/def/basic.def>
108 #include <lely/co/def/time.def>
109 #if !LELY_NO_MALLOC
110 #include <lely/co/def/array.def>
111 #endif // !LELY_NO_MALLOC
112 #undef LELY_CO_DEFINE_TYPE
113  default: set_errnum(ERRNUM_INVAL); return -1;
114  }
115 }
116 
117 int
118 co_val_init_max(co_unsigned16_t type, void *val)
119 {
120  union co_val *u = val;
121  assert(u);
122 
123 #if LELY_NO_MALLOC
124  if (co_type_is_array(type)) {
125  co_array_init(val, 0);
126  return 0;
127  }
128 #endif
129 
130  switch (type) {
131 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
132  case CO_DEFTYPE_##a: \
133  u->c = (co_##b##_t)CO_##a##_MAX; \
134  return 0;
135 #include <lely/co/def/basic.def>
136 #include <lely/co/def/time.def>
137 #if !LELY_NO_MALLOC
138 #include <lely/co/def/array.def>
139 #endif // !LELY_NO_MALLOC
140 #undef LELY_CO_DEFINE_TYPE
141  default: set_errnum(ERRNUM_INVAL); return -1;
142  }
143 }
144 
145 int
146 co_val_init_vs(char **val, const char *vs)
147 {
148  if (vs)
149  return co_val_init_vs_n(val, vs, strlen(vs));
150 
151  co_array_fini(val);
152 
153  return 0;
154 }
155 
156 int
157 co_val_init_vs_n(char **val, const char *vs, size_t n)
158 {
159  assert(val);
160 
161  if (n) {
162  if (co_array_alloc(val, n + 1) == -1)
163  return -1;
164  assert(*val);
165  co_array_init(val, n);
166  if (vs)
167  // Using strncpy() here might cause a compiler warning
168  // because we omit the terminating nul byte, which is
169  // already set by co_array_init().
170  memcpy(*val, vs, n);
171  } else {
172  co_array_fini(val);
173  }
174 
175  return 0;
176 }
177 
178 int
179 co_val_init_os(uint_least8_t **val, const uint_least8_t *os, size_t n)
180 {
181  assert(val);
182 
183  if (n) {
184  if (co_array_alloc(val, n + 1) == -1)
185  return -1;
186  assert(*val);
187  co_array_init(val, n);
188  if (os)
189  memcpy(*val, os, n);
190  } else {
191  co_array_fini(val);
192  }
193 
194  return 0;
195 }
196 
197 int
198 co_val_init_us(char16_t **val, const char16_t *us)
199 {
200  assert(val);
201 
202  if (us)
203  return co_val_init_us_n(val, us, str16len(us));
204 
205  co_array_fini(val);
206 
207  return 0;
208 }
209 
210 int
211 co_val_init_us_n(char16_t **val, const char16_t *us, size_t n)
212 {
213  assert(val);
214 
215  if (n) {
216  if (co_array_alloc(val, 2 * (n + 1)) == -1)
217  return -1;
218  assert(*val);
219  co_array_init(val, 2 * n);
220  if (us)
221  str16ncpy(*val, us, n);
222  } else {
223  co_array_fini(val);
224  }
225 
226  return 0;
227 }
228 
229 int
230 co_val_init_dom(void **val, const void *dom, size_t n)
231 {
232  assert(val);
233 
234  if (n) {
235  if (co_array_alloc(val, n) == -1)
236  return -1;
237  assert(*val);
238  co_array_init(val, n);
239  if (dom)
240  memcpy(*val, dom, n);
241  } else {
242  co_array_fini(val);
243  }
244 
245  return 0;
246 }
247 
248 void
249 co_val_fini(co_unsigned16_t type, void *val)
250 {
251  assert(val);
252 
253  if (co_type_is_array(type)) {
254  co_array_free(val);
255  co_array_fini(val);
256  }
257 }
258 
259 const void *
260 co_val_addressof(co_unsigned16_t type, const void *val)
261 {
262  if (!val)
263  return NULL;
264 
265  return co_type_is_array(type) ? *(const void **)val : val;
266 }
267 
268 size_t
269 co_val_sizeof(co_unsigned16_t type, const void *val)
270 {
271  if (!val)
272  return 0;
273 
274  // clang-format off
275  return co_type_is_array(type)
276  ? co_array_sizeof(val)
277  : co_type_sizeof(type);
278  // clang-format on
279 }
280 
281 size_t
282 co_val_make(co_unsigned16_t type, void *val, const void *ptr, size_t n)
283 {
284  assert(val);
285 
286  switch (type) {
288  n = ptr ? strlen(ptr) : 0;
289  if (co_val_init_vs(val, ptr) == -1)
290  return 0;
291  break;
293  if (!ptr)
294  n = 0;
295  if (co_val_init_os(val, ptr, n) == -1)
296  return 0;
297  break;
299  n = ptr ? str16len(ptr) : 0;
300  if (co_val_init_us(val, ptr) == -1)
301  return 0;
302  break;
303  case CO_DEFTYPE_DOMAIN:
304  if (!ptr)
305  n = 0;
306  if (co_val_init_dom(val, ptr, n) == -1)
307  return 0;
308  break;
309  default:
310  if (!ptr || co_type_sizeof(type) != n)
311  return 0;
312  memcpy(val, ptr, n);
313  }
314  return n;
315 }
316 
317 size_t
318 co_val_copy(co_unsigned16_t type, void *dst, const void *src)
319 {
320  assert(dst);
321  assert(src);
322 
323  size_t n;
324  if (co_type_is_array(type)) {
325  const void *ptr = co_val_addressof(type, src);
326  n = co_val_sizeof(type, src);
327  switch (type) { // LCOV_EXCL_BR_LINE
329  if (co_val_init_vs(dst, ptr) == -1)
330  return 0;
331  break;
333  if (co_val_init_os(dst, ptr, n) == -1)
334  return 0;
335  break;
337  if (co_val_init_us(dst, ptr) == -1)
338  return 0;
339  break;
340  case CO_DEFTYPE_DOMAIN:
341  if (co_val_init_dom(dst, ptr, n) == -1)
342  return 0;
343  break;
344  default: return 0; // We can never get here. [LCOV_EXCL_LINE]
345  }
346  } else {
347  n = co_type_sizeof(type);
348  memcpy(dst, src, n);
349  }
350  return n;
351 }
352 
353 size_t
354 co_val_move(co_unsigned16_t type, void *dst, void *src)
355 {
356  assert(dst);
357  assert(src);
358 
359  size_t n = co_type_sizeof(type);
360  memcpy(dst, src, n);
361 
362  if (co_type_is_array(type))
363  *(char **)src = NULL;
364 
365  return n;
366 }
367 
368 int
369 co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
370 {
371  if (v1 == v2)
372  return 0;
373 
374  if (!v1)
375  return -1;
376  if (!v2)
377  return 1;
378 
379  int cmp = 0;
380  if (co_type_is_array(type)) {
381  const void *p1 = co_val_addressof(type, v1);
382  const void *p2 = co_val_addressof(type, v2);
383 
384  if (p1 == p2)
385  return 0;
386 
387  if (!p1)
388  return -1;
389  if (!p2)
390  return 1;
391 
392  size_t n1 = co_val_sizeof(type, v1);
393  size_t n2 = co_val_sizeof(type, v2);
394  switch (type) { // LCOV_EXCL_BR_LINE
396  cmp = strncmp(p1, p2, MIN(n1, n2));
397  break;
399  cmp = memcmp(p1, p2, MIN(n1, n2));
400  break;
402  cmp = str16ncmp(p1, p2, MIN(n1, n2) / 2);
403  break;
404  case CO_DEFTYPE_DOMAIN:
405  cmp = memcmp(p1, p2, MIN(n1, n2));
406  break;
407  default: return 0; // We can never get here. [LCOV_EXCL_LINE]
408  }
409  if (!cmp)
410  cmp = (n1 > n2) - (n1 < n2);
411  return cmp;
412  } else {
413  const union co_val *u1 = v1;
414  const union co_val *u2 = v2;
415  switch (type) {
416  case CO_DEFTYPE_BOOLEAN: return bool_cmp(v1, v2);
417  case CO_DEFTYPE_INTEGER8: return int8_cmp(v1, v2);
418  case CO_DEFTYPE_INTEGER16: return int16_cmp(v1, v2);
419  case CO_DEFTYPE_INTEGER32: return int32_cmp(v1, v2);
420  case CO_DEFTYPE_UNSIGNED8: return uint8_cmp(v1, v2);
421  case CO_DEFTYPE_UNSIGNED16: return uint16_cmp(v1, v2);
422  case CO_DEFTYPE_UNSIGNED32: return uint32_cmp(v1, v2);
423  case CO_DEFTYPE_REAL32: return flt_cmp(v1, v2);
425  cmp = uint16_cmp(&u1->t.days, &u2->t.days);
426  if (!cmp)
427  cmp = uint32_cmp(&u1->t.ms, &u2->t.ms);
428  return cmp;
430  cmp = uint16_cmp(&u1->td.days, &u2->td.days);
431  if (!cmp)
432  cmp = uint32_cmp(&u1->td.ms, &u2->td.ms);
433  return cmp;
434  case CO_DEFTYPE_INTEGER24: return int32_cmp(v1, v2);
435  case CO_DEFTYPE_REAL64: return dbl_cmp(v1, v2);
436  case CO_DEFTYPE_INTEGER40: return int64_cmp(v1, v2);
437  case CO_DEFTYPE_INTEGER48: return int64_cmp(v1, v2);
438  case CO_DEFTYPE_INTEGER56: return int64_cmp(v1, v2);
439  case CO_DEFTYPE_INTEGER64: return int64_cmp(v1, v2);
440  case CO_DEFTYPE_UNSIGNED24: return uint32_cmp(v1, v2);
441  case CO_DEFTYPE_UNSIGNED40: return uint64_cmp(v1, v2);
442  case CO_DEFTYPE_UNSIGNED48: return uint64_cmp(v1, v2);
443  case CO_DEFTYPE_UNSIGNED56: return uint64_cmp(v1, v2);
444  case CO_DEFTYPE_UNSIGNED64: return uint64_cmp(v1, v2);
445  default: return 0;
446  }
447  }
448 }
449 
450 size_t
451 co_val_read(co_unsigned16_t type, void *val, const uint_least8_t *begin,
452  const uint_least8_t *end)
453 {
454  assert(begin || begin == end);
455  assert(end >= begin);
456 
457  size_t n = end - begin;
458 
459  if (co_type_is_array(type)) {
460  if (val) {
461  switch (type) { // LCOV_EXCL_BR_LINE
463  // clang-format off
464  if (co_val_init_vs_n(val, (const char *)begin,
465  n) == -1)
466  // clang-format on
467  return 0;
468  break;
470  if (co_val_init_os(val, begin, n) == -1)
471  return 0;
472  break;
474  if (co_val_init_us_n(val, NULL, n / 2) == -1)
475  return 0;
476  if (n) {
477  char16_t *us = *(char16_t **)val;
478  assert(us);
479  for (size_t i = 0; i + 1 < n; i += 2)
480  us[i / 2] = ldle_u16(begin + i);
481  }
482  break;
483  case CO_DEFTYPE_DOMAIN:
484  if (co_val_init_dom(val, begin, n) == -1)
485  return 0;
486  break;
487  // We can never get here
488  default: return 0; // LCOV_EXCL_LINE
489  }
490  }
491  return n;
492  } else {
493  union co_val *u = val;
494  switch (type) {
495  case CO_DEFTYPE_BOOLEAN:
496  if (n < 1)
497  return 0;
498  if (u)
499  u->b = (*begin != 0);
500  return 1;
501  case CO_DEFTYPE_INTEGER8:
502  if (n < 1)
503  return 0;
504  if (u)
505  u->i8 = *(const co_integer8_t *)begin;
506  return 1;
508  if (n < 2)
509  return 0;
510  if (u)
511  u->i16 = ldle_i16(begin);
512  return 2;
514  if (n < 4)
515  return 0;
516  if (u)
517  u->i32 = ldle_i32(begin);
518  return 4;
520  if (n < 1)
521  return 0;
522  if (u)
523  u->u8 = *(const co_unsigned8_t *)begin;
524  return 1;
526  if (n < 2)
527  return 0;
528  if (u)
529  u->u16 = ldle_u16(begin);
530  return 2;
532  if (n < 4)
533  return 0;
534  if (u)
535  u->u32 = ldle_u32(begin);
536  return 4;
537  case CO_DEFTYPE_REAL32:
538  if (n < 4)
539  return 0;
540  if (u)
541  u->r32 = ldle_flt32(begin);
542  return 4;
545  if (n < 6)
546  return 0;
547  if (u) {
548  u->t.ms = ldle_u32(begin)
549  & UINT32_C(0x0fffffff);
550  u->t.days = ldle_u16(begin + 4);
551  }
552  return 6;
554  if (n < 3)
555  return 0;
556  if (u) {
557  co_unsigned24_t u24 = 0;
558  for (size_t i = 0; i < 3; i++)
559  u24 |= (co_unsigned24_t)*begin++
560  << 8 * i;
561  u->i24 = u24 > CO_INTEGER24_MAX
562  ? -(CO_UNSIGNED24_MAX + 1 - u24)
563  : u24;
564  }
565  return 3;
566  case CO_DEFTYPE_REAL64:
567  if (n < 8)
568  return 0;
569  if (u)
570  u->r64 = ldle_flt64(begin);
571  return 8;
573  if (n < 5)
574  return 0;
575  if (u) {
576  co_unsigned40_t u40 = 0;
577  for (size_t i = 0; i < 5; i++)
578  u40 |= (co_unsigned40_t)*begin++
579  << 8 * i;
580  u->i40 = u40 > CO_INTEGER40_MAX
581  ? -(CO_UNSIGNED40_MAX + 1 - u40)
582  : u40;
583  }
584  return 5;
586  if (n < 6)
587  return 0;
588  if (u) {
589  co_unsigned48_t u48 = 0;
590  for (size_t i = 0; i < 6; i++)
591  u48 |= (co_unsigned48_t)*begin++
592  << 8 * i;
593  u->i48 = u48 > CO_INTEGER48_MAX
594  ? -(CO_UNSIGNED48_MAX + 1 - u48)
595  : u48;
596  }
597  return 6;
599  if (n < 7)
600  return 0;
601  if (u) {
602  co_unsigned56_t u56 = 0;
603  for (size_t i = 0; i < 7; i++)
604  u56 |= (co_unsigned56_t)*begin++
605  << 8 * i;
606  u->i56 = u56 > CO_INTEGER56_MAX
607  ? -(CO_UNSIGNED56_MAX + 1 - u56)
608  : u56;
609  }
610  return 7;
612  if (n < 8)
613  return 0;
614  if (u)
615  u->i64 = ldle_i64(begin);
616  return 8;
618  if (n < 3)
619  return 0;
620  if (u) {
621  u->u24 = 0;
622  for (size_t i = 0; i < 3; i++)
623  u->u24 |= (co_unsigned24_t)*begin++
624  << 8 * i;
625  }
626  return 3;
628  if (n < 5)
629  return 0;
630  if (u) {
631  u->u40 = 0;
632  for (size_t i = 0; i < 5; i++)
633  u->u40 |= (co_unsigned40_t)*begin++
634  << 8 * i;
635  }
636  return 5;
638  if (n < 6)
639  return 0;
640  if (u) {
641  u->u48 = 0;
642  for (size_t i = 0; i < 6; i++)
643  u->u48 |= (co_unsigned48_t)*begin++
644  << 8 * i;
645  }
646  return 6;
648  if (n < 7)
649  return 0;
650  if (u) {
651  u->u56 = 0;
652  for (size_t i = 0; i < 7; i++)
653  u->u56 |= (co_unsigned56_t)*begin++
654  << 8 * i;
655  }
656  return 7;
658  if (n < 8)
659  return 0;
660  if (u)
661  u->u64 = ldle_u64(begin);
662  return 8;
663  default: set_errnum(ERRNUM_INVAL); return 0;
664  }
665  }
666 }
667 
668 #if !LELY_NO_STDIO
669 
670 size_t
671 co_val_read_file(co_unsigned16_t type, void *val, const char *filename)
672 {
673  frbuf_t *buf = frbuf_create(filename);
674  if (buf) {
675  int errc = get_errc();
676  set_errc(0);
677  size_t size = co_val_read_frbuf(type, val, buf);
678  if (!size && get_errc()) {
679  errc = get_errc();
680  diag(DIAG_ERROR, get_errc(), "%s", filename);
681  }
682  frbuf_destroy(buf);
683  set_errc(errc);
684  return size;
685  } else {
686  diag(DIAG_ERROR, get_errc(), "%s", filename);
687  return 0;
688  }
689 }
690 
691 size_t
692 co_val_read_frbuf(co_unsigned16_t type, void *val, frbuf_t *buf)
693 {
694  intmax_t size = frbuf_get_size(buf);
695  if (size == -1)
696  return 0;
697  assert(size >= 0);
698 
699  intmax_t pos = frbuf_get_pos(buf);
700  if (pos == -1)
701  return 0;
702  assert(pos >= 0);
703 
704  if (pos > size)
705  pos = size;
706  size -= pos;
707 
708  if (co_type_is_array(type)) {
709  size_t n = (size_t)size;
710  if (val) {
711  switch (type) {
713  if (co_val_init_vs_n(val, NULL, n) == -1)
714  return 0;
715  char *vs = *(char **)val;
716  if (frbuf_read(buf, vs, n) != (ssize_t)n)
717  return 0;
718  break;
720  if (co_val_init_os(val, NULL, n) == -1)
721  return 0;
722  uint_least8_t *os = *(uint_least8_t **)val;
723  if (frbuf_read(buf, os, n) != (ssize_t)n)
724  return 0;
725  break;
727  if (co_val_init_us_n(val, NULL, n / 2) == -1)
728  return 0;
729  char16_t *us = *(char16_t **)val;
730  if (frbuf_read(buf, us, n) != (ssize_t)n)
731  return 0;
732  // Update the byte order in-place.
733  const uint_least8_t *begin =
734  (const uint_least8_t *)us;
735  assert(us);
736  for (size_t i = 0; i + 1 < n; i += 2)
737  us[i / 2] = ldle_u16(begin + i);
738  break;
739  case CO_DEFTYPE_DOMAIN:
740  if (co_val_init_dom(val, NULL, n) == -1)
741  return 0;
742  void *dom = *(void **)val;
743  if (frbuf_read(buf, dom, n) != (ssize_t)n)
744  return 0;
745  break;
746  // We can never get here
747  default: return 0;
748  }
749  }
750  return n;
751  } else {
752  size_t n = co_type_sizeof(type);
753  n = MIN(n, (size_t)size);
754  union co_val tmp;
755  assert(n <= sizeof(tmp));
756  if (frbuf_read(buf, &tmp, n) != (ssize_t)n)
757  return 0;
758  const uint_least8_t *begin = (const uint_least8_t *)&tmp;
759  const uint_least8_t *end = begin + n;
760  return co_val_read(type, val, begin, end);
761  }
762 }
763 
764 #endif // !LELY_NO_STDIO
765 
766 co_unsigned32_t
767 co_val_read_sdo(co_unsigned16_t type, void *val, const void *ptr, size_t n)
768 {
769  int errc = get_errc();
770  co_unsigned32_t ac = 0;
771 
772  const uint_least8_t *begin = ptr;
773  const uint_least8_t *end = begin ? begin + n : NULL;
774  if (n && !co_val_read(type, val, begin, end)) {
775 #if LELY_NO_ERRNO
776  ac = CO_SDO_AC_ERROR;
777 #else
778  // clang-format off
779  ac = get_errnum() == ERRNUM_NOMEM
781  : CO_SDO_AC_ERROR;
782  // clang-format on
783 #endif
784  set_errc(errc);
785  }
786 
787  return ac;
788 }
789 
790 size_t
791 co_val_write(co_unsigned16_t type, const void *val, uint_least8_t *begin,
792  uint_least8_t *end)
793 {
794  assert(val);
795 
796  if (co_type_is_array(type)) {
797  const void *ptr = co_val_addressof(type, val);
798  size_t n = co_val_sizeof(type, val);
799  if (!ptr || !n)
800  return 0;
801  if (begin && (!end || end - begin >= (ptrdiff_t)n)) {
802  switch (type) { // LCOV_EXCL_BR_LINE
805  case CO_DEFTYPE_DOMAIN: memcpy(begin, ptr, n); break;
807  const char16_t *us = ptr;
808  for (size_t i = 0; i + 1 < n; i += 2)
809  stle_u16(begin + i, us[i / 2]);
810  break;
811  }
812  // We can never get here.
813  default: return 0; // LCOV_EXCL_LINE
814  }
815  }
816  return n;
817  } else {
818  const union co_val *u = val;
819  switch (type) {
820  case CO_DEFTYPE_BOOLEAN:
821  if (begin && (!end || end - begin >= 1)) {
822  if (u->b != 0)
823  *(co_boolean_t *)begin = 1;
824  else
825  *(co_boolean_t *)begin = 0;
826  }
827  return 1;
828  case CO_DEFTYPE_INTEGER8:
829  if (begin && (!end || end - begin >= 1))
830  *(co_integer8_t *)begin = u->i8;
831  return 1;
833  if (begin && (!end || end - begin >= 2))
834  stle_i16(begin, u->i16);
835  return 2;
837  if (begin && (!end || end - begin >= 4))
838  stle_i32(begin, u->i32);
839  return 4;
841  if (begin && (!end || end - begin >= 1))
842  *(co_unsigned8_t *)begin = u->u8;
843  return 1;
845  if (begin && (!end || end - begin >= 2))
846  stle_u16(begin, u->u16);
847  return 2;
849  if (begin && (!end || end - begin >= 4))
850  stle_u32(begin, u->u32);
851  return 4;
852  case CO_DEFTYPE_REAL32:
853  if (begin && (!end || end - begin >= 4))
854  stle_flt32(begin, u->r32);
855  return 4;
858  if (begin && (!end || end - begin >= 6)) {
859  stle_u32(begin, u->t.ms & UINT32_C(0x0fffffff));
860  stle_u16(begin + 4, u->t.days);
861  }
862  return 6;
864  if (begin && (!end || end - begin >= 3)) {
865  co_unsigned24_t u24 = u->i24 < 0
866  ? CO_UNSIGNED24_MAX + 1 + u->i24
867  : (co_unsigned24_t)u->i24;
868  for (size_t i = 0; i < 3; i++)
869  *begin++ = (u24 >> 8 * i) & 0xff;
870  }
871  return 3;
872  case CO_DEFTYPE_REAL64:
873  if (begin && (!end || end - begin >= 8))
874  stle_flt64(begin, u->r64);
875  return 8;
877  if (begin && (!end || end - begin >= 5)) {
878  co_unsigned40_t u40 = u->i40 < 0
879  ? CO_UNSIGNED40_MAX + 1 + u->i40
880  : (co_unsigned40_t)u->i40;
881  for (size_t i = 0; i < 5; i++)
882  *begin++ = (u40 >> 8 * i) & 0xff;
883  }
884  return 5;
886  if (begin && (!end || end - begin >= 6)) {
887  co_unsigned48_t u48 = u->i48 < 0
888  ? CO_UNSIGNED48_MAX + 1 + u->i48
889  : (co_unsigned48_t)u->i48;
890  for (size_t i = 0; i < 6; i++)
891  *begin++ = (u48 >> 8 * i) & 0xff;
892  }
893  return 6;
895  if (begin && (!end || end - begin >= 7)) {
896  co_unsigned56_t u56 = u->i56 < 0
897  ? CO_UNSIGNED56_MAX + 1 + u->i56
898  : (co_unsigned56_t)u->i56;
899  for (size_t i = 0; i < 7; i++)
900  *begin++ = (u56 >> 8 * i) & 0xff;
901  }
902  return 7;
904  if (begin && (!end || end - begin >= 8))
905  stle_i64(begin, u->i64);
906  return 8;
908  if (begin && (!end || end - begin >= 3)) {
909  for (size_t i = 0; i < 3; i++)
910  *begin++ = (u->u24 >> 8 * i) & 0xff;
911  }
912  return 3;
914  if (begin && (!end || end - begin >= 5)) {
915  for (size_t i = 0; i < 5; i++)
916  *begin++ = (u->u40 >> 8 * i) & 0xff;
917  }
918  return 5;
920  if (begin && (!end || end - begin >= 6)) {
921  for (size_t i = 0; i < 6; i++)
922  *begin++ = (u->u48 >> 8 * i) & 0xff;
923  }
924  return 6;
926  if (begin && (!end || end - begin >= 7)) {
927  for (size_t i = 0; i < 7; i++)
928  *begin++ = (u->u56 >> 8 * i) & 0xff;
929  }
930  return 7;
932  if (begin && (!end || end - begin >= 8))
933  stle_u64(begin, u->u64);
934  return 8;
935  default: set_errnum(ERRNUM_INVAL); return 0;
936  }
937  }
938 }
939 
940 #if !LELY_NO_STDIO
941 
942 size_t
943 co_val_write_file(co_unsigned16_t type, const void *val, const char *filename)
944 {
945  fwbuf_t *buf = fwbuf_create(filename);
946  if (buf) {
947  int errc = get_errc();
948  set_errc(0);
949  size_t size = co_val_write_fwbuf(type, val, buf);
950  if (!size && get_errc()) {
951  errc = get_errc();
952  diag(DIAG_ERROR, get_errc(), "%s", filename);
953  }
954  fwbuf_destroy(buf);
955  set_errc(errc);
956  return size;
957  } else {
958  diag(DIAG_ERROR, get_errc(), "%s", filename);
959  return 0;
960  }
961 }
962 
963 size_t
964 co_val_write_fwbuf(co_unsigned16_t type, const void *val, fwbuf_t *buf)
965 {
966  if (co_type_is_array(type)) {
967  const void *ptr = co_val_addressof(type, val);
968  size_t n = co_val_sizeof(type, val);
969  if (!ptr || !n)
970  return 0;
971  switch (type) {
974  case CO_DEFTYPE_DOMAIN:
975  if (fwbuf_write(buf, ptr, n) != (ssize_t)n)
976  return 0;
977  break;
979  const char16_t *us = ptr;
980  for (size_t i = 0; i + 1 < n; i += 2) {
981  uint_least8_t tmp[2];
982  stle_u16(tmp, us[i / 2]);
983  if (fwbuf_write(buf, tmp, 2) != 2)
984  return 0;
985  }
986  break;
987  }
988  // We can never get here.
989  default: return 0;
990  }
991  if (fwbuf_commit(buf) == -1)
992  return 0;
993  return n;
994  } else {
995  union co_val tmp;
996  uint_least8_t *begin = (uint_least8_t *)&tmp;
997  uint_least8_t *end = begin + sizeof(tmp);
998  size_t n = co_val_write(type, val, begin, end);
999  if (!n)
1000  return 0;
1001  if (fwbuf_write(buf, &tmp, n) != (ssize_t)n)
1002  return 0;
1003  if (fwbuf_commit(buf) == -1)
1004  return 0;
1005  return n;
1006  }
1007 }
1008 
1009 size_t
1010 co_val_lex(co_unsigned16_t type, void *val, const char *begin, const char *end,
1011  struct floc *at)
1012 {
1013  assert(begin);
1014  assert(!end || end >= begin);
1015 
1016  // Prevent a previous range error from triggering a spurious warning.
1017  if (get_errnum() == ERRNUM_RANGE)
1018  set_errnum(0);
1019 
1020  const char *cp = begin;
1021  size_t chars = 0;
1022 
1023  union co_val u;
1024  switch (type) {
1025  case CO_DEFTYPE_BOOLEAN:
1026  chars = lex_c99_u8(cp, end, NULL, &u.u8);
1027  if (chars) {
1028  cp += chars;
1029  if (u.u8 > CO_BOOLEAN_MAX) {
1030  u.u8 = CO_BOOLEAN_MAX;
1032  diag_if(DIAG_WARNING, get_errc(), at,
1033  "boolean truth value overflow");
1034  }
1035  if (val)
1036  *(co_boolean_t *)val = u.u8;
1037  }
1038  break;
1039  case CO_DEFTYPE_INTEGER8:
1040  chars = lex_c99_i8(cp, end, NULL, &u.i8);
1041  if (chars) {
1042  cp += chars;
1043 #ifdef INT8_MIN
1044  if (get_errnum() == ERRNUM_RANGE && u.i8 == INT8_MIN) {
1045 #else
1046  if (u.i8 < CO_INTEGER8_MIN) {
1047  u.i8 = CO_INTEGER8_MIN;
1049 #endif
1050  diag_if(DIAG_WARNING, get_errc(), at,
1051  "8-bit signed integer underflow");
1052 #ifdef INT8_MAX
1053  } else if (get_errnum() == ERRNUM_RANGE
1054  && u.i8 == INT8_MAX) {
1055 #else
1056  } else if (u.i8 > CO_INTEGER8_MAX) {
1057  u.i8 = CO_INTEGER8_MAX;
1059 #endif
1060  diag_if(DIAG_WARNING, get_errc(), at,
1061  "8-bit signed integer overflow");
1062  }
1063  if (val)
1064  *(co_integer8_t *)val = u.i8;
1065  }
1066  break;
1067  case CO_DEFTYPE_INTEGER16:
1068  chars = lex_c99_i16(cp, end, NULL, &u.i16);
1069  if (chars) {
1070  cp += chars;
1071 #ifdef INT16_MIN
1072  if (get_errnum() == ERRNUM_RANGE
1073  && u.i16 == INT16_MIN) {
1074 #else
1075  if (u.i16 < CO_INTEGER16_MIN) {
1076  u.i16 = CO_INTEGER16_MIN;
1078 #endif
1079  diag_if(DIAG_WARNING, get_errc(), at,
1080  "16-bit signed integer underflow");
1081 #ifdef INT16_MAX
1082  } else if (get_errnum() == ERRNUM_RANGE
1083  && u.i16 == INT16_MAX) {
1084 #else
1085  } else if (u.i16 > CO_INTEGER16_MAX) {
1086  u.i16 = CO_INTEGER16_MAX;
1088 #endif
1089  diag_if(DIAG_WARNING, get_errc(), at,
1090  "16-bit signed integer overflow");
1091  }
1092  if (val)
1093  *(co_integer16_t *)val = u.i16;
1094  }
1095  break;
1096  case CO_DEFTYPE_INTEGER32:
1097  chars = lex_c99_i32(cp, end, NULL, &u.i32);
1098  if (chars) {
1099  cp += chars;
1100 #ifdef INT32_MIN
1101  if (get_errnum() == ERRNUM_RANGE
1102  && u.i32 == INT32_MIN) {
1103 #else
1104  if (u.i32 < CO_INTEGER32_MIN) {
1105  u.i32 = CO_INTEGER32_MIN;
1107 #endif
1108  diag_if(DIAG_WARNING, get_errc(), at,
1109  "32-bit signed integer underflow");
1110 #ifdef INT32_MAX
1111  } else if (get_errnum() == ERRNUM_RANGE
1112  && u.i32 == INT32_MAX) {
1113 #else
1114  } else if (u.i32 > CO_INTEGER32_MAX) {
1115  u.i32 = CO_INTEGER32_MAX;
1117 #endif
1118  diag_if(DIAG_WARNING, get_errc(), at,
1119  "32-bit signed integer overflow");
1120  }
1121  if (val)
1122  *(co_integer32_t *)val = u.i32;
1123  }
1124  break;
1125  case CO_DEFTYPE_UNSIGNED8:
1126  chars = lex_c99_u8(cp, end, NULL, &u.u8);
1127  if (chars) {
1128  cp += chars;
1129 #ifdef UINT8_MAX
1130  if (get_errnum() == ERRNUM_RANGE && u.u8 == UINT8_MAX) {
1131 #else
1132  if (u.u8 > CO_UNSIGNED8_MAX) {
1133  u.u8 = CO_UNSIGNED8_MAX;
1135 #endif
1136  diag_if(DIAG_WARNING, get_errc(), at,
1137  "8-bit unsigned integer overflow");
1138  }
1139  if (val)
1140  *(co_unsigned8_t *)val = u.u8;
1141  }
1142  break;
1143  case CO_DEFTYPE_UNSIGNED16:
1144  chars = lex_c99_u16(cp, end, NULL, &u.u16);
1145  if (chars) {
1146  cp += chars;
1147 #ifdef UINT16_MAX
1148  if (get_errnum() == ERRNUM_RANGE
1149  && u.u16 == UINT16_MAX) {
1150 #else
1151  if (u.u16 > CO_UNSIGNED16_MAX) {
1152  u.u16 = CO_UNSIGNED16_MAX;
1154 #endif
1155  diag_if(DIAG_WARNING, get_errc(), at,
1156  "16-bit unsigned integer overflow");
1157  }
1158  if (val)
1159  *(co_unsigned16_t *)val = u.u16;
1160  }
1161  break;
1162  case CO_DEFTYPE_UNSIGNED32:
1163  chars = lex_c99_u32(cp, end, NULL, &u.u32);
1164  if (chars) {
1165  cp += chars;
1166 #ifdef UINT32_MAX
1167  if (get_errnum() == ERRNUM_RANGE
1168  && u.u32 == UINT32_MAX) {
1169 #else
1170  if (u.u32 > CO_UNSIGNED32_MAX) {
1171  u.u32 = CO_UNSIGNED32_MAX;
1173 #endif
1174  diag_if(DIAG_WARNING, get_errc(), at,
1175  "32-bit unsigned integer overflow");
1176  }
1177  if (val)
1178  *(co_unsigned32_t *)val = u.u32;
1179  }
1180  break;
1181  case CO_DEFTYPE_REAL32:
1182  chars = lex_c99_u32(cp, end, NULL, &u.u32);
1183  if (chars) {
1184  cp += chars;
1185  if (get_errnum() == ERRNUM_RANGE
1186  && u.u32 == UINT_LEAST32_MAX)
1187  diag_if(DIAG_WARNING, get_errc(), at,
1188  "32-bit unsigned integer overflow");
1189  // clang-format off
1190  u.r32 = ((union {
1191  uint_least32_t u32;
1192  co_real32_t r32;
1193  }){ u.u32 }).r32;
1194  // clang-format on
1195  if (val)
1196  *(co_real32_t *)val = u.r32;
1197  }
1198  break;
1200  size_t n = 0;
1201  chars = lex_c99_str(cp, end, NULL, NULL, &n);
1202  if (val) {
1203  if (co_val_init_vs_n(val, 0, n) == -1) {
1204  diag_if(DIAG_ERROR, get_errc(), at,
1205  "unable to create value of type VISIBLE_STRING");
1206  return 0;
1207  }
1208  // Parse the characters.
1209  char *vs = *(void **)val;
1210  assert(vs);
1211  lex_c99_str(cp, end, NULL, vs, &n);
1212  }
1213  cp += chars;
1214  break;
1215  }
1216  case CO_DEFTYPE_OCTET_STRING: {
1217  size_t n = 0;
1218  chars = lex_base64(cp, end, NULL, NULL, &n);
1219  if (val) {
1220  if (co_val_init_os(val, NULL, n) == -1) {
1221  diag_if(DIAG_ERROR, get_errc(), at,
1222  "unable to create value of type OCTET_STRING");
1223  return 0;
1224  }
1225  // Parse the octets.
1226  uint_least8_t *os = *(void **)val;
1227  assert(!n || os);
1228  lex_base64(cp, end, NULL, os, &n);
1229  }
1230  cp += chars;
1231  break;
1232  }
1234  size_t n = 0;
1235  chars = lex_base64(cp, end, NULL, NULL, &n);
1236  if (val) {
1237  if (co_val_init_us_n(val, NULL, n / 2) == -1) {
1238  diag_if(DIAG_ERROR, get_errc(), at,
1239  "unable to create value of type UNICODE_STRING");
1240  return 0;
1241  }
1242  // Parse the Unicode characters.
1243  char16_t *us = *(void **)val;
1244  assert(us);
1245  lex_base64(cp, end, NULL, us, &n);
1246  for (size_t i = 0; i + 1 < n; i += 2)
1247  us[i / 2] = letoh16(us[i / 2]);
1248  }
1249  cp += chars;
1250  break;
1251  }
1253  case CO_DEFTYPE_TIME_DIFF:
1254  chars = lex_c99_u16(cp, end, NULL, &u.t.days);
1255  if (!chars)
1256  return 0;
1257  cp += chars;
1258  cp += lex_ctype(&isblank, cp, end, NULL);
1259  chars = lex_c99_u32(cp, end, NULL, &u.t.ms);
1260  if (!chars)
1261  return 0;
1262  cp += chars;
1263  if (val)
1264  *(co_time_of_day_t *)val = u.t;
1265  break;
1266  case CO_DEFTYPE_DOMAIN: {
1267  size_t n = 0;
1268  chars = lex_base64(cp, end, NULL, NULL, &n);
1269  if (val) {
1270  if (co_val_init_dom(val, NULL, n) == -1) {
1271  diag_if(DIAG_ERROR, get_errc(), at,
1272  "unable to create value of type DOMAIN");
1273  return 0;
1274  }
1275  void *dom = *(void **)val;
1276  assert(!n || dom);
1277  lex_base64(cp, end, NULL, dom, &n);
1278  }
1279  cp += chars;
1280  break;
1281  }
1282  case CO_DEFTYPE_INTEGER24:
1283  chars = lex_c99_i32(cp, end, NULL, &u.i32);
1284  if (chars) {
1285  cp += chars;
1286  if (u.i32 < CO_INTEGER24_MIN) {
1287  u.i32 = CO_INTEGER24_MIN;
1289  diag_if(DIAG_WARNING, get_errc(), at,
1290  "24-bit signed integer underflow");
1291  } else if (u.i32 > CO_INTEGER24_MAX) {
1292  u.i32 = CO_INTEGER24_MAX;
1294  diag_if(DIAG_WARNING, get_errc(), at,
1295  "24-bit signed integer overflow");
1296  }
1297  if (val)
1298  *(co_integer24_t *)val = u.i32;
1299  }
1300  break;
1301  case CO_DEFTYPE_REAL64:
1302  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1303  if (chars) {
1304  cp += chars;
1305  if (get_errnum() == ERRNUM_RANGE
1306  && u.u64 == UINT_LEAST64_MAX)
1307  diag_if(DIAG_WARNING, get_errc(), at,
1308  "64-bit unsigned integer overflow");
1309  // clang-format off
1310  u.r64 = ((union {
1311  uint_least64_t u64;
1312  co_real64_t r64;
1313  }){ u.u64 }).r64;
1314  // clang-format on
1315  if (val)
1316  *(co_real64_t *)val = u.r64;
1317  }
1318  break;
1319  case CO_DEFTYPE_INTEGER40:
1320  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1321  if (chars) {
1322  cp += chars;
1323  if (u.i64 < CO_INTEGER40_MIN) {
1324  u.i64 = CO_INTEGER40_MIN;
1326  diag_if(DIAG_WARNING, get_errc(), at,
1327  "40-bit signed integer underflow");
1328  } else if (u.i64 > CO_INTEGER40_MAX) {
1329  u.i64 = CO_INTEGER40_MAX;
1331  diag_if(DIAG_WARNING, get_errc(), at,
1332  "40-bit signed integer overflow");
1333  }
1334  if (val)
1335  *(co_integer40_t *)val = u.i64;
1336  }
1337  break;
1338  case CO_DEFTYPE_INTEGER48:
1339  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1340  if (chars) {
1341  cp += chars;
1342  if (u.i64 < CO_INTEGER48_MIN) {
1343  u.i64 = CO_INTEGER48_MIN;
1345  diag_if(DIAG_WARNING, get_errc(), at,
1346  "48-bit signed integer underflow");
1347  } else if (u.i64 > CO_INTEGER48_MAX) {
1348  u.i64 = CO_INTEGER48_MAX;
1350  diag_if(DIAG_WARNING, get_errc(), at,
1351  "48-bit signed integer overflow");
1352  }
1353  if (val)
1354  *(co_integer48_t *)val = u.i64;
1355  }
1356  break;
1357  case CO_DEFTYPE_INTEGER56:
1358  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1359  if (chars) {
1360  cp += chars;
1361  if (u.i64 < CO_INTEGER56_MIN) {
1362  u.i64 = CO_INTEGER56_MIN;
1364  diag_if(DIAG_WARNING, get_errc(), at,
1365  "56-bit signed integer underflow");
1366  } else if (u.i64 > CO_INTEGER56_MAX) {
1367  u.i64 = CO_INTEGER56_MAX;
1369  diag_if(DIAG_WARNING, get_errc(), at,
1370  "56-bit signed integer overflow");
1371  }
1372  if (val)
1373  *(co_integer56_t *)val = u.i64;
1374  }
1375  break;
1376  case CO_DEFTYPE_INTEGER64:
1377  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1378  if (chars) {
1379  cp += chars;
1380 #ifdef INT64_MIN
1381  if (get_errnum() == ERRNUM_RANGE
1382  && u.i64 == INT64_MIN) {
1383 #else
1384  if (u.i64 > CO_INTEGER64_MIN) {
1385  u.i64 = CO_INTEGER64_MIN;
1387 #endif
1388  diag_if(DIAG_WARNING, get_errc(), at,
1389  "64-bit signed integer underflow");
1390 #ifdef INT64_MAX
1391  } else if (get_errnum() == ERRNUM_RANGE
1392  && u.i64 == INT64_MAX) {
1393 #else
1394  } else if (u.i64 < CO_INTEGER64_MAX) {
1395  u.i64 = CO_INTEGER64_MAX;
1397 #endif
1398  diag_if(DIAG_WARNING, get_errc(), at,
1399  "64-bit signed integer overflow");
1400  }
1401  if (val)
1402  *(co_integer64_t *)val = u.i64;
1403  }
1404  break;
1405  case CO_DEFTYPE_UNSIGNED24:
1406  chars = lex_c99_u32(cp, end, NULL, &u.u32);
1407  if (chars) {
1408  cp += chars;
1409  if (u.u32 > CO_UNSIGNED24_MAX) {
1410  u.u32 = CO_UNSIGNED24_MAX;
1412  diag_if(DIAG_WARNING, get_errc(), at,
1413  "24-bit unsigned integer overflow");
1414  }
1415  if (val)
1416  *(co_unsigned24_t *)val = u.u32;
1417  }
1418  break;
1419  case CO_DEFTYPE_UNSIGNED40:
1420  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1421  if (chars) {
1422  cp += chars;
1423  if (u.u64 > CO_UNSIGNED40_MAX) {
1424  u.u64 = CO_UNSIGNED40_MAX;
1426  diag_if(DIAG_WARNING, get_errc(), at,
1427  "40-bit unsigned integer overflow");
1428  }
1429  if (val)
1430  *(co_unsigned40_t *)val = u.u64;
1431  }
1432  break;
1433  case CO_DEFTYPE_UNSIGNED48:
1434  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1435  if (chars) {
1436  cp += chars;
1437  if (u.u64 > CO_UNSIGNED48_MAX) {
1438  u.u64 = CO_UNSIGNED48_MAX;
1440  diag_if(DIAG_WARNING, get_errc(), at,
1441  "48-bit unsigned integer overflow");
1442  }
1443  if (val)
1444  *(co_unsigned48_t *)val = u.u64;
1445  }
1446  break;
1447  case CO_DEFTYPE_UNSIGNED56:
1448  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1449  if (chars) {
1450  cp += chars;
1451  if (u.u64 > CO_UNSIGNED56_MAX) {
1452  u.u64 = CO_UNSIGNED56_MAX;
1454  diag_if(DIAG_WARNING, get_errc(), at,
1455  "56-bit unsigned integer overflow");
1456  }
1457  if (val)
1458  *(co_unsigned56_t *)val = u.u64;
1459  }
1460  break;
1461  case CO_DEFTYPE_UNSIGNED64:
1462  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1463  if (chars) {
1464  cp += chars;
1465 #ifdef UINT64_MAX
1466  if (get_errnum() == ERRNUM_RANGE
1467  && u.u64 == UINT64_MAX) {
1468 #else
1469  if (u.u64 > CO_UNSIGNED64_MAX) {
1470  u.u64 = CO_UNSIGNED64_MAX;
1472 #endif
1473  diag_if(DIAG_WARNING, get_errc(), at,
1474  "64-bit unsigned integer overflow");
1475  }
1476  if (val)
1477  *(co_unsigned64_t *)val = u.u64;
1478  }
1479  break;
1480  default:
1481  diag_if(DIAG_ERROR, 0, at, "cannot parse value of type 0x%04X",
1482  type);
1483  break;
1484  }
1485 
1486  return floc_lex(at, begin, cp);
1487 }
1488 
1489 size_t
1490 co_val_print(co_unsigned16_t type, const void *val, char **pbegin, char *end)
1491 {
1492  if (co_type_is_array(type)) {
1493  const void *ptr = co_val_addressof(type, val);
1494  size_t n = co_val_sizeof(type, val);
1495  if (!ptr || !n)
1496  return 0;
1497  switch (type) {
1499  return print_c99_str(pbegin, end, ptr, n);
1500  case CO_DEFTYPE_OCTET_STRING: {
1501  return print_base64(pbegin, end, ptr, n);
1502  }
1504 #if LELY_NO_MALLOC
1505  if (n > CO_ARRAY_CAPACITY) {
1507  return -1;
1508  }
1509  char16_t us[CO_ARRAY_CAPACITY / 2];
1510 #else
1511  char16_t *us = malloc(n);
1512  if (!us)
1513  return 0;
1514 #endif
1515  memcpy(us, ptr, n);
1516  for (size_t i = 0; i + 1 < n; i += 2)
1517  us[i / 2] = htole16(us[i / 2]);
1518  size_t chars = print_base64(pbegin, end, us, n);
1519 #if !LELY_NO_MALLOC
1520  free(us);
1521 #endif
1522  return chars;
1523  }
1524  case CO_DEFTYPE_DOMAIN:
1525  return print_base64(pbegin, end, ptr, n);
1526  default:
1527  // We can never get here.
1528  return 0;
1529  }
1530  } else {
1531  const union co_val *u = val;
1532  assert(u);
1533  switch (type) {
1534  case CO_DEFTYPE_BOOLEAN:
1535  return print_c99_u8(pbegin, end, !!u->b);
1536  case CO_DEFTYPE_INTEGER8:
1537  return print_c99_i8(pbegin, end, u->i8);
1538  case CO_DEFTYPE_INTEGER16:
1539  return print_c99_i16(pbegin, end, u->i16);
1540  case CO_DEFTYPE_INTEGER32:
1541  return print_c99_i32(pbegin, end, u->i32);
1542  case CO_DEFTYPE_UNSIGNED8:
1543  return print_fmt(pbegin, end, "0x%02" PRIx8, u->u8);
1544  case CO_DEFTYPE_UNSIGNED16:
1545  return print_fmt(pbegin, end, "0x%04" PRIx16, u->u16);
1546  case CO_DEFTYPE_UNSIGNED32:
1547  return print_fmt(pbegin, end, "0x%08" PRIx32, u->u32);
1548  case CO_DEFTYPE_REAL32:
1549  return print_c99_u32(pbegin, end, u->u32);
1551  case CO_DEFTYPE_TIME_DIFF: {
1552  size_t chars = 0;
1553  chars += print_c99_u16(pbegin, end, u->t.days);
1554  chars += print_char(pbegin, end, ' ');
1555  chars += print_c99_u32(pbegin, end, u->t.ms);
1556  return chars;
1557  }
1558  case CO_DEFTYPE_INTEGER24:
1559  return print_c99_i32(pbegin, end, u->i24);
1560  case CO_DEFTYPE_REAL64:
1561  return print_fmt(pbegin, end, "0x%016" PRIx64, u->u64);
1562  case CO_DEFTYPE_INTEGER40:
1563  return print_c99_i64(pbegin, end, u->i40);
1564  case CO_DEFTYPE_INTEGER48:
1565  return print_c99_i64(pbegin, end, u->i48);
1566  case CO_DEFTYPE_INTEGER56:
1567  return print_c99_i64(pbegin, end, u->i56);
1568  case CO_DEFTYPE_INTEGER64:
1569  return print_c99_i64(pbegin, end, u->i64);
1570  case CO_DEFTYPE_UNSIGNED24:
1571  return print_fmt(pbegin, end, "0x%06" PRIx32, u->u24);
1572  case CO_DEFTYPE_UNSIGNED40:
1573  return print_fmt(pbegin, end, "0x%010" PRIx64, u->u40);
1574  case CO_DEFTYPE_UNSIGNED48:
1575  return print_fmt(pbegin, end, "0x%012" PRIx64, u->u48);
1576  case CO_DEFTYPE_UNSIGNED56:
1577  return print_fmt(pbegin, end, "0x%014" PRIx64, u->u56);
1578  case CO_DEFTYPE_UNSIGNED64:
1579  return print_fmt(pbegin, end, "0x%016" PRIx64, u->u64);
1580  default: set_errnum(ERRNUM_INVAL); return 0;
1581  }
1582  }
1583 }
1584 
1585 #endif // !LELY_NO_STDIO
1586 
1587 static inline struct co_array_hdr *
1588 co_array_get_hdr(const void *val)
1589 {
1590  assert(val);
1591 
1592  char *ptr = *(char **)val;
1593  return ptr ? (void *)(ptr - CO_ARRAY_HDR_OFFSET) : NULL;
1594 }
1595 
1596 static int
1597 co_array_alloc(void *val, size_t size)
1598 {
1599  assert(val);
1600 
1601 #if LELY_NO_MALLOC
1602  struct co_array_hdr *hdr = co_array_get_hdr(val);
1603  if (!hdr || hdr->capacity < size) {
1605  return -1;
1606  }
1607  hdr->size = 0;
1608 #else
1609  if (size) {
1610  // cppcheck-suppress AssignmentAddressToInteger
1611  struct co_array_hdr *hdr = malloc(CO_ARRAY_HDR_OFFSET + size);
1612  if (!hdr) {
1613 #if !LELY_NO_ERRNO
1614  set_errc(errno2c(errno));
1615 #endif
1616  return -1;
1617  }
1618  *hdr = (struct co_array_hdr){ size, 0 };
1619  *(char **)val = (char *)hdr + CO_ARRAY_HDR_OFFSET;
1620  } else {
1621  *(char **)val = NULL;
1622  }
1623 #endif
1624 
1625  return 0;
1626 }
1627 
1628 static void
1629 co_array_free(void *val)
1630 {
1631 #if LELY_NO_MALLOC
1632  (void)val;
1633 #else
1634  struct co_array_hdr *hdr = co_array_get_hdr(val);
1635  if (hdr)
1636  free(hdr);
1637 #endif
1638 }
1639 
1640 static void
1641 co_array_init(void *val, size_t size)
1642 {
1643  struct co_array_hdr *hdr = co_array_get_hdr(val);
1644  assert(val || !size);
1645 
1646  if (hdr) {
1647  memset(*(char **)val, 0, hdr->capacity);
1648  assert(size <= hdr->capacity);
1649  hdr->size = size;
1650  }
1651 }
1652 
1653 static void
1654 co_array_fini(void *val)
1655 {
1656 #if LELY_NO_MALLOC
1657  co_array_init(val, 0);
1658 #else
1659  assert(val);
1660 
1661  *(char **)val = NULL;
1662 #endif
1663 }
1664 
1665 static size_t
1666 co_array_sizeof(const void *val)
1667 {
1668  const struct co_array_hdr *hdr = co_array_get_hdr(val);
1669 
1670  return hdr ? hdr->size : 0;
1671 }
This header file is part of the utilities library; it contains the comparison function definitions.
This header file is part of the utilities library; it contains the diagnostic declarations.
size_t floc_lex(struct floc *at, const char *begin, const char *end)
Increments a file location by reading characters from a memory buffer.
Definition: diag.c:65
@ DIAG_WARNING
A warning.
Definition: diag.h:55
@ DIAG_ERROR
An error.
Definition: diag.h:57
void diag_if(enum diag_severity severity, int errc, const struct floc *at, const char *format,...)
Emits a diagnostic message occurring at a location in a text file.
Definition: diag.c:205
void diag(enum diag_severity severity, int errc, const char *format,...)
Emits a diagnostic message.
Definition: diag.c:171
This header file is part of the utilities library; it contains the byte order (endianness) function d...
void stle_u64(uint_least8_t dst[8], uint_least64_t x)
Stores a 64-bit unsigned integer in little-endian byte order.
Definition: endian.h:672
uint_least16_t htole16(uint_least16_t x)
Converts a 16-bit unsigned integer from host to little-endian byte order.
Definition: endian.h:351
uint_least32_t ldle_u32(const uint_least8_t src[4])
Loads a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:596
void stle_i64(uint_least8_t dst[8], int_least64_t x)
Stores a 64-bit signed integer in little-endian byte order.
Definition: endian.h:660
int_least32_t ldle_i32(const uint_least8_t src[4])
Loads a 32-bit signed integer in little-endian byte order.
Definition: endian.h:576
int_least16_t ldle_i16(const uint_least8_t src[2])
Loads a 16-bit signed integer in little-endian byte order.
Definition: endian.h:498
int_least64_t ldle_i64(const uint_least8_t src[8])
Loads a 64-bit signed integer in little-endian byte order.
Definition: endian.h:666
uint_least16_t ldle_u16(const uint_least8_t src[2])
Loads a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:516
void stle_i16(uint_least8_t dst[2], int_least16_t x)
Stores a 16-bit signed integer in little-endian byte order.
Definition: endian.h:492
uint_least64_t ldle_u64(const uint_least8_t src[8])
Loads a 64-bit unsigned integer in little-endian byte order.
Definition: endian.h:690
void stle_i32(uint_least8_t dst[4], int_least32_t x)
Stores a 32-bit signed integer in little-endian byte order.
Definition: endian.h:570
void stle_u16(uint_least8_t dst[2], uint_least16_t x)
Stores a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:504
void stle_u32(uint_least8_t dst[4], uint_least32_t x)
Stores a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:582
@ ERRNUM_RANGE
Result too large.
Definition: errnum.h:218
@ ERRNUM_NOMEM
Not enough space.
Definition: errnum.h:172
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:132
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:46
errnum_t get_errnum(void)
Returns the last (thread-specific) platform-independent error number set by a system call or library ...
Definition: errnum.h:418
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
This header file is part of the utilities library; it contains the read file buffer declarations.
intmax_t frbuf_get_size(frbuf_t *buf)
Returns the size (in bytes) of the a read file buffer, or -1 on error.
Definition: frbuf.c:172
frbuf_t * frbuf_create(const char *filename)
Creates a new read file buffer.
Definition: frbuf.c:138
void frbuf_destroy(frbuf_t *buf)
Destroys a read file buffer.
Definition: frbuf.c:163
intmax_t frbuf_get_pos(frbuf_t *buf)
Returns the current offset (in bytes) of a read file buffer with respect to the beginning of the file...
Definition: frbuf.c:217
ssize_t frbuf_read(frbuf_t *buf, void *ptr, size_t size)
Reads bytes from the current position in a read file buffer.
Definition: frbuf.c:275
This header file is part of the utilities library; it contains the (atomic) write file buffer declara...
ssize_t fwbuf_write(fwbuf_t *buf, const void *ptr, size_t size)
Writes bytes to the current position in a write file buffer.
Definition: fwbuf.c:489
void fwbuf_destroy(fwbuf_t *buf)
Destroys a write file buffer.
Definition: fwbuf.c:330
int fwbuf_commit(fwbuf_t *buf)
Commits all changes to a write file buffer to disk if all previous file operations were successful,...
Definition: fwbuf.c:979
fwbuf_t * fwbuf_create(const char *filename)
Creates a new (atomic) write file buffer.
Definition: fwbuf.c:305
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
#define CO_SDO_AC_ERROR
SDO abort code: General error.
Definition: sdo.h:150
#define CO_SDO_AC_NO_MEM
SDO abort code: Out of memory.
Definition: sdo.h:81
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
This header file is part of the utilities library; it contains the lexer function declarations.
size_t lex_c99_i16(const char *begin, const char *end, struct floc *at, int_least16_t *pi16)
Lexes a C99 int_least16_t from a memory buffer.
Definition: lex.c:448
size_t lex_ctype(int(*ctype)(int), const char *begin, const char *end, struct floc *at)
Greedily lexes a sequence of characters of the specified class from a memory buffer.
Definition: lex.c:54
size_t lex_c99_u8(const char *begin, const char *end, struct floc *at, uint_least8_t *pu8)
Lexes a C99 uint_least8_t from a memory buffer.
Definition: lex.c:543
size_t lex_base64(const char *begin, const char *end, struct floc *at, void *ptr, size_t *pn)
Lexes and decodes the Base64 representation of binary data from a memory buffer.
Definition: lex.c:685
size_t lex_c99_str(const char *begin, const char *end, struct floc *at, char *s, size_t *pn)
Lexes a UTF-8 encoded Unicode string from a memory buffer.
Definition: lex.c:250
size_t lex_c99_i8(const char *begin, const char *end, struct floc *at, int_least8_t *pi8)
Lexes a C99 int_least8_t from a memory buffer.
Definition: lex.c:424
size_t lex_c99_u32(const char *begin, const char *end, struct floc *at, uint_least32_t *pu32)
Lexes a C99 uint_least32_t from a memory buffer.
Definition: lex.c:581
size_t lex_c99_u64(const char *begin, const char *end, struct floc *at, uint_least64_t *pu64)
Lexes a C99 uint_least64_t from a memory buffer.
Definition: lex.c:604
size_t lex_c99_i32(const char *begin, const char *end, struct floc *at, int_least32_t *pi32)
Lexes a C99 int_least32_t from a memory buffer.
Definition: lex.c:472
size_t lex_c99_u16(const char *begin, const char *end, struct floc *at, uint_least16_t *pu16)
Lexes a C99 uint_least16_t from a memory buffer.
Definition: lex.c:562
size_t lex_c99_i64(const char *begin, const char *end, struct floc *at, int_least64_t *pi64)
Lexes a C99 int_least64_t from a memory buffer.
Definition: lex.c:504
This header file is part of the utilities library; it contains the printing function declarations.
size_t print_c99_i8(char **pbegin, char *end, int_least8_t i8)
Prints a C99 int_least8_t to a memory buffer.
Definition: print.c:242
size_t print_c99_str(char **pbegin, char *end, const char *s, size_t n)
Prints a UTF-8 encoded Unicode string to a memory buffer.
Definition: print.c:193
size_t print_char(char **pbegin, char *end, int c)
Prints a single character to a memory buffer.
Definition: print.h:286
size_t print_c99_u8(char **pbegin, char *end, uint_least8_t u8)
Prints a C99 uint_least8_t to a memory buffer.
Definition: print.c:250
size_t print_c99_i32(char **pbegin, char *end, int_least32_t i32)
Prints a C99 int_least32_t to a memory buffer.
Definition: print.c:244
size_t print_c99_u32(char **pbegin, char *end, uint_least32_t u32)
Prints a C99 uint_least32_t to a memory buffer.
Definition: print.c:252
size_t print_base64(char **pbegin, char *end, const void *ptr, size_t n)
Prints the Base64 representation of binary data to a memory buffer.
Definition: print.c:262
size_t print_c99_i16(char **pbegin, char *end, int_least16_t i16)
Prints a C99 int_least16_t to a memory buffer.
Definition: print.c:243
size_t print_c99_i64(char **pbegin, char *end, int_least64_t i64)
Prints a C99 int_least64_t to a memory buffer.
Definition: print.c:248
size_t print_c99_u16(char **pbegin, char *end, uint_least16_t u16)
Prints a C99 uint_least16_t to a memory buffer.
Definition: print.c:251
size_t print_fmt(char **pbegin, char *end, const char *format,...)
Prints a formatted string to a memory buffer.
Definition: print.c:43
This is the internal header file of the CANopen library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
An read file buffer struct.
Definition: frbuf.c:52
An (atomic) write file buffer struct.
Definition: fwbuf.c:59
The header directly preceding the bytes in a CANopen array.
Definition: val.h:280
size_t size
The current size (in bytes).
Definition: val.h:284
size_t capacity
The total capacity (in bytes).
Definition: val.h:282
A location in a text file.
Definition: diag.h:39
#define CO_DEFTYPE_UNICODE_STRING
The data type (and object index) of an array of (16-bit) Unicode characters.
Definition: type.h:62
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
Definition: type.h:47
#define CO_DEFTYPE_INTEGER24
The data type (and object index) of a 24-bit signed integer.
Definition: type.h:80
#define CO_DEFTYPE_UNSIGNED48
The data type (and object index) of a 48-bit unsigned integer.
Definition: type.h:104
#define CO_DEFTYPE_INTEGER48
The data type (and object index) of a 48-bit signed integer.
Definition: type.h:89
#define CO_DEFTYPE_VISIBLE_STRING
The data type (and object index) of an array of visible characters.
Definition: type.h:56
#define CO_DEFTYPE_UNSIGNED40
The data type (and object index) of a 40-bit unsigned integer.
Definition: type.h:101
int co_type_is_array(co_unsigned16_t type)
Returns 1 if the specified (static) data type is an array, and 0 if not.
Definition: type.c:40
#define CO_DEFTYPE_INTEGER56
The data type (and object index) of a 56-bit signed integer.
Definition: type.h:92
#define CO_DEFTYPE_UNSIGNED64
The data type (and object index) of a 64-bit unsigned integer.
Definition: type.h:110
#define CO_DEFTYPE_INTEGER8
The data type (and object index) of an 8-bit signed integer.
Definition: type.h:35
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
Definition: type.h:77
#define CO_DEFTYPE_UNSIGNED24
The data type (and object index) of a 24-bit unsigned integer.
Definition: type.h:98
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
Definition: type.h:44
#define CO_DEFTYPE_REAL64
The data type (and object index) of a 64-bit IEEE-754 floating-point number.
Definition: type.h:83
#define CO_DEFTYPE_BOOLEAN
The data type (and object index) of a boolean truth value.
Definition: type.h:32
#define CO_DEFTYPE_INTEGER40
The data type (and object index) of a 40-bit signed integer.
Definition: type.h:86
#define CO_DEFTYPE_TIME_OF_DAY
The data type (and object index) of a 48-bit structure representing the absolute time.
Definition: type.h:68
size_t co_type_sizeof(co_unsigned16_t type)
Returns the native size (in bytes) of a value of the specified data type, or 1 if it is not a static ...
Definition: type.c:52
#define CO_DEFTYPE_INTEGER32
The data type (and object index) of a 32-bit signed integer.
Definition: type.h:41
#define CO_DEFTYPE_INTEGER64
The data type (and object index) of a 64-bit signed integer.
Definition: type.h:95
#define CO_DEFTYPE_UNSIGNED56
The data type (and object index) of a 56-bit unsigned integer.
Definition: type.h:107
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
Definition: type.h:50
#define CO_DEFTYPE_INTEGER16
The data type (and object index) of a 16-bit signed integer.
Definition: type.h:38
#define CO_DEFTYPE_OCTET_STRING
The data type (and object index) of an array of octets.
Definition: type.h:59
#define CO_DEFTYPE_REAL32
The data type (and object index) of a 32-bit IEEE-754 floating-point number.
Definition: type.h:53
#define CO_DEFTYPE_TIME_DIFF
The data type (and object index) of a 48-bit structure representing a time difference.
Definition: type.h:74
This header file is part of the C11 and POSIX compatibility library; it includes <sys/types....
A union of the CANopen static data types.
Definition: val.h:273
This header file is part of the utilities library; it contains (16-bit) Unicode string functions.
int str16ncmp(const char16_t *s1, const char16_t *s2, size_t n)
Compares two (16-bit) Unicode strings.
Definition: ustring.h:100
char16_t * str16ncpy(char16_t *dst, const char16_t *src, size_t n)
Copies n (16-bit) Unicode characters from the string at src to dst.
Definition: ustring.h:88
size_t str16len(const char16_t *s)
Returns the number of (16-bit) Unicode characters, excluding the terminating null bytes,...
Definition: ustring.h:78
size_t co_val_read_frbuf(co_unsigned16_t type, void *val, frbuf_t *buf)
Reads a value of the specified data type from the current position in a read file buffer.
Definition: val.c:692
size_t co_val_read(co_unsigned16_t type, void *val, const uint_least8_t *begin, const uint_least8_t *end)
Reads a value of the specified data type from a memory buffer.
Definition: val.c:451
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
Definition: val.c:62
size_t co_val_move(co_unsigned16_t type, void *dst, void *src)
Moves one value to another.
Definition: val.c:354
int co_val_init_os(uint_least8_t **val, const uint_least8_t *os, size_t n)
Initializes an array of octets (CO_DEFTYPE_OCTET_STRING).
Definition: val.c:179
size_t co_val_write(co_unsigned16_t type, const void *val, uint_least8_t *begin, uint_least8_t *end)
Writes a value of the specified data type to a memory buffer.
Definition: val.c:791
int co_val_init_dom(void **val, const void *dom, size_t n)
Initializes an arbitrary large block of data (CO_DEFTYPE_DOMAIN).
Definition: val.c:230
const void * co_val_addressof(co_unsigned16_t type, const void *val)
Returns the address of the first byte in a value of the specified data type.
Definition: val.c:260
size_t co_val_copy(co_unsigned16_t type, void *dst, const void *src)
Copies one value to another.
Definition: val.c:318
size_t co_val_sizeof(co_unsigned16_t type, const void *val)
Returns the size (in bytes) of a value of the specified data type.
Definition: val.c:269
int co_val_init_us_n(char16_t **val, const char16_t *us, size_t n)
Initializes an array of (16-bit) Unicode characters (CO_DEFTYPE_UNICODE_STRING).
Definition: val.c:211
int co_val_init_vs_n(char **val, const char *vs, size_t n)
Initializes an array of visible characters (CO_DEFTYPE_VISIBLE_STRING).
Definition: val.c:157
size_t co_val_read_file(co_unsigned16_t type, void *val, const char *filename)
Reads a value of the specified data type from a file.
Definition: val.c:671
int co_val_init_us(char16_t **val, const char16_t *us)
Initializes an array of (16-bit) Unicode characters (CO_DEFTYPE_UNICODE_STRING).
Definition: val.c:198
int co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
Compares two values of the specified data type.
Definition: val.c:369
co_unsigned32_t co_val_read_sdo(co_unsigned16_t type, void *val, const void *ptr, size_t n)
Reads a value of the specified data type from an SDO buffer.
Definition: val.c:767
int co_val_init_min(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its lower limit.
Definition: val.c:90
size_t co_val_print(co_unsigned16_t type, const void *val, char **pbegin, char *end)
Prints a value of the specified data type to a memory buffer.
Definition: val.c:1490
size_t co_val_make(co_unsigned16_t type, void *val, const void *ptr, size_t n)
Constructs a value of the specified data type.
Definition: val.c:282
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
Definition: val.c:249
int co_val_init_vs(char **val, const char *vs)
Initializes an array of visible characters (CO_DEFTYPE_VISIBLE_STRING).
Definition: val.c:146
size_t co_val_write_file(co_unsigned16_t type, const void *val, const char *filename)
Writes a value of the specified data type to a file.
Definition: val.c:943
size_t co_val_lex(co_unsigned16_t type, void *val, const char *begin, const char *end, struct floc *at)
Lexes a value of the specified data type from a memory buffer.
Definition: val.c:1010
size_t co_val_write_fwbuf(co_unsigned16_t type, const void *val, fwbuf_t *buf)
Writes a value of the specified data type to the current position in a write file buffer.
Definition: val.c:964
int co_val_init_max(co_unsigned16_t type, void *val)
Initializes a value of the specified data type with its upper limit.
Definition: val.c:118
This header file is part of the CANopen library; it contains the CANopen value declarations.
#define CO_INTEGER8_MIN
The minimum value of an 8-bit signed integer.
Definition: val.h:51
#define CO_INTEGER64_MAX
The maximum value of a 64-bit signed integer.
Definition: val.h:225
#define CO_INTEGER32_MAX
The maximum value of a 32-bit signed integer.
Definition: val.h:72
#define CO_INTEGER24_MAX
The maximum value of a 24-bit signed integer (encoded as an int32_t).
Definition: val.h:180
#define CO_UNSIGNED8_MAX
The maximum value of an 8-bit unsigned integer.
Definition: val.h:81
#define CO_INTEGER16_MAX
The maximum value of a 16-bit signed integer.
Definition: val.h:63
#define CO_ARRAY_CAPACITY
The default capacity (in bytes) of a statically allocated CANopen array.
Definition: val.h:292
#define CO_UNSIGNED32_MAX
The maximum value of a 32-bit unsigned integer.
Definition: val.h:99
#define CO_INTEGER48_MAX
The maximum value of a 48-bit signed integer (encoded as an int64_t).
Definition: val.h:207
#define CO_INTEGER24_MIN
The minimum value of a 24-bit signed integer (encoded as an int32_t).
Definition: val.h:177
#define CO_BOOLEAN_MAX
The maximum value of a boolean truth value (true).
Definition: val.h:45
#define CO_UNSIGNED64_MAX
The maximum value of a 64-bit unsigned integer.
Definition: val.h:270
#define CO_INTEGER32_MIN
The minimum value of a 32-bit signed integer.
Definition: val.h:69
#define CO_INTEGER40_MAX
The maximum value of a 40-bit signed integer (encoded as an int64_t).
Definition: val.h:198
#define CO_UNSIGNED40_MAX
The maximum value of a 40-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:243
#define CO_INTEGER64_MIN
The minimum value of a 64-bit signed integer.
Definition: val.h:222
#define CO_UNSIGNED56_MAX
The maximum value of a 56-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:261
#define CO_INTEGER48_MIN
The minimum value of a 48-bit signed integer (encoded as an int64_t).
Definition: val.h:204
#define CO_UNSIGNED48_MAX
The maximum value of a 48-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:252
#define CO_INTEGER56_MAX
The maximum value of a 56-bit signed integer (encoded as an int64_t).
Definition: val.h:216
#define CO_INTEGER40_MIN
The minimum value of a 40-bit signed integer (encoded as an int64_t).
Definition: val.h:195
#define CO_UNSIGNED24_MAX
The maximum value of a 24-bit unsigned integer (encoded as a uint32_t).
Definition: val.h:234
#define CO_INTEGER16_MIN
The minimum value of a 16-bit signed integer.
Definition: val.h:60
#define CO_INTEGER56_MIN
The minimum value of a 56-bit signed integer (encoded as an int64_t).
Definition: val.h:213
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.
Definition: val.h:90
#define CO_INTEGER8_MAX
The maximum value of an 8-bit signed integer.
Definition: val.h:54