json.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* Structures for JSON parsing using only fixed-extent memory
  2. *
  3. * This file is Copyright 2010 by the GPSD project
  4. * SPDX-License-Identifier: BSD-2-clause
  5. */
  6. #include <ctype.h>
  7. #include <stdbool.h>
  8. #include <sys/time.h> // for struct timespec
  9. /* the json_type is the type of the C variable the JSON
  10. * value gets placed in. It is NOT the JSON type as used
  11. * in the JSON standard. But it does partly specify how
  12. * the JSON value is decoded.
  13. *
  14. * For example a t_character must be in quotes, but a t_byte
  15. * is a bare number. */
  16. typedef enum {t_integer, t_uinteger, t_real,
  17. t_string, t_boolean, t_character,
  18. t_time,
  19. t_object, t_structobject, t_array,
  20. t_check, t_ignore,
  21. t_short, t_ushort, t_byte, t_ubyte}
  22. json_type;
  23. struct json_enum_t {
  24. char *name;
  25. int value;
  26. };
  27. struct json_array_t {
  28. json_type element_type;
  29. union {
  30. struct {
  31. const struct json_attr_t *subtype;
  32. char *base;
  33. size_t stride;
  34. } objects;
  35. struct {
  36. char **ptrs;
  37. char *store;
  38. int storelen;
  39. } strings;
  40. struct {
  41. int *store;
  42. } bytes;
  43. struct {
  44. unsigned int *store;
  45. } ubytes;
  46. struct {
  47. int *store;
  48. } integers;
  49. struct {
  50. unsigned int *store;
  51. } uintegers;
  52. struct {
  53. short *store;
  54. } shorts;
  55. struct {
  56. unsigned short *store;
  57. } ushorts;
  58. struct {
  59. double *store;
  60. } reals;
  61. struct {
  62. bool *store;
  63. } booleans;
  64. struct {
  65. struct timespec *store;
  66. } timespecs;
  67. } arr;
  68. int *count, maxlen;
  69. };
  70. struct json_attr_t {
  71. char *attribute;
  72. json_type type;
  73. union {
  74. bool *boolean;
  75. char *byte;
  76. char *character;
  77. char *string;
  78. double *real;
  79. int *integer;
  80. short *shortint;
  81. size_t offset;
  82. struct json_array_t array;
  83. unsigned char *ubyte;
  84. unsigned int *uinteger;
  85. unsigned short *ushortint;
  86. struct timespec *ts;
  87. } addr;
  88. union {
  89. bool boolean;
  90. char byte;
  91. char character;
  92. char *check;
  93. double real;
  94. int integer;
  95. short shortint;
  96. unsigned char ubyte;
  97. unsigned int uinteger;
  98. unsigned short ushortint;
  99. struct timespec ts;
  100. } dflt;
  101. size_t len;
  102. const struct json_enum_t *map;
  103. bool nodefault;
  104. };
  105. #define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
  106. #define JSON_VAL_MAX 512 /* max chars in JSON value part */
  107. #ifdef __cplusplus
  108. extern "C" {
  109. #endif
  110. int json_read_object(const char *, const struct json_attr_t *,
  111. const char **);
  112. int json_read_array(const char *, const struct json_array_t *,
  113. const char **);
  114. const char *json_error_string(int);
  115. void json_enable_debug(int, FILE *);
  116. char *json_quote(const char *, char *, size_t, size_t);
  117. #ifdef __cplusplus
  118. }
  119. #endif
  120. #define JSON_ERR_OBSTART 1 /* non-WS when expecting object start */
  121. #define JSON_ERR_ATTRSTART 2 /* non-WS when expecting attrib start */
  122. #define JSON_ERR_BADATTR 3 /* unknown attribute name */
  123. #define JSON_ERR_ATTRLEN 4 /* attribute name too long */
  124. #define JSON_ERR_NOARRAY 5 /* saw [ when not expecting array */
  125. #define JSON_ERR_NOBRAK 6 /* array element specified, but no [ */
  126. #define JSON_ERR_STRLONG 7 /* string value too long */
  127. #define JSON_ERR_TOKLONG 8 /* token value too long */
  128. #define JSON_ERR_BADTRAIL 9 // garbage while expecting comma or } or ]
  129. #define JSON_ERR_ARRAYSTART 10 /* didn't find expected array start */
  130. #define JSON_ERR_OBJARR 11 /* error while parsing object array */
  131. #define JSON_ERR_SUBTOOLONG 12 /* too many array elements */
  132. #define JSON_ERR_BADSUBTRAIL 13 // garbage while expecting array comma
  133. #define JSON_ERR_SUBTYPE 14 /* unsupported array element type */
  134. #define JSON_ERR_BADSTRING 15 /* error while string parsing */
  135. #define JSON_ERR_CHECKFAIL 16 /* check attribute not matched */
  136. #define JSON_ERR_NOPARSTR 17 // can't support strings in parallel arrays
  137. #define JSON_ERR_BADENUM 18 /* invalid enumerated value */
  138. #define JSON_ERR_QNONSTRING 19 // saw quoted value when expecting nonstring
  139. #define JSON_ERR_NONQSTRING 20 // didn't see quoted value when expecting string
  140. #define JSON_ERR_MISC 21 /* other data conversion error */
  141. #define JSON_ERR_BADNUM 22 // error while parsing a numerical argument
  142. #define JSON_ERR_NULLPTR 23 // unexpected null value or attribute pointer
  143. #define JSON_ERR_NOCURLY 24 /* object element specified, but no { */
  144. /*
  145. * Use the following macros to declare template initializers for structobject
  146. * arrays. Writing the equivalents out by hand is error-prone.
  147. *
  148. * STRUCTOBJECT takes a structure name s, and a fieldname f in s.
  149. *
  150. * STRUCTARRAY takes the name of a structure array, a pointer to a an
  151. * initializer defining the subobject type, and the address of an integer to
  152. * store the length in.
  153. */
  154. #define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
  155. #define STRUCTARRAY(a, e, n) \
  156. .addr.array.element_type = t_structobject, \
  157. .addr.array.arr.objects.subtype = e, \
  158. .addr.array.arr.objects.base = (char*)a, \
  159. .addr.array.arr.objects.stride = sizeof(a[0]), \
  160. .addr.array.count = n, \
  161. .addr.array.maxlen = NITEMS(a)
  162. /* json.h ends here */
  163. // vim: set expandtab shiftwidth=4