tiny_json.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. <https://github.com/rafagafe/tiny-json>
  3. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
  4. SPDX-License-Identifier: MIT
  5. Copyright (c) 2016-2018 Rafa Garcia <rafagarcia77@gmail.com>.
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in all
  13. copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. SOFTWARE.
  21. */
  22. #ifndef _TINY_JSON_H_
  23. #define _TINY_JSON_H_
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. #include <stddef.h>
  28. #include <stdlib.h>
  29. #include <stdbool.h>
  30. #include <stdint.h>
  31. #define json_containerOf( ptr, type, member ) \
  32. ((type*)( (char*)ptr - offsetof( type, member ) ))
  33. /** @defgroup tinyJson Tiny JSON parser.
  34. * @{ */
  35. /** Enumeration of codes of supported JSON properties types. */
  36. typedef enum {
  37. JSON_OBJ, JSON_ARRAY, JSON_TEXT, JSON_BOOLEAN,
  38. JSON_INTEGER, JSON_REAL, JSON_NULL
  39. } jsonType_t;
  40. /** Structure to handle JSON properties. */
  41. typedef struct json_s {
  42. struct json_s* sibling;
  43. char const* name;
  44. union {
  45. char const* value;
  46. struct {
  47. struct json_s* child;
  48. struct json_s* last_child;
  49. } c;
  50. } u;
  51. jsonType_t type;
  52. } json_t;
  53. /** Parse a string to get a json.
  54. * @param str String pointer with a JSON object. It will be modified.
  55. * @param mem Array of json properties to allocate.
  56. * @param qty Number of elements of mem.
  57. * @retval Null pointer if any was wrong in the parse process.
  58. * @retval If the parser process was successfully a valid handler of a json.
  59. * This property is always unnamed and its type is JSON_OBJ. */
  60. json_t const* json_create( char* str, json_t mem[], unsigned int qty );
  61. /** Get the name of a json property.
  62. * @param json A valid handler of a json property.
  63. * @retval Pointer to null-terminated if property has name.
  64. * @retval Null pointer if the property is unnamed. */
  65. static inline char const* json_getName( json_t const* json ) {
  66. return json->name;
  67. }
  68. /** Get the value of a json property.
  69. * The type of property cannot be JSON_OBJ or JSON_ARRAY.
  70. * @param property A valid handler of a json property.
  71. * @return Pointer to null-terminated string with the value. */
  72. static inline char const* json_getValue( json_t const* property ) {
  73. return property->u.value;
  74. }
  75. /** Get the type of a json property.
  76. * @param json A valid handler of a json property.
  77. * @return The code of type.*/
  78. static inline jsonType_t json_getType( json_t const* json ) {
  79. return json->type;
  80. }
  81. /** Get the next sibling of a JSON property that is within a JSON object or array.
  82. * @param json A valid handler of a json property.
  83. * @retval The handler of the next sibling if found.
  84. * @retval Null pointer if the json property is the last one. */
  85. static inline json_t const* json_getSibling( json_t const* json ) {
  86. return json->sibling;
  87. }
  88. /** Search a property by its name in a JSON object.
  89. * @param obj A valid handler of a json object. Its type must be JSON_OBJ.
  90. * @param property The name of property to get.
  91. * @retval The handler of the json property if found.
  92. * @retval Null pointer if not found. */
  93. json_t const* json_getProperty( json_t const* obj, char const* property );
  94. /** Search a property by its name in a JSON object and return its value.
  95. * @param obj A valid handler of a json object. Its type must be JSON_OBJ.
  96. * @param property The name of property to get.
  97. * @retval If found a pointer to null-terminated string with the value.
  98. * @retval Null pointer if not found or it is an array or an object. */
  99. char const* json_getPropertyValue( json_t const* obj, char const* property );
  100. /** Get the first property of a JSON object or array.
  101. * @param json A valid handler of a json property.
  102. * Its type must be JSON_OBJ or JSON_ARRAY.
  103. * @retval The handler of the first property if there is.
  104. * @retval Null pointer if the json object has not properties. */
  105. static inline json_t const* json_getChild( json_t const* json ) {
  106. return json->u.c.child;
  107. }
  108. /** Get the value of a json boolean property.
  109. * @param property A valid handler of a json object. Its type must be JSON_BOOLEAN.
  110. * @return The value stdbool. */
  111. static inline bool json_getBoolean( json_t const* property ) {
  112. return *property->u.value == 't';
  113. }
  114. /** Get the value of a json integer property.
  115. * @param property A valid handler of a json object. Its type must be JSON_INTEGER.
  116. * @return The value stdint. */
  117. static inline int64_t json_getInteger( json_t const* property ) {
  118. return strtoll( property->u.value,(char**)NULL, 10);
  119. }
  120. /** Get the value of a json real property.
  121. * @param property A valid handler of a json object. Its type must be JSON_REAL.
  122. * @return The value. */
  123. static inline double json_getReal( json_t const* property ) {
  124. return strtod( property->u.value,(char**)NULL );
  125. }
  126. /** Structure to handle a heap of JSON properties. */
  127. typedef struct jsonPool_s jsonPool_t;
  128. struct jsonPool_s {
  129. json_t* (*init)( jsonPool_t* pool );
  130. json_t* (*alloc)( jsonPool_t* pool );
  131. };
  132. /** Parse a string to get a json.
  133. * @param str String pointer with a JSON object. It will be modified.
  134. * @param pool Custom json pool pointer.
  135. * @retval Null pointer if any was wrong in the parse process.
  136. * @retval If the parser process was successfully a valid handler of a json.
  137. * This property is always unnamed and its type is JSON_OBJ. */
  138. json_t const* json_createWithPool( char* str, jsonPool_t* pool );
  139. /** @ } */
  140. #ifdef __cplusplus
  141. }
  142. #endif
  143. #endif /* _TINY_JSON_H_ */