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