Lely core libraries  1.9.2
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 #include <lely/util/cmp.h>
29 #include <lely/util/diag.h>
30 #include <lely/util/endian.h>
31 #include <lely/util/lex.h>
32 #include <lely/util/print.h>
33 
34 #include <assert.h>
35 #include <inttypes.h>
36 #include <stdlib.h>
37 
38 #define CO_BOOLEAN_INIT 0
39 #define CO_INTEGER8_INIT 0
40 #define CO_INTEGER16_INIT 0
41 #define CO_INTEGER32_INIT 0
42 #define CO_UNSIGNED8_INIT 0
43 #define CO_UNSIGNED16_INIT 0
44 #define CO_UNSIGNED32_INIT 0
45 #define CO_REAL32_INIT 0
46 #define CO_VISIBLE_STRING_INIT NULL
47 #define CO_OCTET_STRING_INIT NULL
48 #define CO_UNICODE_STRING_INIT NULL
49 #define CO_TIME_OF_DAY_INIT \
50  { \
51  0, 0 \
52  }
53 #define CO_TIME_DIFF_INIT CO_TIME_OF_DAY_INIT
54 #define CO_DOMAIN_INIT NULL
55 #define CO_INTEGER24_INIT 0
56 #define CO_REAL64_INIT 0
57 #define CO_INTEGER40_INIT 0
58 #define CO_INTEGER48_INIT 0
59 #define CO_INTEGER56_INIT 0
60 #define CO_INTEGER64_INIT 0
61 #define CO_UNSIGNED24_INIT 0
62 #define CO_UNSIGNED40_INIT 0
63 #define CO_UNSIGNED48_INIT 0
64 #define CO_UNSIGNED56_INIT 0
65 #define CO_UNSIGNED64_INIT 0
66 
67 #define CO_VISIBLE_STRING_MIN NULL
68 #define CO_VISIBLE_STRING_MAX NULL
69 
70 #define CO_OCTET_STRING_MIN NULL
71 #define CO_OCTET_STRING_MAX NULL
72 
73 #define CO_UNICODE_STRING_MIN NULL
74 #define CO_UNICODE_STRING_MAX NULL
75 
76 #define CO_DOMAIN_MIN NULL
77 #define CO_DOMAIN_MAX NULL
78 
79 #define CO_ARRAY_OFFSET ALIGN(sizeof(size_t), _Alignof(union co_val))
80 
81 static int co_array_alloc(void *val, size_t size);
82 static void co_array_free(void *val);
83 static void co_array_init(void *val, size_t size);
84 static void co_array_fini(void *val);
85 
86 static size_t co_array_sizeof(const void *val);
87 
92 static size_t str16len(const char16_t *s);
93 
105 static char16_t *str16ncpy(char16_t *dst, const char16_t *src, size_t n);
106 
117 static int str16ncmp(const char16_t *s1, const char16_t *s2, size_t n);
118 
119 int
120 co_val_init(co_unsigned16_t type, void *val)
121 {
122  union co_val *u = val;
123  assert(u);
124 
125  switch (type) {
126 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
127  case CO_DEFTYPE_##a: \
128  u->c = (co_##b##_t)CO_##a##_INIT; \
129  return 0;
130 #include <lely/co/def/type.def>
131 #undef LELY_CO_DEFINE_TYPE
132  default: set_errnum(ERRNUM_INVAL); return -1;
133  }
134 }
135 
136 int
137 co_val_init_min(co_unsigned16_t type, void *val)
138 {
139  union co_val *u = val;
140  assert(u);
141 
142  switch (type) {
143 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
144  case CO_DEFTYPE_##a: \
145  u->c = (co_##b##_t)CO_##a##_MIN; \
146  return 0;
147 #include <lely/co/def/type.def>
148 #undef LELY_CO_DEFINE_TYPE
149  default: set_errnum(ERRNUM_INVAL); return -1;
150  }
151 }
152 
153 int
154 co_val_init_max(co_unsigned16_t type, void *val)
155 {
156  union co_val *u = val;
157  assert(u);
158 
159  switch (type) {
160 #define LELY_CO_DEFINE_TYPE(a, b, c, d) \
161  case CO_DEFTYPE_##a: \
162  u->c = (co_##b##_t)CO_##a##_MAX; \
163  return 0;
164 #include <lely/co/def/type.def>
165 #undef LELY_CO_DEFINE_TYPE
166  default: set_errnum(ERRNUM_INVAL); return -1;
167  }
168 }
169 
170 int
171 co_val_init_vs(char **val, const char *vs)
172 {
173  assert(val);
174 
175  if (vs)
176  return co_val_init_vs_n(val, vs, strlen(vs));
177 
178  *val = NULL;
179 
180  return 0;
181 }
182 
183 int
184 co_val_init_vs_n(char **val, const char *vs, size_t n)
185 {
186  assert(val);
187 
188  if (n) {
189  if (__unlikely(co_array_alloc(val, n + 1) == -1))
190  return -1;
191  assert(*val);
192  co_array_init(val, n);
193  if (vs)
194  strncpy(*val, vs, n);
195  } else {
196  *val = NULL;
197  }
198 
199  return 0;
200 }
201 
202 int
203 co_val_init_os(uint8_t **val, const uint8_t *os, size_t n)
204 {
205  assert(val);
206 
207  if (n) {
208  if (__unlikely(co_array_alloc(val, n + 1) == -1))
209  return -1;
210  assert(*val);
211  co_array_init(val, n);
212  if (os)
213  memcpy(*val, os, n);
214  } else {
215  *val = NULL;
216  }
217 
218  return 0;
219 }
220 
221 int
222 co_val_init_us(char16_t **val, const char16_t *us)
223 {
224  assert(val);
225 
226  if (us)
227  return co_val_init_us_n(val, us, str16len(us));
228 
229  *val = NULL;
230 
231  return 0;
232 }
233 
234 int
235 co_val_init_us_n(char16_t **val, const char16_t *us, size_t n)
236 {
237  assert(val);
238 
239  if (n) {
240  if (__unlikely(co_array_alloc(val, 2 * (n + 1)) == -1))
241  return -1;
242  assert(*val);
243  co_array_init(val, 2 * n);
244  if (us)
245  str16ncpy(*val, us, n);
246  } else {
247  *val = NULL;
248  }
249 
250  return 0;
251 }
252 
253 int
254 co_val_init_dom(void **val, const void *dom, size_t n)
255 {
256  assert(val);
257 
258  if (n) {
259  if (__unlikely(co_array_alloc(val, n) == -1))
260  return -1;
261  assert(*val);
262  co_array_init(val, n);
263  if (dom)
264  memcpy(*val, dom, n);
265  } else {
266  *val = NULL;
267  }
268 
269  return 0;
270 }
271 
272 void
273 co_val_fini(co_unsigned16_t type, void *val)
274 {
275  assert(val);
276 
277  if (co_type_is_array(type)) {
278  co_array_free(val);
279  co_array_fini(val);
280  }
281 }
282 
283 const void *
284 co_val_addressof(co_unsigned16_t type, const void *val)
285 {
286  if (__unlikely(!val))
287  return NULL;
288 
289  return co_type_is_array(type) ? *(const void **)val : val;
290 }
291 
292 size_t
293 co_val_sizeof(co_unsigned16_t type, const void *val)
294 {
295  if (__unlikely(!val))
296  return 0;
297 
298  // clang-format off
299  return co_type_is_array(type)
300  ? co_array_sizeof(val)
301  : co_type_sizeof(type);
302  // clang-format on
303 }
304 
305 size_t
306 co_val_make(co_unsigned16_t type, void *val, const void *ptr, size_t n)
307 {
308  assert(val);
309 
310  if (!ptr)
311  n = 0;
312 
313  switch (type) {
315  n = ptr ? strlen(ptr) : 0;
316  co_val_init_vs(val, ptr);
317  break;
318  case CO_DEFTYPE_OCTET_STRING: co_val_init_os(val, ptr, n); break;
320  n = ptr ? str16len(ptr) : 0;
321  co_val_init_us(val, ptr);
322  break;
323  case CO_DEFTYPE_DOMAIN: co_val_init_dom(val, ptr, n); break;
324  default:
325  if (__unlikely(!ptr || co_type_sizeof(type) != n))
326  return 0;
327  memcpy(val, ptr, n);
328  }
329  return n;
330 }
331 
332 size_t
333 co_val_copy(co_unsigned16_t type, void *dst, const void *src)
334 {
335  assert(dst);
336  assert(src);
337 
338  size_t n;
339  if (co_type_is_array(type)) {
340  const void *ptr = co_val_addressof(type, src);
341  n = co_val_sizeof(type, src);
342  switch (type) {
344  if (__unlikely(co_val_init_vs(dst, ptr) == -1))
345  return 0;
346  break;
348  if (__unlikely(co_val_init_os(dst, ptr, n) == -1))
349  return 0;
350  break;
352  if (__unlikely(co_val_init_us(dst, ptr) == -1))
353  return 0;
354  break;
355  case CO_DEFTYPE_DOMAIN:
356  if (__unlikely(co_val_init_dom(dst, ptr, n) == -1))
357  return 0;
358  break;
359  default:
360  // We can never get here.
361  return 0;
362  }
363  } else {
364  n = co_type_sizeof(type);
365  memcpy(dst, src, n);
366  }
367  return n;
368 }
369 
370 size_t
371 co_val_move(co_unsigned16_t type, void *dst, void *src)
372 {
373  assert(dst);
374  assert(src);
375 
376  size_t n = co_type_sizeof(type);
377  memcpy(dst, src, n);
378 
379  if (co_type_is_array(type))
380  co_array_fini(src);
381 
382  return n;
383 }
384 
385 int
386 co_val_cmp(co_unsigned16_t type, const void *v1, const void *v2)
387 {
388  if (v1 == v2)
389  return 0;
390 
391  if (__unlikely(!v1))
392  return -1;
393  if (__unlikely(!v2))
394  return 1;
395 
396  int cmp = 0;
397  if (co_type_is_array(type)) {
398  const void *p1 = co_val_addressof(type, v1);
399  const void *p2 = co_val_addressof(type, v2);
400 
401  if (p1 == p2)
402  return 0;
403 
404  if (!p1)
405  return -1;
406  if (!p2)
407  return 1;
408 
409  size_t n1 = co_val_sizeof(type, v1);
410  size_t n2 = co_val_sizeof(type, v2);
411  switch (type) {
413  cmp = strncmp(p1, p2, MIN(n1, n2));
414  break;
416  cmp = memcmp(p1, p2, MIN(n1, n2));
417  break;
419  cmp = str16ncmp(p1, p2, MIN(n1, n2) / 2);
420  break;
421  case CO_DEFTYPE_DOMAIN:
422  cmp = memcmp(p1, p2, MIN(n1, n2));
423  break;
424  default:
425  // We can never get here.
426  return 0;
427  }
428  if (!cmp)
429  cmp = (n1 > n2) - (n1 < n2);
430  return cmp;
431  } else {
432  const union co_val *u1 = v1;
433  const union co_val *u2 = v2;
434  switch (type) {
435  case CO_DEFTYPE_BOOLEAN: return bool_cmp(v1, v2);
436  case CO_DEFTYPE_INTEGER8: return int8_cmp(v1, v2);
437  case CO_DEFTYPE_INTEGER16: return int16_cmp(v1, v2);
438  case CO_DEFTYPE_INTEGER32: return int32_cmp(v1, v2);
439  case CO_DEFTYPE_UNSIGNED8: return uint8_cmp(v1, v2);
440  case CO_DEFTYPE_UNSIGNED16: return uint16_cmp(v1, v2);
441  case CO_DEFTYPE_UNSIGNED32: return uint32_cmp(v1, v2);
442  case CO_DEFTYPE_REAL32: return flt_cmp(v1, v2);
444  cmp = uint32_cmp(&u1->t.ms, &u2->t.ms);
445  if (!cmp)
446  cmp = uint16_cmp(&u1->t.days, &u2->t.days);
447  return cmp;
449  cmp = uint32_cmp(&u1->td.ms, &u2->td.ms);
450  if (!cmp)
451  cmp = uint16_cmp(&u1->td.days, &u2->td.days);
452  return cmp;
453  case CO_DEFTYPE_INTEGER24: return int32_cmp(v1, v2);
454  case CO_DEFTYPE_REAL64: return dbl_cmp(v1, v2);
455  case CO_DEFTYPE_INTEGER40: return int64_cmp(v1, v2);
456  case CO_DEFTYPE_INTEGER48: return int64_cmp(v1, v2);
457  case CO_DEFTYPE_INTEGER56: return int64_cmp(v1, v2);
458  case CO_DEFTYPE_INTEGER64: return int64_cmp(v1, v2);
459  case CO_DEFTYPE_UNSIGNED24: return uint32_cmp(v1, v2);
460  case CO_DEFTYPE_UNSIGNED40: return uint64_cmp(v1, v2);
461  case CO_DEFTYPE_UNSIGNED48: return uint64_cmp(v1, v2);
462  case CO_DEFTYPE_UNSIGNED56: return uint64_cmp(v1, v2);
463  case CO_DEFTYPE_UNSIGNED64: return uint64_cmp(v1, v2);
464  default: return 0;
465  }
466  }
467 }
468 
469 size_t
470 co_val_read(co_unsigned16_t type, void *val, const uint8_t *begin,
471  const uint8_t *end)
472 {
473  assert(begin || begin == end);
474  assert(!end || end >= begin);
475 
476  size_t n = end - begin;
477 
478  if (co_type_is_array(type)) {
479  if (val) {
480  switch (type) {
482  // clang-format off
484  (const char *)begin, n) == -1))
485  // clang-format on
486  return 0;
487  break;
489  // clang-format off
490  if (__unlikely(co_val_init_os(val, begin, n)
491  == -1))
492  // clang-format on
493  return 0;
494  break;
496  // clang-format off
497  if (__unlikely(co_val_init_us_n(val, NULL,
498  n / 2) == -1))
499  // clang-format on
500  return 0;
501  if (n) {
502  char16_t *us = *(char16_t **)val;
503  assert(us);
504  for (size_t i = 0; i + 1 < n; i += 2)
505  us[i / 2] = ldle_u16(begin + i);
506  }
507  break;
508  case CO_DEFTYPE_DOMAIN:
509  // clang-format off
510  if (__unlikely(co_val_init_dom(val, begin, n)
511  == -1))
512  // clang-format on
513  return 0;
514  break;
515  default:
516  // We can never get here.
517  return 0;
518  }
519  }
520  return n;
521  } else {
522  union co_val *u = val;
523  switch (type) {
524  case CO_DEFTYPE_BOOLEAN:
525  if (__unlikely(n < 1))
526  return 0;
527  if (u)
528  u->b = !!*(const co_boolean_t *)begin;
529  return 1;
530  case CO_DEFTYPE_INTEGER8:
531  if (__unlikely(n < 1))
532  return 0;
533  if (u)
534  u->i8 = *(const co_integer8_t *)begin;
535  return 1;
537  if (__unlikely(n < 2))
538  return 0;
539  if (u)
540  u->i16 = ldle_i16(begin);
541  return 2;
543  if (__unlikely(n < 4))
544  return 0;
545  if (u)
546  u->i32 = ldle_i32(begin);
547  return 4;
549  if (__unlikely(n < 1))
550  return 0;
551  if (u)
552  u->u8 = *(const co_unsigned8_t *)begin;
553  return 1;
555  if (__unlikely(n < 2))
556  return 0;
557  if (u)
558  u->u16 = ldle_u16(begin);
559  return 2;
561  if (__unlikely(n < 4))
562  return 0;
563  if (u)
564  u->u32 = ldle_u32(begin);
565  return 4;
566  case CO_DEFTYPE_REAL32:
567  if (__unlikely(n < 4))
568  return 0;
569  if (u)
570  u->r32 = ldle_flt32(begin);
571  return 4;
574  if (__unlikely(n < 6))
575  return 0;
576  if (u) {
577  u->t.ms = ldle_u32(begin)
578  & UINT32_C(0x0fffffff);
579  u->t.days = ldle_u16(begin + 4);
580  }
581  return 6;
583  if (__unlikely(n < 3))
584  return 0;
585  if (u) {
586  co_unsigned24_t u24 = 0;
587  for (size_t i = 0; i < 3; i++)
588  u24 |= (co_unsigned24_t)*begin++
589  << 8 * i;
590  u->i24 = u24 > CO_INTEGER24_MAX
591  ? -(CO_UNSIGNED24_MAX + 1 - u24)
592  : u24;
593  }
594  return 3;
595  case CO_DEFTYPE_REAL64:
596  if (__unlikely(n < 8))
597  return 0;
598  if (u)
599  u->r64 = ldle_flt64(begin);
600  return 8;
602  if (__unlikely(n < 5))
603  return 0;
604  if (u) {
605  co_unsigned40_t u40 = 0;
606  for (size_t i = 0; i < 5; i++)
607  u40 |= (co_unsigned40_t)*begin++
608  << 8 * i;
609  u->i40 = u40 > CO_INTEGER40_MAX
610  ? -(CO_UNSIGNED40_MAX + 1 - u40)
611  : u40;
612  }
613  return 5;
615  if (__unlikely(n < 6))
616  return 0;
617  if (u) {
618  co_unsigned48_t u48 = 0;
619  for (size_t i = 0; i < 6; i++)
620  u48 |= (co_unsigned48_t)*begin++
621  << 8 * i;
622  u->i48 = u48 > CO_INTEGER48_MAX
623  ? -(CO_UNSIGNED48_MAX + 1 - u48)
624  : u48;
625  }
626  return 6;
628  if (__unlikely(n < 7))
629  return 0;
630  if (u) {
631  co_unsigned56_t u56 = 0;
632  for (size_t i = 0; i < 7; i++)
633  u56 |= (co_unsigned56_t)*begin++
634  << 8 * i;
635  u->i56 = u56 > CO_INTEGER56_MAX
636  ? -(CO_UNSIGNED56_MAX + 1 - u56)
637  : u56;
638  }
639  return 7;
641  if (__unlikely(n < 8))
642  return 0;
643  if (u)
644  u->i64 = ldle_i64(begin);
645  return 8;
647  if (__unlikely(n < 3))
648  return 0;
649  if (u) {
650  u->u24 = 0;
651  for (size_t i = 0; i < 3; i++)
652  u->u24 |= (co_unsigned24_t)*begin++
653  << 8 * i;
654  }
655  return 3;
657  if (__unlikely(n < 5))
658  return 0;
659  if (u) {
660  u->u40 = 0;
661  for (size_t i = 0; i < 5; i++)
662  u->u40 |= (co_unsigned40_t)*begin++
663  << 8 * i;
664  }
665  return 5;
667  if (__unlikely(n < 6))
668  return 0;
669  if (u) {
670  u->u48 = 0;
671  for (size_t i = 0; i < 6; i++)
672  u->u48 |= (co_unsigned48_t)*begin++
673  << 8 * i;
674  }
675  return 6;
677  if (__unlikely(n < 7))
678  return 0;
679  if (u) {
680  u->u56 = 0;
681  for (size_t i = 0; i < 7; i++)
682  u->u56 |= (co_unsigned56_t)*begin++
683  << 8 * i;
684  }
685  return 7;
687  if (__unlikely(n < 8))
688  return 0;
689  if (u)
690  u->u64 = ldle_u64(begin);
691  return 8;
692  default: set_errnum(ERRNUM_INVAL); return 0;
693  }
694  }
695 }
696 
697 co_unsigned32_t
698 co_val_read_sdo(co_unsigned16_t type, void *val, const void *ptr, size_t n)
699 {
700  int errc = get_errc();
701  co_unsigned32_t ac = 0;
702 
703  const uint8_t *begin = ptr;
704  const uint8_t *end = begin ? begin + n : NULL;
705  if (__unlikely(n && !co_val_read(type, val, begin, end))) {
706  // clang-format off
707  ac = get_errnum() == ERRNUM_NOMEM
709  : CO_SDO_AC_ERROR;
710  // clang-format on
711  set_errc(errc);
712  }
713 
714  return ac;
715 }
716 
717 size_t
718 co_val_write(co_unsigned16_t type, const void *val, uint8_t *begin,
719  uint8_t *end)
720 {
721  assert(val);
722 
723  if (co_type_is_array(type)) {
724  const void *ptr = co_val_addressof(type, val);
725  size_t n = co_val_sizeof(type, val);
726  if (!ptr || !n)
727  return 0;
728  if (begin && (!end || end - begin >= (ptrdiff_t)n)) {
729  switch (type) {
731  memcpy(begin, ptr, n);
732  break;
734  memcpy(begin, ptr, n);
735  break;
737  const char16_t *us = ptr;
738  for (size_t i = 0; i + 1 < n; i += 2)
739  stle_u16(begin + i, us[i / 2]);
740  break;
741  }
742  case CO_DEFTYPE_DOMAIN: memcpy(begin, ptr, n); break;
743  default:
744  // We can never get here.
745  return 0;
746  }
747  }
748  return n;
749  } else {
750  const union co_val *u = val;
751  switch (type) {
752  case CO_DEFTYPE_BOOLEAN:
753  if (begin && (!end || end - begin >= 1))
754  *(co_boolean_t *)begin = !!u->b;
755  return 1;
756  case CO_DEFTYPE_INTEGER8:
757  if (begin && (!end || end - begin >= 1))
758  *(co_integer8_t *)begin = u->i8;
759  return 1;
761  if (begin && (!end || end - begin >= 2))
762  stle_i16(begin, u->i16);
763  return 2;
765  if (begin && (!end || end - begin >= 4))
766  stle_i32(begin, u->i32);
767  return 4;
769  if (begin && (!end || end - begin >= 1))
770  *(co_unsigned8_t *)begin = u->u8;
771  return 1;
773  if (begin && (!end || end - begin >= 2))
774  stle_u16(begin, u->u16);
775  return 2;
777  if (begin && (!end || end - begin >= 4))
778  stle_u32(begin, u->u32);
779  return 4;
780  case CO_DEFTYPE_REAL32:
781  if (begin && (!end || end - begin >= 4))
782  stle_flt32(begin, u->r32);
783  return 4;
786  if (begin && (!end || end - begin >= 6)) {
787  stle_u32(begin, u->t.ms & UINT32_C(0x0fffffff));
788  stle_u16(begin + 4, u->t.days);
789  }
790  return 6;
792  if (begin && (!end || end - begin >= 3)) {
793  co_unsigned24_t u24 = u->i24 < 0
794  ? CO_UNSIGNED24_MAX + 1 + u->i24
795  : (co_unsigned24_t)u->i24;
796  for (size_t i = 0; i < 3; i++)
797  *begin++ = (u24 >> 8 * i) & 0xff;
798  }
799  return 3;
800  case CO_DEFTYPE_REAL64:
801  if (begin && (!end || end - begin >= 8))
802  stle_flt64(begin, u->r64);
803  return 8;
805  if (begin && (!end || end - begin >= 5)) {
806  co_unsigned40_t u40 = u->i40 < 0
807  ? CO_UNSIGNED40_MAX + 1 + u->i40
808  : (co_unsigned40_t)u->i40;
809  for (size_t i = 0; i < 5; i++)
810  *begin++ = (u40 >> 8 * i) & 0xff;
811  }
812  return 5;
814  if (begin && (!end || end - begin >= 6)) {
815  co_unsigned48_t u48 = u->i48 < 0
816  ? CO_UNSIGNED48_MAX + 1 + u->i48
817  : (co_unsigned48_t)u->i48;
818  for (size_t i = 0; i < 6; i++)
819  *begin++ = (u48 >> 8 * i) & 0xff;
820  }
821  return 6;
823  if (begin && (!end || end - begin >= 7)) {
824  co_unsigned56_t u56 = u->i56 < 0
825  ? CO_UNSIGNED56_MAX + 1 + u->i56
826  : (co_unsigned56_t)u->i56;
827  for (size_t i = 0; i < 7; i++)
828  *begin++ = (u56 >> 8 * i) & 0xff;
829  }
830  return 7;
832  if (begin && (!end || end - begin >= 8))
833  stle_i64(begin, u->i64);
834  return 8;
836  if (begin && (!end || end - begin >= 3)) {
837  for (size_t i = 0; i < 3; i++)
838  *begin++ = (u->u24 >> 8 * i) & 0xff;
839  }
840  return 3;
842  if (begin && (!end || end - begin >= 5)) {
843  for (size_t i = 0; i < 5; i++)
844  *begin++ = (u->u40 >> 8 * i) & 0xff;
845  }
846  return 5;
848  if (begin && (!end || end - begin >= 6)) {
849  for (size_t i = 0; i < 6; i++)
850  *begin++ = (u->u48 >> 8 * i) & 0xff;
851  }
852  return 6;
854  if (begin && (!end || end - begin >= 7)) {
855  for (size_t i = 0; i < 7; i++)
856  *begin++ = (u->u56 >> 8 * i) & 0xff;
857  }
858  return 7;
860  if (begin && (!end || end - begin >= 8))
861  stle_u64(begin, u->u64);
862  return 8;
863  default: set_errnum(ERRNUM_INVAL); return 0;
864  }
865  }
866 }
867 
868 size_t
869 co_val_lex(co_unsigned16_t type, void *val, const char *begin, const char *end,
870  struct floc *at)
871 {
872  assert(begin);
873  assert(!end || end >= begin);
874 
875  // Prevent a previous range error from triggering a spurious warning.
876  if (get_errnum() == ERRNUM_RANGE)
877  set_errnum(0);
878 
879  const char *cp = begin;
880  size_t chars = 0;
881 
882  union co_val u;
883  switch (type) {
884  case CO_DEFTYPE_BOOLEAN:
885  chars = lex_c99_u8(cp, end, NULL, &u.u8);
886  if (chars) {
887  cp += chars;
888  if (__unlikely(u.u8 > CO_BOOLEAN_MAX)) {
889  u.u8 = CO_BOOLEAN_MAX;
892  "boolean truth value overflow");
893  }
894  if (val)
895  *(co_boolean_t *)val = u.u8;
896  }
897  break;
898  case CO_DEFTYPE_INTEGER8:
899  chars = lex_c99_i8(cp, end, NULL, &u.i8);
900  if (chars) {
901  cp += chars;
902  // clang-format off
904  && u.i8 == INT8_MIN))
905  // clang-format on
907  "8-bit signed integer underflow");
908  // clang-format off
909  else if (__unlikely(get_errnum() == ERRNUM_RANGE
910  && u.i8 == INT8_MAX))
911  // clang-format on
913  "8-bit signed integer overflow");
914  if (val)
915  *(co_integer8_t *)val = u.i8;
916  }
917  break;
919  chars = lex_c99_i16(cp, end, NULL, &u.i16);
920  if (chars) {
921  cp += chars;
922  // clang-format off
924  && u.i16 == INT16_MIN))
925  // clang-format on
927  "16-bit signed integer underflow");
928  // clang-format off
929  else if (__unlikely(get_errnum() == ERRNUM_RANGE
930  && u.i16 == INT16_MAX))
931  // clang-format on
933  "16-bit signed integer overflow");
934  if (val)
935  *(co_integer16_t *)val = u.i16;
936  }
937  break;
939  chars = lex_c99_i32(cp, end, NULL, &u.i32);
940  if (chars) {
941  cp += chars;
942  // clang-format off
944  && u.i32 == INT32_MIN))
945  // clang-format on
947  "32-bit signed integer underflow");
948  // clang-format off
949  else if (__unlikely(get_errnum() == ERRNUM_RANGE
950  && u.i32 == INT32_MAX))
951  // clang-format on
953  "32-bit signed integer overflow");
954  if (val)
955  *(co_integer32_t *)val = u.i32;
956  }
957  break;
959  chars = lex_c99_u8(cp, end, NULL, &u.u8);
960  if (chars) {
961  cp += chars;
962  // clang-format off
964  && u.u8 == UINT8_MAX))
965  // clang-format on
967  "8-bit unsigned integer overflow");
968  if (val)
969  *(co_unsigned8_t *)val = u.u8;
970  }
971  break;
973  chars = lex_c99_u16(cp, end, NULL, &u.u16);
974  if (chars) {
975  cp += chars;
976  // clang-format off
978  && u.u16 == UINT16_MAX))
979  // clang-format on
981  "16-bit unsigned integer overflow");
982  if (val)
983  *(co_unsigned16_t *)val = u.u16;
984  }
985  break;
987  chars = lex_c99_u32(cp, end, NULL, &u.u32);
988  if (chars) {
989  cp += chars;
990  // clang-format off
992  && u.u32 == UINT32_MAX))
993  // clang-format on
995  "32-bit unsigned integer overflow");
996  if (val)
997  *(co_unsigned32_t *)val = u.u32;
998  }
999  break;
1000  case CO_DEFTYPE_REAL32:
1001  chars = lex_c99_u32(cp, end, NULL, &u.u32);
1002  if (chars) {
1003  cp += chars;
1004  // clang-format off
1006  && u.u32 == UINT32_MAX))
1007  // clang-format on
1008  diag_if(DIAG_WARNING, get_errc(), at,
1009  "32-bit unsigned integer overflow");
1010  // clang-format off
1011  u.r32 = ((union {
1012  uint32_t u32;
1013  co_real32_t r32;
1014  }){ u.u32 }).r32;
1015  // clang-format on
1016  if (val)
1017  *(co_real32_t *)val = u.r32;
1018  }
1019  break;
1021  size_t n = 0;
1022  chars = lex_c99_str(cp, end, NULL, NULL, &n);
1023  if (val) {
1024  if (__unlikely(co_val_init_vs_n(val, 0, n) == -1)) {
1025  diag_if(DIAG_ERROR, get_errc(), at,
1026  "unable to create value of type VISIBLE_STRING");
1027  return 0;
1028  }
1029  // Parse the characters.
1030  char *vs = *(void **)val;
1031  assert(vs);
1032  lex_c99_str(cp, end, NULL, vs, &n);
1033  }
1034  cp += chars;
1035  break;
1036  }
1037  case CO_DEFTYPE_OCTET_STRING: {
1038  // Count the number of hexadecimal digits.
1039  while ((!end || cp + chars < end)
1040  && isxdigit((unsigned char)cp[chars]))
1041  chars++;
1042  if (val) {
1043  // clang-format off
1044  if (__unlikely(co_val_init_os(val, NULL,
1045  (chars + 1) / 2) == -1)) {
1046  // clang-format on
1047  diag_if(DIAG_ERROR, get_errc(), at,
1048  "unable to create value of type OCTET_STRING");
1049  return 0;
1050  }
1051  // Parse the octets.
1052  uint8_t *os = *(void **)val;
1053  assert(os);
1054  for (size_t i = 0; i < chars; i++) {
1055  if (i % 2) {
1056  *os <<= 4;
1057  *os++ |= ctox(cp[i]) & 0xf;
1058  } else {
1059  *os = ctox(cp[i]) & 0xf;
1060  }
1061  }
1062  }
1063  cp += chars;
1064  break;
1065  }
1067  size_t n = 0;
1068  chars = lex_base64(cp, end, NULL, NULL, &n);
1069  if (val) {
1070  // clang-format off
1071  if (__unlikely(co_val_init_us_n(val, NULL, n / 2)
1072  == -1)) {
1073  // clang-format on
1074  diag_if(DIAG_ERROR, get_errc(), at,
1075  "unable to create value of type UNICODE_STRING");
1076  return 0;
1077  }
1078  // Parse the Unicode characters.
1079  char16_t *us = *(void **)val;
1080  assert(us);
1081  lex_base64(cp, end, NULL, us, &n);
1082  for (size_t i = 0; i + 1 < n; i += 2)
1083  us[i / 2] = letoh16(us[i / 2]);
1084  }
1085  cp += chars;
1086  break;
1087  }
1089  case CO_DEFTYPE_TIME_DIFF:
1090  chars = lex_c99_u16(cp, end, NULL, &u.t.days);
1091  if (__unlikely(!chars))
1092  return 0;
1093  cp += chars;
1094  cp += lex_ctype(&isblank, cp, end, NULL);
1095  chars = lex_c99_u32(cp, end, NULL, &u.t.ms);
1096  if (__unlikely(!chars))
1097  return 0;
1098  cp += chars;
1099  if (val)
1100  *(co_time_of_day_t *)val = u.t;
1101  break;
1102  case CO_DEFTYPE_DOMAIN: {
1103  size_t n = 0;
1104  chars = lex_base64(cp, end, NULL, NULL, &n);
1105  if (val) {
1106  if (__unlikely(co_val_init_dom(val, NULL, n) == -1)) {
1107  diag_if(DIAG_ERROR, get_errc(), at,
1108  "unable to create value of type DOMAIN");
1109  return 0;
1110  }
1111  void *dom = *(void **)val;
1112  assert(!n || dom);
1113  lex_base64(cp, end, NULL, dom, &n);
1114  }
1115  cp += chars;
1116  break;
1117  }
1118  case CO_DEFTYPE_INTEGER24:
1119  chars = lex_c99_i32(cp, end, NULL, &u.i32);
1120  if (chars) {
1121  cp += chars;
1122  if (__unlikely(u.i32 < CO_INTEGER24_MIN)) {
1123  u.i32 = CO_INTEGER24_MIN;
1125  diag_if(DIAG_WARNING, get_errc(), at,
1126  "24-bit signed integer underflow");
1127  } else if (__unlikely(u.i32 > CO_INTEGER24_MAX)) {
1128  u.i32 = CO_INTEGER24_MAX;
1130  diag_if(DIAG_WARNING, get_errc(), at,
1131  "24-bit signed integer overflow");
1132  }
1133  if (val)
1134  *(co_integer24_t *)val = u.i32;
1135  }
1136  break;
1137  case CO_DEFTYPE_REAL64:
1138  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1139  if (chars) {
1140  cp += chars;
1141  // clang-format off
1143  && u.u64 == UINT64_MAX))
1144  // clang-format on
1145  diag_if(DIAG_WARNING, get_errc(), at,
1146  "64-bit unsigned integer overflow");
1147  // clang-format off
1148  u.r64 = ((union {
1149  uint64_t u64;
1150  co_real64_t r64;
1151  }){ u.u64 }).r64;
1152  // clang-format on
1153  if (val)
1154  *(co_real64_t *)val = u.r64;
1155  }
1156  break;
1157  case CO_DEFTYPE_INTEGER40:
1158  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1159  if (chars) {
1160  cp += chars;
1161  if (__unlikely(u.i64 < CO_INTEGER40_MIN)) {
1162  u.i64 = CO_INTEGER40_MIN;
1164  diag_if(DIAG_WARNING, get_errc(), at,
1165  "40-bit signed integer underflow");
1166  } else if (__unlikely(u.i64 > CO_INTEGER40_MAX)) {
1167  u.i64 = CO_INTEGER40_MAX;
1169  diag_if(DIAG_WARNING, get_errc(), at,
1170  "40-bit signed integer overflow");
1171  }
1172  if (val)
1173  *(co_integer40_t *)val = u.i64;
1174  }
1175  break;
1176  case CO_DEFTYPE_INTEGER48:
1177  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1178  if (chars) {
1179  cp += chars;
1180  if (__unlikely(u.i64 < CO_INTEGER48_MIN)) {
1181  u.i64 = CO_INTEGER48_MIN;
1183  diag_if(DIAG_WARNING, get_errc(), at,
1184  "48-bit signed integer underflow");
1185  } else if (__unlikely(u.i64 > CO_INTEGER48_MAX)) {
1186  u.i64 = CO_INTEGER48_MAX;
1188  diag_if(DIAG_WARNING, get_errc(), at,
1189  "48-bit signed integer overflow");
1190  }
1191  if (val)
1192  *(co_integer48_t *)val = u.i64;
1193  }
1194  break;
1195  case CO_DEFTYPE_INTEGER56:
1196  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1197  if (chars) {
1198  cp += chars;
1199  if (__unlikely(u.i64 < CO_INTEGER56_MIN)) {
1200  u.i64 = CO_INTEGER56_MIN;
1202  diag_if(DIAG_WARNING, get_errc(), at,
1203  "56-bit signed integer underflow");
1204  } else if (__unlikely(u.i64 > CO_INTEGER56_MAX)) {
1205  u.i64 = CO_INTEGER56_MAX;
1207  diag_if(DIAG_WARNING, get_errc(), at,
1208  "56-bit signed integer overflow");
1209  }
1210  if (val)
1211  *(co_integer56_t *)val = u.i64;
1212  }
1213  break;
1214  case CO_DEFTYPE_INTEGER64:
1215  chars = lex_c99_i64(cp, end, NULL, &u.i64);
1216  if (chars) {
1217  cp += chars;
1218  // clang-format off
1220  && u.i64 == INT64_MIN))
1221  // clang-format on
1222  diag_if(DIAG_WARNING, get_errc(), at,
1223  "64-bit signed integer underflow");
1224  // clang-format off
1225  else if (__unlikely(get_errnum() == ERRNUM_RANGE
1226  && u.i64 == INT64_MAX))
1227  // clang-format on
1228  diag_if(DIAG_WARNING, get_errc(), at,
1229  "64-bit signed integer overflow");
1230  if (val)
1231  *(co_integer64_t *)val = u.i64;
1232  }
1233  break;
1234  case CO_DEFTYPE_UNSIGNED24:
1235  chars = lex_c99_u32(cp, end, NULL, &u.u32);
1236  if (chars) {
1237  cp += chars;
1238  if (__unlikely(u.u32 > CO_UNSIGNED24_MAX)) {
1239  u.u32 = CO_UNSIGNED24_MAX;
1241  diag_if(DIAG_WARNING, get_errc(), at,
1242  "24-bit unsigned integer overflow");
1243  }
1244  if (val)
1245  *(co_unsigned24_t *)val = u.u32;
1246  }
1247  break;
1248  case CO_DEFTYPE_UNSIGNED40:
1249  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1250  if (chars) {
1251  cp += chars;
1252  if (__unlikely(u.u64 > CO_UNSIGNED40_MAX)) {
1253  u.u64 = CO_UNSIGNED40_MAX;
1255  diag_if(DIAG_WARNING, get_errc(), at,
1256  "40-bit unsigned integer overflow");
1257  }
1258  if (val)
1259  *(co_unsigned40_t *)val = u.u64;
1260  }
1261  break;
1262  case CO_DEFTYPE_UNSIGNED48:
1263  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1264  if (chars) {
1265  cp += chars;
1266  if (__unlikely(u.u64 > CO_UNSIGNED48_MAX)) {
1267  u.u64 = CO_UNSIGNED48_MAX;
1269  diag_if(DIAG_WARNING, get_errc(), at,
1270  "48-bit unsigned integer overflow");
1271  }
1272  if (val)
1273  *(co_unsigned48_t *)val = u.u64;
1274  }
1275  break;
1276  case CO_DEFTYPE_UNSIGNED56:
1277  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1278  if (chars) {
1279  cp += chars;
1280  if (__unlikely(u.u64 > CO_UNSIGNED56_MAX)) {
1281  u.u64 = CO_UNSIGNED56_MAX;
1283  diag_if(DIAG_WARNING, get_errc(), at,
1284  "56-bit unsigned integer overflow");
1285  }
1286  if (val)
1287  *(co_unsigned56_t *)val = u.u64;
1288  }
1289  break;
1290  case CO_DEFTYPE_UNSIGNED64:
1291  chars = lex_c99_u64(cp, end, NULL, &u.u64);
1292  if (chars) {
1293  cp += chars;
1294  // clang-format off
1296  && u.u64 == UINT64_MAX))
1297  // clang-format on
1298  diag_if(DIAG_WARNING, get_errc(), at,
1299  "64-bit unsigned integer overflow");
1300  if (val)
1301  *(co_unsigned64_t *)val = u.u64;
1302  }
1303  break;
1304  default:
1305  diag_if(DIAG_ERROR, 0, at, "cannot parse value of type 0x%04X",
1306  type);
1307  break;
1308  }
1309 
1310  return floc_lex(at, begin, cp);
1311 }
1312 
1313 size_t
1314 co_val_print(co_unsigned16_t type, const void *val, char **pbegin, char *end)
1315 {
1316  if (co_type_is_array(type)) {
1317  const void *ptr = co_val_addressof(type, val);
1318  size_t n = co_val_sizeof(type, val);
1319  if (!ptr || !n)
1320  return 0;
1321  switch (type) {
1323  return print_c99_str(pbegin, end, ptr, n);
1324  case CO_DEFTYPE_OCTET_STRING: {
1325  size_t chars = 0;
1326  for (const uint8_t *os = ptr; n; n--, os++) {
1327  chars += print_char(
1328  pbegin, end, xtoc(*os >> 4));
1329  chars += print_char(pbegin, end, xtoc(*os));
1330  }
1331  return chars;
1332  }
1334  char16_t *us = NULL;
1335  if (__unlikely(!co_val_copy(type, &us, val) && !us))
1336  return 0;
1337  assert(us);
1338  for (size_t i = 0; i + 1 < n; i += 2)
1339  us[i / 2] = htole16(us[i / 2]);
1340  size_t chars = print_base64(pbegin, end, us, n);
1341  co_array_free(&us);
1342  return chars;
1343  }
1344  case CO_DEFTYPE_DOMAIN:
1345  return print_base64(pbegin, end, ptr, n);
1346  default:
1347  // We can never get here.
1348  return 0;
1349  }
1350  } else {
1351  const union co_val *u = val;
1352  assert(u);
1353  switch (type) {
1354  case CO_DEFTYPE_BOOLEAN:
1355  return print_c99_u8(pbegin, end, !!u->b);
1356  case CO_DEFTYPE_INTEGER8:
1357  return print_c99_i8(pbegin, end, u->i8);
1358  case CO_DEFTYPE_INTEGER16:
1359  return print_c99_i16(pbegin, end, u->i16);
1360  case CO_DEFTYPE_INTEGER32:
1361  return print_c99_i32(pbegin, end, u->i32);
1362  case CO_DEFTYPE_UNSIGNED8:
1363  return print_fmt(pbegin, end, "0x%02" PRIx8, u->u8);
1364  case CO_DEFTYPE_UNSIGNED16:
1365  return print_fmt(pbegin, end, "0x%04" PRIx16, u->u16);
1366  case CO_DEFTYPE_UNSIGNED32:
1367  return print_fmt(pbegin, end, "0x%08" PRIx32, u->u32);
1368  case CO_DEFTYPE_REAL32:
1369  return print_c99_u32(pbegin, end, u->u32);
1371  case CO_DEFTYPE_TIME_DIFF: {
1372  size_t chars = 0;
1373  chars += print_c99_u16(pbegin, end, u->t.days);
1374  chars += print_char(pbegin, end, ' ');
1375  chars += print_c99_u32(pbegin, end, u->t.ms);
1376  return chars;
1377  }
1378  case CO_DEFTYPE_INTEGER24:
1379  return print_c99_i32(pbegin, end, u->i24);
1380  case CO_DEFTYPE_REAL64:
1381  return print_fmt(pbegin, end, "0x%016" PRIx64, u->u64);
1382  case CO_DEFTYPE_INTEGER40:
1383  return print_c99_i64(pbegin, end, u->i40);
1384  case CO_DEFTYPE_INTEGER48:
1385  return print_c99_i64(pbegin, end, u->i48);
1386  case CO_DEFTYPE_INTEGER56:
1387  return print_c99_i64(pbegin, end, u->i56);
1388  case CO_DEFTYPE_INTEGER64:
1389  return print_c99_i64(pbegin, end, u->i64);
1390  case CO_DEFTYPE_UNSIGNED24:
1391  return print_fmt(pbegin, end, "0x%06" PRIx32, u->u24);
1392  case CO_DEFTYPE_UNSIGNED40:
1393  return print_fmt(pbegin, end, "0x%010" PRIx64, u->u40);
1394  case CO_DEFTYPE_UNSIGNED48:
1395  return print_fmt(pbegin, end, "0x%012" PRIx64, u->u48);
1396  case CO_DEFTYPE_UNSIGNED56:
1397  return print_fmt(pbegin, end, "0x%014" PRIx64, u->u56);
1398  case CO_DEFTYPE_UNSIGNED64:
1399  return print_fmt(pbegin, end, "0x%016" PRIx64, u->u64);
1400  default: set_errnum(ERRNUM_INVAL); return 0;
1401  }
1402  }
1403 }
1404 
1405 static int
1406 co_array_alloc(void *val, size_t size)
1407 {
1408  assert(val);
1409 
1410  if (size) {
1411  char *ptr = calloc(1, CO_ARRAY_OFFSET + size);
1412  if (__unlikely(!ptr)) {
1413  set_errc(errno2c(errno));
1414  return -1;
1415  }
1416  *(char **)val = ptr + CO_ARRAY_OFFSET;
1417  } else {
1418  *(char **)val = NULL;
1419  }
1420 
1421  return 0;
1422 }
1423 
1424 static void
1425 co_array_free(void *val)
1426 {
1427  assert(val);
1428 
1429  char *ptr = *(char **)val;
1430  if (ptr)
1431  free(ptr - CO_ARRAY_OFFSET);
1432 }
1433 
1434 static void
1435 co_array_init(void *val, size_t size)
1436 {
1437  assert(val);
1438 
1439  char *ptr = *(char **)val;
1440  assert(!size || ptr);
1441  if (ptr)
1442  *(size_t *)(ptr - CO_ARRAY_OFFSET) = size;
1443 }
1444 
1445 static void
1446 co_array_fini(void *val)
1447 {
1448  assert(val);
1449 
1450  *(char **)val = NULL;
1451 }
1452 
1453 static size_t
1454 co_array_sizeof(const void *val)
1455 {
1456  assert(val);
1457 
1458  const char *ptr = *(const char **)val;
1459  return ptr ? *(const size_t *)(ptr - CO_ARRAY_OFFSET) : 0;
1460 }
1461 
1462 static size_t
1463 str16len(const char16_t *s)
1464 {
1465  const char16_t *cp = s;
1466  for (; *cp; cp++)
1467  ;
1468  return cp - s;
1469 }
1470 
1471 static char16_t *
1472 str16ncpy(char16_t *dst, const char16_t *src, size_t n)
1473 {
1474  char16_t *cp = dst;
1475  for (; n && *src; n--)
1476  *cp++ = *src++;
1477  while (n--)
1478  *cp++ = 0;
1479 
1480  return dst;
1481 }
1482 
1483 static int
1484 str16ncmp(const char16_t *s1, const char16_t *s2, size_t n)
1485 {
1486  int result = 0;
1487  while (n-- && !(result = *s1 - *s2++) && *s1++)
1488  ;
1489  return result;
1490 }
uint_least16_t htole16(uint_least16_t x)
Converts a 16-bit unsigned integer from host to little-endian byte order.
Definition: endian.h:337
void stle_u32(void *ptr, uint_least32_t x)
Stores a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:534
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:501
#define CO_INTEGER56_MAX
The maximum value of a 56-bit signed integer (encoded as an int64_t).
Definition: val.h:124
size_t co_type_sizeof(co_unsigned16_t type)
Returns the native size (in bytes) of a value of the specified data type, or 0 if it is not a static ...
Definition: type.c:52
#define CO_DEFTYPE_UNSIGNED56
The data type (and object index) of a 56-bit unsigned integer.
Definition: type.h:107
void stle_u64(void *ptr, uint_least64_t x)
Stores a 64-bit unsigned integer in little-endian byte order.
Definition: endian.h:588
Result too large.
Definition: errnum.h:215
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:421
#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 <string.h> and defines any missing functionality.
#define CO_INTEGER48_MAX
The maximum value of a 48-bit signed integer (encoded as an int64_t).
Definition: val.h:118
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:222
#define CO_DEFTYPE_VISIBLE_STRING
The data type (and object index) of an array of visible characters.
Definition: type.h:56
uint_least64_t ldle_u64(const void *ptr)
Loads a 64-bit unsigned integer in little-endian byte order.
Definition: endian.h:595
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
Definition: type.h:77
A location in a text file.
Definition: diag.h:31
This header file is part of the utilities library; it contains the comparison function definitions...
int co_val_init_vs(char **val, const char *vs)
Initializes an array of visible characters (CO_DEFTYPE_VISIBLE_STRING).
Definition: val.c:171
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:469
#define CO_DEFTYPE_INTEGER24
The data type (and object index) of a 24-bit signed integer.
Definition: type.h:80
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
int_least32_t ldle_i32(const void *ptr)
Loads a 32-bit signed integer in little-endian byte order.
Definition: endian.h:528
A union of the CANopen static data types.
Definition: val.h:163
#define CO_DEFTYPE_INTEGER48
The data type (and object index) of a 48-bit signed integer.
Definition: type.h:89
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:386
uint_least16_t ldle_u16(const void *ptr)
Loads a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:487
#define CO_SDO_AC_ERROR
SDO abort code: General error.
Definition: sdo.h:150
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:235
#define CO_DEFTYPE_UNSIGNED48
The data type (and object index) of a 48-bit unsigned integer.
Definition: type.h:104
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
size_t co_val_copy(co_unsigned16_t type, void *dst, const void *src)
Copies one value to another.
Definition: val.c:333
#define CO_UNSIGNED56_MAX
The maximum value of a 56-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:154
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
static size_t str16len(const char16_t *s)
Returns the number of (16-bit) Unicode characters, excluding the terminating null bytes...
Definition: val.c:1463
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
size_t co_val_write(co_unsigned16_t type, const void *val, uint8_t *begin, uint8_t *end)
Writes a value of the specified data type to a memory buffer.
Definition: val.c:718
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:601
This header file is part of the CANopen library; it contains the CANopen value declarations.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:957
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:247
#define CO_INTEGER40_MAX
The maximum value of a 40-bit signed integer (encoded as an int64_t).
Definition: val.h:112
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:51
size_t co_val_read(co_unsigned16_t type, void *val, const uint8_t *begin, const uint8_t *end)
Reads a value of the specified data type from a memory buffer.
Definition: val.c:470
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
Definition: type.h:50
#define CO_DEFTYPE_UNSIGNED24
The data type (and object index) of a 24-bit unsigned integer.
Definition: type.h:98
size_t co_val_move(co_unsigned16_t type, void *dst, void *src)
Moves one value to another.
Definition: val.c:371
#define CO_DEFTYPE_INTEGER64
The data type (and object index) of a 64-bit signed integer.
Definition: type.h:95
#define CO_UNSIGNED24_MAX
The maximum value of a 24-bit unsigned integer (encoded as a uint32_t).
Definition: val.h:136
#define CO_DEFTYPE_REAL32
The data type (and object index) of a 32-bit IEEE-754 floating-point number.
Definition: type.h:53
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:1314
#define CO_DEFTYPE_INTEGER8
The data type (and object index) of an 8-bit signed integer.
Definition: type.h:35
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
Definition: type.h:47
This header file is part of the utilities library; it contains the byte order (endianness) function d...
This is the internal header file of the CANopen library.
void stle_i32(void *ptr, int_least32_t x)
Stores a 32-bit signed integer in little-endian byte order.
Definition: endian.h:522
#define CO_INTEGER40_MIN
The minimum value of a 40-bit signed integer (encoded as an int64_t).
Definition: val.h:109
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:445
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:190
#define CO_DEFTYPE_UNICODE_STRING
The data type (and object index) of an array of (16-bit) Unicode characters.
Definition: type.h:62
This header file is part of the utilities library; it contains the lexer function declarations...
#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
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
Definition: errnum.c:947
void stle_i16(void *ptr, int_least16_t x)
Stores a 16-bit signed integer in little-endian byte order.
Definition: endian.h:468
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:254
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:54
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
Definition: type.h:44
#define CO_DEFTYPE_UNSIGNED40
The data type (and object index) of a 40-bit unsigned integer.
Definition: type.h:101
An error.
Definition: diag.h:49
Invalid argument.
Definition: errnum.h:129
void stle_u16(void *ptr, uint_least16_t x)
Stores a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:480
int co_val_init(co_unsigned16_t type, void *val)
Initializes a value of the specified data type to zero.
Definition: val.c:120
#define CO_UNSIGNED48_MAX
The maximum value of a 48-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:148
#define CO_INTEGER48_MIN
The minimum value of a 48-bit signed integer (encoded as an int64_t).
Definition: val.h:115
int co_val_init_os(uint8_t **val, const uint8_t *os, size_t n)
Initializes an array of octets (CO_DEFTYPE_OCTET_STRING).
Definition: val.c:203
#define CO_INTEGER24_MIN
The minimum value of a 24-bit signed integer (encoded as an int32_t).
Definition: val.h:97
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:540
static int str16ncmp(const char16_t *s1, const char16_t *s2, size_t n)
Compares two (16-bit) Unicode strings.
Definition: val.c:1484
#define CO_DEFTYPE_INTEGER16
The data type (and object index) of a 16-bit signed integer.
Definition: type.h:38
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:43
This header file is part of the utilities library; it contains the diagnostic declarations.
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
Definition: features.h:286
#define CO_DEFTYPE_INTEGER56
The data type (and object index) of a 56-bit signed integer.
Definition: type.h:92
#define CO_INTEGER56_MIN
The minimum value of a 56-bit signed integer (encoded as an int64_t).
Definition: val.h:121
#define CO_UNSIGNED40_MAX
The maximum value of a 40-bit unsigned integer (encoded as a uint64_t).
Definition: val.h:142
int_least16_t ldle_i16(const void *ptr)
Loads a 16-bit signed integer in little-endian byte order.
Definition: endian.h:474
#define CO_DEFTYPE_OCTET_STRING
The data type (and object index) of an array of octets.
Definition: type.h:59
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
Definition: val.c:273
uint_least16_t letoh16(uint_least16_t x)
Converts a 16-bit unsigned integer from little-endian to host byte order.
Definition: endian.h:350
#define CO_INTEGER24_MAX
The maximum value of a 24-bit signed integer (encoded as an int32_t).
Definition: val.h:100
#define CO_DEFTYPE_UNSIGNED64
The data type (and object index) of a 64-bit unsigned integer.
Definition: type.h:110
A warning.
Definition: diag.h:47
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:284
static char16_t * str16ncpy(char16_t *dst, const char16_t *src, size_t n)
Copies at most n (16-bit) Unicode characters from the string at src to dst.
Definition: val.c:1472
#define CO_SDO_AC_NO_MEM
SDO abort code: Out of memory.
Definition: sdo.h:81
errnum_t get_errnum(void)
Returns the last (thread-specific) platform-independent error number set by a system call or library ...
Definition: errnum.h:369
#define CO_DEFTYPE_REAL64
The data type (and object index) of a 64-bit IEEE-754 floating-point number.
Definition: type.h:83
Not enough space.
Definition: errnum.h:169
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:306
void stle_i64(void *ptr, int_least64_t x)
Stores a 64-bit signed integer in little-endian byte order.
Definition: endian.h:576
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:293
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:578
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
#define CO_DEFTYPE_INTEGER32
The data type (and object index) of a 32-bit signed integer.
Definition: type.h:41
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:559
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:154
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:869
#define CO_DEFTYPE_INTEGER40
The data type (and object index) of a 40-bit signed integer.
Definition: type.h:86
int ctox(int c)
Returns the hexadecimal digit corresponding to the character c.
Definition: lex.h:390
size_t lex_base64(const char *begin, const char *end, struct floc *at, void *ptr, size_t *pn)
Lexwes and decodes the Base64 representation of binary data from a memory buffer. ...
Definition: lex.c:652
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:184
int_least64_t ldle_i64(const void *ptr)
Loads a 64-bit signed integer in little-endian byte order.
Definition: endian.h:582
uint_least32_t ldle_u32(const void *ptr)
Loads a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:541
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:137
#define CO_BOOLEAN_MAX
The maximum value of a boolean truth value (true).
Definition: val.h:34
#define CO_DEFTYPE_BOOLEAN
The data type (and object index) of a boolean truth value.
Definition: type.h:32
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:698