Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-memdesc.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2016 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <errno.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <limits.h>
26 #include <sol-common-buildopts.h>
27 #include <sol-str-slice.h>
28 #include <sol-str-table.h>
29 #include <sol-macros.h>
30 #include <sol-buffer.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
55 struct sol_memdesc;
56 
261 };
262 
269 enum sol_memdesc_type sol_memdesc_type_from_str(const char *str)
270 #ifndef DOXYGEN_RUN
272 #endif
273  ;
274 
282 #ifndef DOXYGEN_RUN
283  SOL_ATTR_WARN_UNUSED_RESULT
284 #endif
285  ;
286 
293 #ifndef SOL_MEMDESC_DESCRIPTION
294 /* keep doxygen happy */
295 #define SOL_MEMDESC_DESCRIPTION
296 #undef SOL_MEMDESC_DESCRIPTION
297 #endif
298 
307 #ifdef SOL_MEMDESC_DESCRIPTION
308 #define SOL_MEMDESC_SET_DESCRIPTION(...) __VA_ARGS__
309 #else
310 #define SOL_MEMDESC_SET_DESCRIPTION(...)
311 #endif
312 
313 #ifndef SOL_NO_API_VERSION
314 
322 extern const uint16_t SOL_MEMDESC_API_VERSION_COMPILED;
323 #endif
324 
334 typedef struct sol_memdesc_ops_array {
335 #ifndef SOL_NO_API_VERSION
336 #define SOL_MEMDESC_OPS_ARRAY_API_VERSION (1)
337  uint16_t api_version;
338 #endif
339 
352  ssize_t (*get_length)(const struct sol_memdesc *desc, const void *memory);
363  void *(*get_element)(const struct sol_memdesc *desc, const void *memory, size_t idx);
381  int (*resize)(const struct sol_memdesc *desc, void *memory, size_t length);
383 
394 #ifndef SOL_NO_API_VERSION
395 #define SOL_MEMDESC_OPS_ENUMERATION_API_VERSION (1)
396  uint16_t api_version;
397 #endif
398 
405  const char *(*to_str)(const struct sol_memdesc *desc, const void *memory);
419  int (*from_str)(const struct sol_memdesc *desc, void *ptr_return, const struct sol_str_slice str);
421 
435 typedef struct sol_memdesc_ops {
436 #ifndef SOL_NO_API_VERSION
437 #define SOL_MEMDESC_OPS_API_VERSION (1)
438  uint16_t api_version;
439 #endif
440 
450  int (*init_defaults)(const struct sol_memdesc *desc, void *memory);
467  int (*set_content)(const struct sol_memdesc *desc, void *memory, const void *ptr_content);
479  int (*copy)(const struct sol_memdesc *desc, const void *src_memory, void *dst_memory);
492  int (*compare)(const struct sol_memdesc *desc, const void *a_memory, const void *b_memory);
504  int (*free_content)(const struct sol_memdesc *desc, void *memory);
505  union {
508  };
510 
514 typedef struct sol_memdesc {
515 #ifndef SOL_NO_API_VERSION
516 #define SOL_MEMDESC_API_VERSION (1)
517  uint16_t api_version;
518 #endif
519 
528  uint16_t size;
551  union {
552  uint8_t u8;
553  uint16_t u16;
554  uint32_t u32;
555  uint64_t u64;
556  unsigned long ul;
557  size_t sz;
558  int8_t i8;
559  int16_t i16;
560  int32_t i32;
561  int64_t i64;
562  long l;
563  ssize_t ssz;
564  bool b;
565  double d;
566  int64_t e;
567  const char *s;
568  const void *p;
569  } defcontent;
576  union {
582  const struct sol_memdesc *pointed_item;
588  const struct sol_memdesc *array_item;
604  };
605 
611  const struct sol_memdesc_ops *ops;
612 } sol_memdesc;
613 
630  const char *name;
631 #ifdef SOL_MEMDESC_DESCRIPTION
632 
641  const char *description;
642 #endif
643 
650  uint16_t offset;
657  bool optional : 1;
664  bool detail : 1;
666 
674 extern const struct sol_memdesc_ops SOL_MEMDESC_OPS_VECTOR;
682 extern const struct sol_memdesc_ops SOL_MEMDESC_OPS_PTR_VECTOR;
683 
696 static inline uint16_t
698 {
699  errno = EINVAL;
700  if (!desc)
701  return 0;
702 
703 #ifndef SOL_NO_API_VERSION
704  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
705  return 0;
706 #endif
707 
708  errno = 0;
709  switch (desc->type) {
711  return sizeof(uint8_t);
713  return sizeof(uint16_t);
715  return sizeof(uint32_t);
717  return sizeof(uint64_t);
719  return sizeof(unsigned long);
721  return sizeof(size_t);
723  return sizeof(int8_t);
725  return sizeof(int16_t);
727  return sizeof(int32_t);
729  return sizeof(int64_t);
731  return sizeof(long);
733  return sizeof(ssize_t);
735  return sizeof(bool);
737  return sizeof(double);
739  return sizeof(char *);
741  return sizeof(const char *);
743  return sizeof(void *);
747  if (desc->size)
748  return desc->size;
749 
750  /* must provide size */
751  default:
752  errno = EINVAL;
753  return 0;
754  }
755 }
756 
771 int sol_memdesc_init_defaults(const struct sol_memdesc *desc, void *memory);
772 
788 int sol_memdesc_copy(const struct sol_memdesc *desc, const void *src_memory, void *dst_memory);
789 
805 int sol_memdesc_set_content(const struct sol_memdesc *desc, void *memory, const void *ptr_content);
806 
831 int sol_memdesc_compare(const struct sol_memdesc *desc, const void *a_memory, const void *b_memory);
832 
846 int sol_memdesc_free_content(const struct sol_memdesc *desc, void *memory);
847 
856 static inline void
857 sol_memdesc_free(const struct sol_memdesc *desc, void *memory)
858 {
859  sol_memdesc_free_content(desc, memory);
860  free(memory);
861 }
862 
876 static inline void *
878 {
879  void *mem;
880  uint16_t size;
881  int r;
882 
883  size = sol_memdesc_get_size(desc);
884  if (!size)
885  return NULL;
886 
887  mem = malloc(size);
888  if (!mem)
889  return NULL;
890 
891  r = sol_memdesc_init_defaults(desc, mem);
892  if (r < 0) {
893  sol_memdesc_free(desc, mem);
894  errno = -r;
895  return NULL;
896  }
897 
898  errno = 0;
899  return mem;
900 }
901 
916 ssize_t sol_memdesc_get_array_length(const struct sol_memdesc *array_desc, const void *memory);
917 
937 void *sol_memdesc_get_array_element(const struct sol_memdesc *array_desc, const void *memory, size_t idx);
938 
951 int sol_memdesc_resize_array(const struct sol_memdesc *array_desc, void *memory, size_t length);
952 
976 static inline int
977 sol_memdesc_append_array_element(const struct sol_memdesc *array_desc, void *memory, const void *ptr_content)
978 {
979  void *element;
980  ssize_t len;
981  int r;
982 
983  len = sol_memdesc_get_array_length(array_desc, memory);
984  if (len < 0)
985  return len;
986 
987  if (!array_desc->array_item)
988  return -EINVAL;
989 
990  r = sol_memdesc_resize_array(array_desc, memory, len + 1);
991  if (r < 0)
992  return r;
993 
994  element = sol_memdesc_get_array_element(array_desc, memory, len);
995  if (!element)
996  return -errno;
997 
998  r = sol_memdesc_set_content(array_desc->array_item, element, ptr_content);
999  if (r < 0)
1000  sol_memdesc_resize_array(array_desc, memory, len);
1001 
1002  return r;
1003 }
1004 
1015 #define SOL_MEMDESC_FOREACH_ARRAY_ELEMENT_IN_RANGE(desc, memory, start_idx, end_idx, itr_idx, element) \
1016  for (itr_idx = start_idx, \
1017  element = (itr_idx < end_idx) ? sol_memdesc_get_array_element((desc), (memory), itr_idx) : NULL; \
1018  itr_idx < end_idx && element; \
1019  itr_idx++, \
1020  element = (itr_idx < end_idx) ? sol_memdesc_get_array_element((desc), (memory), itr_idx) : NULL)
1021 
1028 #ifdef SOL_NO_API_VERSION
1029 #define _SOL_MEMDESC_CHECK_API_VERSION(desc) 1
1030 #else
1031 #define _SOL_MEMDESC_CHECK_API_VERSION(desc) ((desc)->api_version == SOL_MEMDESC_API_VERSION_COMPILED)
1032 #endif
1033 
1041 #define _SOL_MEMDESC_CHECK(desc) \
1042  ((desc) && _SOL_MEMDESC_CHECK_API_VERSION(desc) && (desc)->type != SOL_MEMDESC_TYPE_UNKNOWN)
1043 
1051 #define _SOL_MEMDESC_CHECK_STRUCTURE(structure_desc) \
1052  (_SOL_MEMDESC_CHECK(structure_desc) && (structure_desc)->structure_members && _SOL_MEMDESC_CHECK(&((structure_desc)->structure_members->base)))
1053 
1066 #define _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER(structure_desc, member_desc) \
1067  (_SOL_MEMDESC_CHECK(&(member_desc)->base) && \
1068  ((member_desc)->offset + sol_memdesc_get_size(&(member_desc)->base) <= sol_memdesc_get_size((structure_desc))))
1069 
1077 #define SOL_MEMDESC_FOREACH_STRUCTURE_MEMBER(structure_desc, member_desc) \
1078  for (member_desc = (_SOL_MEMDESC_CHECK_STRUCTURE((structure_desc)) && _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), (structure_desc)->structure_members)) ? (structure_desc)->structure_members : NULL; \
1079  _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), member_desc); \
1080  member_desc = _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), member_desc + 1) ? member_desc + 1 : NULL)
1081 
1091 #define SOL_MEMDESC_FOREACH_STRUCTURE_MEMBER_MEMORY(structure_desc, member_desc, structure_memory, member_memory) \
1092  for (member_desc = (_SOL_MEMDESC_CHECK_STRUCTURE((structure_desc)) && _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), (structure_desc)->structure_members)) ? (structure_desc)->structure_members : NULL, \
1093  member_memory = member_desc ? sol_memdesc_get_structure_member_memory((structure_desc), member_desc, (structure_memory)) : NULL; \
1094  _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), member_desc) && member_memory; \
1095  member_desc = _SOL_MEMDESC_CHECK_STRUCTURE_MEMBER((structure_desc), member_desc + 1) ? member_desc + 1 : NULL, \
1096  member_memory = member_desc ? sol_memdesc_get_structure_member_memory((structure_desc), member_desc, (structure_memory)) : NULL)
1097 
1114 static inline const struct sol_memdesc_structure_member *
1116 {
1117  const struct sol_memdesc_structure_member *itr;
1118 
1119  errno = EINVAL;
1120  if (!structure_desc || !name.len)
1121  return NULL;
1122 
1123  SOL_MEMDESC_FOREACH_STRUCTURE_MEMBER(structure_desc, itr) {
1124  if (sol_str_slice_str_eq(name, itr->name)) {
1125  errno = 0;
1126  return itr;
1127  }
1128  }
1129 
1130  errno = ENOENT;
1131  return NULL;
1132 }
1133 
1148 static inline void *
1149 sol_memdesc_get_structure_member_memory(const struct sol_memdesc *structure_desc, const struct sol_memdesc_structure_member *member_desc, const void *structure_memory)
1150 {
1151  errno = EINVAL;
1152  if (!structure_desc || !member_desc || !structure_memory)
1153  return NULL;
1154 
1155 #ifndef SOL_NO_API_VERSION
1156  if (structure_desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1157  return NULL;
1158  if (member_desc->base.api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1159  return NULL;
1160 #endif
1161 
1162  if (member_desc->offset + sol_memdesc_get_size(&member_desc->base) > sol_memdesc_get_size(structure_desc)) {
1163  errno = EOVERFLOW;
1164  return NULL;
1165  }
1166 
1167  errno = 0;
1168  return ((uint8_t *)structure_memory) + member_desc->offset;
1169 }
1170 
1180 const char *sol_memdesc_enumeration_to_str(const struct sol_memdesc *enumeration, const void *memory);
1181 
1199 int sol_memdesc_enumeration_from_str(const struct sol_memdesc *enumeration, void *ptr_return, const struct sol_str_slice str);
1200 
1211 static inline uint64_t
1212 sol_memdesc_get_as_uint64(const struct sol_memdesc *desc, const void *memory)
1213 {
1214  int64_t i64;
1215 
1216  errno = EINVAL;
1217  if (!desc || !memory)
1218  return 0;
1219 
1220 #ifndef SOL_NO_API_VERSION
1221  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1222  return 0;
1223 #endif
1224 
1225  errno = 0;
1226  switch (desc->type) {
1228  return *(const uint8_t *)memory;
1230  return *(const uint16_t *)memory;
1232  return *(const uint32_t *)memory;
1234  return *(const uint64_t *)memory;
1236  return *(const unsigned long *)memory;
1237  case SOL_MEMDESC_TYPE_SIZE:
1238  return *(const size_t *)memory;
1239  case SOL_MEMDESC_TYPE_INT8:
1240  i64 = *(const int8_t *)memory;
1241  goto check_signed;
1243  i64 = *(const int16_t *)memory;
1244  goto check_signed;
1246  i64 = *(const int32_t *)memory;
1247  goto check_signed;
1249  i64 = *(const int64_t *)memory;
1250  goto check_signed;
1251  case SOL_MEMDESC_TYPE_LONG:
1252  i64 = *(const long *)memory;
1253  goto check_signed;
1255  i64 = *(const ssize_t *)memory;
1256  goto check_signed;
1257  case SOL_MEMDESC_TYPE_BOOL:
1258  return *(const bool *)memory;
1260  i64 = *(const double *)memory;
1261  goto check_signed;
1263  uint8_t offset = 0;
1264 
1265  if (desc->size > sizeof(int64_t)) {
1266  errno = EINVAL;
1267  return 0;
1268  }
1269 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1270  else if (desc->size < sizeof(int64_t))
1271  offset = sizeof(desc->defcontent.e) - desc->size;
1272 #endif
1273  i64 = 0;
1274  memcpy((uint8_t *)&i64 + offset, memory, desc->size);
1275  goto check_signed;
1276  }
1279  case SOL_MEMDESC_TYPE_PTR:
1282  default:
1283  errno = EINVAL;
1284  return 0;
1285  }
1286 
1287 check_signed:
1288  if (i64 < 0) {
1289  errno = ERANGE;
1290  return 0;
1291  }
1292  return i64;
1293 }
1294 
1305 static inline int64_t
1306 sol_memdesc_get_as_int64(const struct sol_memdesc *desc, const void *memory)
1307 {
1308  uint64_t u64;
1309 
1310  errno = EINVAL;
1311  if (!desc || !memory)
1312  return 0;
1313 
1314 #ifndef SOL_NO_API_VERSION
1315  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1316  return 0;
1317 #endif
1318 
1319  errno = 0;
1320  switch (desc->type) {
1322  return *(const uint8_t *)memory;
1324  return *(const uint16_t *)memory;
1326  return *(const uint32_t *)memory;
1328  u64 = *(const uint64_t *)memory;
1329  goto check_overflow;
1331  u64 = *(const unsigned long *)memory;
1332  goto check_overflow;
1333  case SOL_MEMDESC_TYPE_SIZE:
1334  u64 = *(const size_t *)memory;
1335  goto check_overflow;
1336  case SOL_MEMDESC_TYPE_INT8:
1337  return *(const int8_t *)memory;
1339  return *(const int16_t *)memory;
1341  return *(const int32_t *)memory;
1343  return *(const int64_t *)memory;
1344  case SOL_MEMDESC_TYPE_LONG:
1345  return *(const long *)memory;
1347  return *(const ssize_t *)memory;
1348  case SOL_MEMDESC_TYPE_BOOL:
1349  return *(const bool *)memory;
1351  return *(const double *)memory;
1353  int64_t i64 = 0;
1354  uint8_t offset = 0;
1355 
1356  if (desc->size > sizeof(int64_t)) {
1357  errno = EINVAL;
1358  return 0;
1359  }
1360 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1361  else if (desc->size < sizeof(int64_t))
1362  offset = sizeof(desc->defcontent.e) - desc->size;
1363 #endif
1364  memcpy((uint8_t *)&i64 + offset, memory, desc->size);
1365  return i64;
1366  }
1369  case SOL_MEMDESC_TYPE_PTR:
1372  default:
1373  errno = EINVAL;
1374  return 0;
1375  }
1376 
1377 check_overflow:
1378  if (u64 > INT64_MAX) {
1379  errno = ERANGE;
1380  return 0;
1381  }
1382  return u64;
1383 }
1384 
1396 static inline int
1397 sol_memdesc_set_as_uint64(const struct sol_memdesc *desc, void *memory, uint64_t value)
1398 {
1399  if (!desc || !memory)
1400  return -EINVAL;
1401 
1402 #ifndef SOL_NO_API_VERSION
1403  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1404  return -EINVAL;
1405 #endif
1406 
1407  switch (desc->type) {
1409  if (value > UINT8_MAX)
1410  return -EOVERFLOW;
1411  *(uint8_t *)memory = value;
1412  return 0;
1414  if (value > UINT16_MAX)
1415  return -EOVERFLOW;
1416  *(uint16_t *)memory = value;
1417  return 0;
1419  if (value > UINT32_MAX)
1420  return -EOVERFLOW;
1421  *(uint32_t *)memory = value;
1422  return 0;
1424  *(uint64_t *)memory = value;
1425  return 0;
1427  if (value > ULONG_MAX)
1428  return -EOVERFLOW;
1429  *(unsigned long *)memory = value;
1430  return 0;
1431  case SOL_MEMDESC_TYPE_SIZE:
1432  if (value > SIZE_MAX)
1433  return -EOVERFLOW;
1434  *(size_t *)memory = value;
1435  return 0;
1436  case SOL_MEMDESC_TYPE_INT8:
1437  if (value > INT8_MAX)
1438  return -EOVERFLOW;
1439  *(int8_t *)memory = value;
1440  return 0;
1442  if (value > INT16_MAX)
1443  return -EOVERFLOW;
1444  *(int16_t *)memory = value;
1445  return 0;
1447  if (value > INT32_MAX)
1448  return -EOVERFLOW;
1449  *(int32_t *)memory = value;
1450  return 0;
1452  if (value > INT64_MAX)
1453  return -EOVERFLOW;
1454  *(int64_t *)memory = value;
1455  return 0;
1456  case SOL_MEMDESC_TYPE_LONG:
1457  if (value > LONG_MAX)
1458  return -EOVERFLOW;
1459  *(long *)memory = value;
1460  return 0;
1462  if (value > SSIZE_MAX)
1463  return -EOVERFLOW;
1464  *(ssize_t *)memory = value;
1465  return 0;
1466  case SOL_MEMDESC_TYPE_BOOL:
1467  *(bool *)memory = !!value;
1468  return 0;
1470  *(double *)memory = value;
1471  return 0;
1473  uint8_t offset = 0;
1474 
1475  if (desc->size > sizeof(int64_t))
1476  return -EINVAL;
1477 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1478  else if (desc->size < sizeof(int64_t))
1479  offset = sizeof(desc->defcontent.e) - desc->size;
1480 #endif
1481 
1482  if (value > (((uint64_t)1 << (desc->size * 8 - 1)) - 1))
1483  return -EOVERFLOW;
1484 
1485  memcpy(memory, (uint8_t *)&value + offset, desc->size);
1486  return 0;
1487  }
1490  case SOL_MEMDESC_TYPE_PTR:
1493  default:
1494  return -EINVAL;
1495  }
1496 }
1497 
1509 static inline int64_t
1510 sol_memdesc_set_as_int64(const struct sol_memdesc *desc, void *memory, int64_t value)
1511 {
1512  if (!desc || !memory)
1513  return -EINVAL;
1514 
1515 #ifndef SOL_NO_API_VERSION
1516  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1517  return -EINVAL;
1518 #endif
1519 
1520  switch (desc->type) {
1522  if (value < 0 || value > UINT8_MAX)
1523  return -EOVERFLOW;
1524  *(uint8_t *)memory = value;
1525  return 0;
1527  if (value < 0 || value > UINT16_MAX)
1528  return -EOVERFLOW;
1529  *(uint16_t *)memory = value;
1530  return 0;
1532  if (value < 0 || value > UINT32_MAX)
1533  return -EOVERFLOW;
1534  *(uint32_t *)memory = value;
1535  return 0;
1537  if (value < 0)
1538  return -EOVERFLOW;
1539  *(uint64_t *)memory = value;
1540  return 0;
1542  if (value < 0 || (uint64_t)value > ULONG_MAX)
1543  return -EOVERFLOW;
1544  *(unsigned long *)memory = value;
1545  return 0;
1546  case SOL_MEMDESC_TYPE_SIZE:
1547  if (value < 0 || (uint64_t)value > SIZE_MAX)
1548  return -EOVERFLOW;
1549  *(size_t *)memory = value;
1550  return 0;
1551  case SOL_MEMDESC_TYPE_INT8:
1552  if (value < INT8_MIN || value > INT8_MAX)
1553  return -EOVERFLOW;
1554  *(int8_t *)memory = value;
1555  return 0;
1557  if (value < INT16_MIN || value > INT16_MAX)
1558  return -EOVERFLOW;
1559  *(int16_t *)memory = value;
1560  return 0;
1562  if (value < INT32_MIN || value > INT32_MAX)
1563  return -EOVERFLOW;
1564  *(int32_t *)memory = value;
1565  return 0;
1567  *(int64_t *)memory = value;
1568  return 0;
1569  case SOL_MEMDESC_TYPE_LONG:
1570  if (value < LONG_MIN || value > LONG_MAX)
1571  return -EOVERFLOW;
1572  *(long *)memory = value;
1573  return 0;
1575  if (value < SSIZE_MIN || value > SSIZE_MAX)
1576  return -EOVERFLOW;
1577  *(ssize_t *)memory = value;
1578  return 0;
1579  case SOL_MEMDESC_TYPE_BOOL:
1580  *(bool *)memory = !!value;
1581  return 0;
1583  *(double *)memory = value;
1584  return 0;
1586  uint8_t offset = 0;
1587 
1588  if (desc->size > sizeof(int64_t))
1589  return -EINVAL;
1590 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1591  else if (desc->size < sizeof(int64_t))
1592  offset = sizeof(desc->defcontent.e) - desc->size;
1593 #endif
1594 
1595  if (desc->size < sizeof(int64_t)) {
1596  if (value > (((int64_t)1 << (desc->size * 8 - 1)) - 1))
1597  return -EOVERFLOW;
1598  if (value < -((int64_t)1 << (desc->size * 8 - 1)))
1599  return -EOVERFLOW;
1600  }
1601 
1602  memcpy(memory, (uint8_t *)&value + offset, desc->size);
1603  return 0;
1604  }
1607  case SOL_MEMDESC_TYPE_PTR:
1610  default:
1611  return -EINVAL;
1612  }
1613 }
1614 
1623 static inline bool
1625 {
1626  errno = EINVAL;
1627  if (!desc)
1628  return false;
1629 
1630 #ifndef SOL_NO_API_VERSION
1631  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1632  return false;
1633 #endif
1634 
1635  errno = 0;
1636  switch (desc->type) {
1642  case SOL_MEMDESC_TYPE_SIZE:
1643  return true;
1644  case SOL_MEMDESC_TYPE_INT8:
1648  case SOL_MEMDESC_TYPE_LONG:
1650  case SOL_MEMDESC_TYPE_BOOL:
1654  case SOL_MEMDESC_TYPE_PTR:
1658  default:
1659  return false;
1660  }
1661 }
1662 
1671 static inline bool
1673 {
1674  errno = EINVAL;
1675  if (!desc)
1676  return false;
1677 
1678 #ifndef SOL_NO_API_VERSION
1679  if (desc->api_version != SOL_MEMDESC_API_VERSION_COMPILED)
1680  return false;
1681 #endif
1682 
1683  errno = 0;
1684  switch (desc->type) {
1690  case SOL_MEMDESC_TYPE_SIZE:
1691  return false;
1692  case SOL_MEMDESC_TYPE_INT8:
1696  case SOL_MEMDESC_TYPE_LONG:
1699  return true;
1700  case SOL_MEMDESC_TYPE_BOOL:
1704  case SOL_MEMDESC_TYPE_PTR:
1707  default:
1708  return false;
1709  }
1710 }
1711 
1716 #ifndef SOL_NO_API_VERSION
1717 #define SOL_MEMDESC_SERIALIZE_OPTIONS_API_VERSION (1)
1718  uint16_t api_version;
1719 #endif
1720 
1727  int (*serialize_int64)(const struct sol_memdesc *desc, int64_t value, struct sol_buffer *buffer);
1735  int (*serialize_uint64)(const struct sol_memdesc *desc, uint64_t value, struct sol_buffer *buffer);
1743  int (*serialize_double)(const struct sol_memdesc *desc, double value, struct sol_buffer *buffer);
1751  int (*serialize_bool)(const struct sol_memdesc *desc, bool value, struct sol_buffer *buffer);
1764  int (*serialize_pointer)(const struct sol_memdesc *desc, const void *value, struct sol_buffer *buffer);
1775  int (*serialize_string)(const struct sol_memdesc *desc, const char *value, struct sol_buffer *buffer);
1789  int (*serialize_enumeration)(const struct sol_memdesc *desc, const void *memory, struct sol_buffer *buffer);
1810  int (*serialize_structure_member)(const struct sol_memdesc *structure, const struct sol_memdesc_structure_member *member, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix, bool is_first);
1827  int (*serialize_array_item)(const struct sol_memdesc *desc, size_t idx, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix);
1834  struct {
1835  struct {
1839  const struct sol_str_slice start;
1843  const struct sol_str_slice end;
1847  const struct sol_str_slice indent;
1848  } container;
1849  struct {
1856  const struct sol_str_slice start;
1863  const struct sol_str_slice end;
1867  const struct sol_str_slice indent;
1868  } key;
1869  struct {
1873  const struct sol_str_slice start;
1877  const struct sol_str_slice end;
1881  const struct sol_str_slice indent;
1882  } value;
1883 #ifdef SOL_MEMDESC_DESCRIPTION
1884  struct {
1888  const struct sol_str_slice start;
1892  const struct sol_str_slice end;
1896  const struct sol_str_slice indent;
1897  } description;
1898 #endif
1899 
1906  bool show_key;
1914  bool detailed;
1915 #ifdef SOL_MEMDESC_DESCRIPTION
1916 
1919  bool show_description;
1920 #endif
1921  } structure;
1928  struct {
1929  struct {
1933  const struct sol_str_slice start;
1937  const struct sol_str_slice end;
1941  const struct sol_str_slice indent;
1942  } container;
1943  struct {
1950  const struct sol_str_slice start;
1957  const struct sol_str_slice end;
1961  const struct sol_str_slice indent;
1962  } index;
1963  struct {
1967  const struct sol_str_slice start;
1971  const struct sol_str_slice end;
1975  const struct sol_str_slice indent;
1976  } value;
1980  struct sol_str_slice separator;
1985  } array;
1987 
2001 
2020 int sol_memdesc_serialize(const struct sol_memdesc *desc, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix);
2021 
2026 #ifdef __cplusplus
2027 }
2028 #endif
int8_t equivalent (one signed byte).
Definition: sol-memdesc.h:110
uint16_t u16
use when SOL_MEMDESC_TYPE_UINT16
Definition: sol-memdesc.h:553
long l
use when SOL_MEMDESC_TYPE_LONG
Definition: sol-memdesc.h:562
int(* serialize_structure_member)(const struct sol_memdesc *structure, const struct sol_memdesc_structure_member *member, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix, bool is_first)
function used to format a struct member.
Definition: sol-memdesc.h:1810
int sol_memdesc_init_defaults(const struct sol_memdesc *desc, void *memory)
initialize the memory.
int16_t equivalent (two signed bytes).
Definition: sol-memdesc.h:117
static uint16_t sol_memdesc_get_size(const struct sol_memdesc *desc)
get the size in bytes of the memory description.
Definition: sol-memdesc.h:697
static int64_t sol_memdesc_set_as_int64(const struct sol_memdesc *desc, void *memory, int64_t value)
Helper to set the memory as the largest supported signed integer.
Definition: sol-memdesc.h:1510
static bool sol_memdesc_is_unsigned_integer(const struct sol_memdesc *desc)
Helper to check if type is unsigned integer-compatible.
Definition: sol-memdesc.h:1624
const struct sol_str_slice start
Used when starting a new structure.
Definition: sol-memdesc.h:1839
#define SOL_MEMDESC_FOREACH_STRUCTURE_MEMBER(structure_desc, member_desc)
Macro to loop over all structure members.
Definition: sol-memdesc.h:1077
const struct sol_str_slice end
Used when finishing a structure.
Definition: sol-memdesc.h:1843
int sol_memdesc_copy(const struct sol_memdesc *desc, const void *src_memory, void *dst_memory)
copy the memory using the given description.
uint32_t equivalent (four unsigned bytes).
Definition: sol-memdesc.h:82
static int sol_memdesc_set_as_uint64(const struct sol_memdesc *desc, void *memory, uint64_t value)
Helper to set the memory as the largest supported unsigned integer.
Definition: sol-memdesc.h:1397
int(* init_defaults)(const struct sol_memdesc *desc, void *memory)
initialize the defaults of memory.
Definition: sol-memdesc.h:450
struct sol_memdesc_ops sol_memdesc_ops
override operations to be used in this memory description.
const struct sol_memdesc_serialize_options SOL_MEMDESC_SERIALIZE_OPTIONS_DEFAULT
the default struct sol_memdesc_serialize_options.
int(* from_str)(const struct sol_memdesc *desc, void *ptr_return, const struct sol_str_slice str)
convert enumeration value from string.
Definition: sol-memdesc.h:419
int(* resize)(const struct sol_memdesc *desc, void *memory, size_t length)
resize array length.
Definition: sol-memdesc.h:381
static void sol_memdesc_free(const struct sol_memdesc *desc, void *memory)
Free the contents and the memory.
Definition: sol-memdesc.h:857
enum sol_memdesc_type type
basic type of the member memory.
Definition: sol-memdesc.h:537
const struct sol_memdesc_structure_member * structure_members
null-terminated array of structure members.
Definition: sol-memdesc.h:596
struct sol_memdesc_structure_member sol_memdesc_structure_member
Description of a structure member.
uint16_t offset
offset in bytes relative to containing structure memory.
Definition: sol-memdesc.h:650
int(* serialize_array_item)(const struct sol_memdesc *desc, size_t idx, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix)
function used to format an array item.
Definition: sol-memdesc.h:1827
unsigned long ul
use when SOL_MEMDESC_TYPE_ULONG
Definition: sol-memdesc.h:556
static bool sol_memdesc_is_signed_integer(const struct sol_memdesc *desc)
Helper to check if type is signed integer-compatible.
Definition: sol-memdesc.h:1672
int(* serialize_double)(const struct sol_memdesc *desc, double value, struct sol_buffer *buffer)
function used to format a double precision floating point number.
Definition: sol-memdesc.h:1743
const char * s
use when SOL_MEMDESC_TYPE_STRING or SOL_MEMDESC_TYPE_CONST_STRING
Definition: sol-memdesc.h:567
double d
use when SOL_MEMDESC_TYPE_DOUBLE
Definition: sol-memdesc.h:565
Operations specific to SOL_MEMDESC_TYPE_ENUMERATION.
Definition: sol-memdesc.h:393
bool optional
whenever member is mandatory in serialization and parsing.
Definition: sol-memdesc.h:657
static uint64_t sol_memdesc_get_as_uint64(const struct sol_memdesc *desc, const void *memory)
Helper to fetch the memory as the largest supported unsigned integer.
Definition: sol-memdesc.h:1212
int sol_memdesc_free_content(const struct sol_memdesc *desc, void *memory)
free the contents (internal memory) of a member.
not to be used.
Definition: sol-memdesc.h:61
int sol_memdesc_compare(const struct sol_memdesc *desc, const void *a_memory, const void *b_memory)
compare two memories using the given description.
struct sol_memdesc_serialize_options::@22 array
options used by serialize_array_item
struct sol_memdesc base
Definition: sol-memdesc.h:623
uint64_t u64
use when SOL_MEMDESC_TYPE_UINT64
Definition: sol-memdesc.h:555
const struct sol_memdesc_ops SOL_MEMDESC_OPS_PTR_VECTOR
operations to handle struct sol_ptr_vector.
const struct sol_memdesc * array_item
Type of array item.
Definition: sol-memdesc.h:588
struct sol_memdesc_serialize_options::@22::@27 index
const char * sol_memdesc_type_to_str(enum sol_memdesc_type type)
Converts a sol_memdesc_type to a string.
int(* free_content)(const struct sol_memdesc *desc, void *memory)
free the contents (internal memory) of a memory.
Definition: sol-memdesc.h:504
int(* serialize_uint64)(const struct sol_memdesc *desc, uint64_t value, struct sol_buffer *buffer)
function used to format an unsigned integer.
Definition: sol-memdesc.h:1735
These are common Soletta macros.
const void * p
use when SOL_MEMDESC_TYPE_PTR, SOL_MEMDESC_TYPE_STRUCTURE or SOL_MEMDESC_TYPE_ARRAY ...
Definition: sol-memdesc.h:568
uint8_t u8
use when SOL_MEMDESC_TYPE_UINT8
Definition: sol-memdesc.h:552
String/int64_t table type.
Definition: sol-str-table.h:228
static int sol_memdesc_append_array_element(const struct sol_memdesc *array_desc, void *memory, const void *ptr_content)
Append the array element.
Definition: sol-memdesc.h:977
int(* compare)(const struct sol_memdesc *desc, const void *a_memory, const void *b_memory)
compare the content of two memories.
Definition: sol-memdesc.h:492
static struct sol_buffer value
Definition: server.c:42
ssize_t ssz
use when SOL_MEMDESC_TYPE_SSIZE
Definition: sol-memdesc.h:563
int8_t i8
use when SOL_MEMDESC_TYPE_INT8
Definition: sol-memdesc.h:558
int32_t i32
use when SOL_MEMDESC_TYPE_INT32
Definition: sol-memdesc.h:560
boolean equivalent.
Definition: sol-memdesc.h:152
uint16_t equivalent (two unsigned bytes).
Definition: sol-memdesc.h:75
size_t equivalent (four or eight unsigned bytes, depends on platform).
Definition: sol-memdesc.h:103
const char * sol_memdesc_enumeration_to_str(const struct sol_memdesc *enumeration, const void *memory)
convert enumeration value to string.
String slice type.
Definition: sol-str-slice.h:84
These are routines that Soletta provides for its buffer implementation.
struct sol_memdesc_serialize_options::@21 structure
options used by serialize_structure_member.
struct sol_memdesc_ops_enumeration sol_memdesc_ops_enumeration
Operations specific to SOL_MEMDESC_TYPE_ENUMERATION.
#define SOL_ATTR_WARN_UNUSED_RESULT
Causes a warning to be emitted if a caller of the function with this attribute does not use its retur...
Definition: sol-macros.h:187
int64_t e
use when SOL_MEMDESC_TYPE_ENUMERATION
Definition: sol-memdesc.h:566
enum sol_memdesc_type sol_memdesc_type_from_str(const char *str)
Converts a Memdesc Type from string to sol_memdesc_type.
null-terminated C-string (char*).
Definition: sol-memdesc.h:169
union sol_memdesc::@18 defcontent
default contents to be used if required == false.
uint64_t equivalent (four unsigned bytes).
Definition: sol-memdesc.h:89
bool detailed
Controls whenever struct sol_memdesc_structure_member::detail is to be printed.
Definition: sol-memdesc.h:1914
int(* serialize_int64)(const struct sol_memdesc *desc, int64_t value, struct sol_buffer *buffer)
function used to format a signed integer.
Definition: sol-memdesc.h:1727
bool b
use when SOL_MEMDESC_TYPE_BOOL
Definition: sol-memdesc.h:564
int16_t i16
use when SOL_MEMDESC_TYPE_INT16
Definition: sol-memdesc.h:559
uint32_t u32
use when SOL_MEMDESC_TYPE_UINT32
Definition: sol-memdesc.h:554
bool detail
whenever member is extended detail.
Definition: sol-memdesc.h:664
ssize_t(* get_length)(const struct sol_memdesc *desc, const void *memory)
calculate array length.
Definition: sol-memdesc.h:352
static void * sol_memdesc_get_structure_member_memory(const struct sol_memdesc *structure_desc, const struct sol_memdesc_structure_member *member_desc, const void *structure_memory)
get the pointer to the struct member memory description inside the given container.
Definition: sol-memdesc.h:1149
const char * name
memory name, such as the member name in a structure.
Definition: sol-memdesc.h:630
const struct sol_memdesc * pointed_item
Type of a memory pointer.
Definition: sol-memdesc.h:582
int(* copy)(const struct sol_memdesc *desc, const void *src_memory, void *dst_memory)
copy the content from another memory.
Definition: sol-memdesc.h:479
null-terminated C-string (const char*).
Definition: sol-memdesc.h:179
int sol_memdesc_resize_array(const struct sol_memdesc *array_desc, void *memory, size_t length)
Resize the length of an array.
int64_t equivalent (eight signed bytes).
Definition: sol-memdesc.h:131
int64_t i64
use when SOL_MEMDESC_TYPE_INT64
Definition: sol-memdesc.h:561
size_t sz
use when SOL_MEMDESC_TYPE_SIZE
Definition: sol-memdesc.h:557
#define SSIZE_MAX
Maximum value of a ssize variable.
Definition: sol-types.h:102
enumeration
Definition: sol-memdesc.h:201
struct sol_memdesc_ops_array sol_memdesc_ops_array
Operations specific to SOL_MEMDESC_TYPE_ARRAY.
const struct sol_str_slice indent
Used to indent a new container.
Definition: sol-memdesc.h:1847
const struct sol_memdesc_ops * ops
Override operations to use when operating on the memory.
Definition: sol-memdesc.h:611
int sol_memdesc_serialize(const struct sol_memdesc *desc, const void *memory, struct sol_buffer *buffer, const struct sol_memdesc_serialize_options *opts, struct sol_buffer *prefix)
Serialize a memory to a buffer using a description.
struct sol_memdesc_serialize_options::@21::@25 value
Description of a structure member.
Definition: sol-memdesc.h:622
an array with internal members.
Definition: sol-memdesc.h:260
const struct sol_memdesc_ops_array * array
Definition: sol-memdesc.h:506
Data type to describe a memory region.
Definition: sol-memdesc.h:514
sol_memdesc_type
Designates the type of the memory description.
Definition: sol-memdesc.h:60
struct sol_memdesc_serialize_options sol_memdesc_serialize_options
Options on how to serialize a memory given its description.
signed long equivalent.
Definition: sol-memdesc.h:138
uint16_t api_version
API version, must match SOL_MEMDESC_API_VERSION at runtime.
Definition: sol-memdesc.h:517
const struct sol_memdesc_ops SOL_MEMDESC_OPS_VECTOR
operations to handle struct sol_vector.
int sol_memdesc_set_content(const struct sol_memdesc *desc, void *memory, const void *ptr_content)
set the content of this memory.
const uint16_t SOL_MEMDESC_API_VERSION_COMPILED
the SOL_MEMDESC_API_VERSION this soletta build used.
const struct sol_memdesc_ops_enumeration * enumeration
Definition: sol-memdesc.h:507
These are routines that Soletta provides for its string slice implementation.
const struct sol_str_table_int64 * enumeration_mapping
null-terminated array of struct sol_str_table.
Definition: sol-memdesc.h:603
bool show_index
Controls whenever the index is to be serialized.
Definition: sol-memdesc.h:1984
int(* serialize_pointer)(const struct sol_memdesc *desc, const void *value, struct sol_buffer *buffer)
function used to format a pointer.
Definition: sol-memdesc.h:1764
struct sol_memdesc sol_memdesc
Data type to describe a memory region.
ssize_t sol_memdesc_get_array_length(const struct sol_memdesc *array_desc, const void *memory)
Get the length of an array.
int sol_memdesc_enumeration_from_str(const struct sol_memdesc *enumeration, void *ptr_return, const struct sol_str_slice str)
convert enumeration value from string.
Options on how to serialize a memory given its description.
Definition: sol-memdesc.h:1715
bool show_key
Controls whenever the key is to be serialized.
Definition: sol-memdesc.h:1906
int32_t equivalent (four signed bytes).
Definition: sol-memdesc.h:124
These are routines that Soletta provides for its string table implementation.
ssize_t equivalent (four or eight signed bytes, depends on platform).
Definition: sol-memdesc.h:145
unsigned long equivalent.
Definition: sol-memdesc.h:96
struct sol_memdesc_serialize_options::@21::@24 key
structure with internal members.
Definition: sol-memdesc.h:231
int(* serialize_bool)(const struct sol_memdesc *desc, bool value, struct sol_buffer *buffer)
function used to format a boolean.
Definition: sol-memdesc.h:1751
double precision floating point equivalent.
Definition: sol-memdesc.h:159
static const struct sol_memdesc_structure_member * sol_memdesc_find_structure_member(const struct sol_memdesc *structure_desc, struct sol_str_slice name)
Find structure member given its name.
Definition: sol-memdesc.h:1115
int(* set_content)(const struct sol_memdesc *desc, void *memory, const void *ptr_content)
sets the content of a memory.
Definition: sol-memdesc.h:467
struct sol_memdesc_serialize_options::@21::@23 container
generic pointer (void *).
Definition: sol-memdesc.h:218
A sol_buffer is a dynamic array, that can be resized if needed.
Definition: sol-buffer.h:130
int(* serialize_string)(const struct sol_memdesc *desc, const char *value, struct sol_buffer *buffer)
function used to format a string.
Definition: sol-memdesc.h:1775
uint16_t size
size in bytes of the member memory.
Definition: sol-memdesc.h:528
struct sol_str_slice separator
Used if multiple members exist.
Definition: sol-memdesc.h:1902
void * sol_memdesc_get_array_element(const struct sol_memdesc *array_desc, const void *memory, size_t idx)
Get the array element.
Operations specific to SOL_MEMDESC_TYPE_ARRAY.
Definition: sol-memdesc.h:334
uint8_t equivalent (one unsigned byte).
Definition: sol-memdesc.h:68
static bool sol_str_slice_str_eq(const struct sol_str_slice a, const char *b)
Checks if the content of the slice is equal to the string.
Definition: sol-str-slice.h:100
static void * sol_memdesc_new_with_defaults(const struct sol_memdesc *desc)
Allocate the memory required by this description and initialize it.
Definition: sol-memdesc.h:877
int(* serialize_enumeration)(const struct sol_memdesc *desc, const void *memory, struct sol_buffer *buffer)
function used to format an enumeration.
Definition: sol-memdesc.h:1789
override operations to be used in this memory description.
Definition: sol-memdesc.h:435
size_t len
Slice length.
Definition: sol-str-slice.h:85
static int64_t sol_memdesc_get_as_int64(const struct sol_memdesc *desc, const void *memory)
Helper to fetch the memory as the largest supported signed integer.
Definition: sol-memdesc.h:1306