jsonparse.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (c) 2011-2012, Swedish Institute of Computer Science.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the Institute nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * This file is part of the Contiki operating system.
  30. */
  31. #include "jsonparse.h"
  32. //#include <stdlib.h>
  33. //#include <string.h>
  34. #include "../../platform/include/pando_types.h"
  35. /*--------------------------------------------------------------------*/
  36. static int FUNCTION_ATTRIBUTE
  37. push(struct jsonparse_state *state, char c)
  38. {
  39. state->stack[state->depth] = c;
  40. state->depth++;
  41. state->vtype = 0;
  42. return state->depth < JSONPARSE_MAX_DEPTH;
  43. }
  44. /*--------------------------------------------------------------------*/
  45. static char FUNCTION_ATTRIBUTE
  46. pop(struct jsonparse_state *state)
  47. {
  48. if(state->depth == 0) {
  49. return JSON_TYPE_ERROR;
  50. }
  51. state->depth--;
  52. return state->stack[state->depth];
  53. }
  54. /*--------------------------------------------------------------------*/
  55. /* will pass by the value and store the start and length of the value for
  56. atomic types */
  57. /*--------------------------------------------------------------------*/
  58. static void FUNCTION_ATTRIBUTE
  59. atomic(struct jsonparse_state *state, char type)
  60. {
  61. char c;
  62. state->vstart = state->pos;
  63. state->vtype = type;
  64. if(type == JSON_TYPE_STRING || type == JSON_TYPE_PAIR_NAME) {
  65. while((c = state->json[state->pos++]) && c != '"') {
  66. if(c == '\\') {
  67. state->pos++; /* skip current char */
  68. }
  69. }
  70. state->vlen = state->pos - state->vstart - 1;
  71. } else if(type == JSON_TYPE_NUMBER) {
  72. do {
  73. c = state->json[state->pos];
  74. if((c < '0' || c > '9') && c != '.') {
  75. c = 0;
  76. } else {
  77. state->pos++;
  78. }
  79. } while(c);
  80. /* need to back one step since first char is already gone */
  81. state->vstart--;
  82. state->vlen = state->pos - state->vstart;
  83. }
  84. /* no other types for now... */
  85. }
  86. /*--------------------------------------------------------------------*/
  87. static void FUNCTION_ATTRIBUTE
  88. skip_ws(struct jsonparse_state *state)
  89. {
  90. char c;
  91. while(state->pos < state->len &&
  92. ((c = state->json[state->pos]) == ' ' || c == '\n')) {
  93. state->pos++;
  94. }
  95. }
  96. /*--------------------------------------------------------------------*/
  97. void FUNCTION_ATTRIBUTE
  98. jsonparse_setup(struct jsonparse_state *state, const char *json, int len)
  99. {
  100. state->json = json;
  101. state->len = len;
  102. state->pos = 0;
  103. state->depth = 0;
  104. state->error = 0;
  105. state->stack[0] = 0;
  106. }
  107. /*--------------------------------------------------------------------*/
  108. int FUNCTION_ATTRIBUTE
  109. jsonparse_next(struct jsonparse_state *state)
  110. {
  111. char c;
  112. char s;
  113. skip_ws(state);
  114. c = state->json[state->pos];
  115. s = jsonparse_get_type(state);
  116. state->pos++;
  117. switch(c) {
  118. case '{':
  119. push(state, c);
  120. return c;
  121. case '}':
  122. if(s == ':' && state->vtype != 0) {
  123. /* printf("Popping vtype: '%c'\n", state->vtype); */
  124. pop(state);
  125. s = jsonparse_get_type(state);
  126. }
  127. if(s == '{') {
  128. pop(state);
  129. } else {
  130. state->error = JSON_ERROR_SYNTAX;
  131. return JSON_TYPE_ERROR;
  132. }
  133. return c;
  134. case ']':
  135. if(s == '[') {
  136. pop(state);
  137. } else {
  138. state->error = JSON_ERROR_UNEXPECTED_END_OF_ARRAY;
  139. return JSON_TYPE_ERROR;
  140. }
  141. return c;
  142. case ':':
  143. push(state, c);
  144. return c;
  145. case ',':
  146. /* if x:y ... , */
  147. if(s == ':' && state->vtype != 0) {
  148. pop(state);
  149. } else if(s == '[') {
  150. /* ok! */
  151. } else {
  152. state->error = JSON_ERROR_SYNTAX;
  153. return JSON_TYPE_ERROR;
  154. }
  155. return c;
  156. case '"':
  157. if(s == '{' || s == '[' || s == ':') {
  158. atomic(state, c = (s == '{' ? JSON_TYPE_PAIR_NAME : c));
  159. } else {
  160. state->error = JSON_ERROR_UNEXPECTED_STRING;
  161. return JSON_TYPE_ERROR;
  162. }
  163. return c;
  164. case '[':
  165. if(s == '{' || s == '[' || s == ':') {
  166. push(state, c);
  167. } else {
  168. state->error = JSON_ERROR_UNEXPECTED_ARRAY;
  169. return JSON_TYPE_ERROR;
  170. }
  171. return c;
  172. default:
  173. if(s == ':' || s == '[') {
  174. if(c <= '9' && c >= '0') {
  175. atomic(state, JSON_TYPE_NUMBER);
  176. return JSON_TYPE_NUMBER;
  177. }
  178. }
  179. }
  180. return 0;
  181. }
  182. /*--------------------------------------------------------------------*/
  183. /* get the json value of the current position
  184. * works only on "atomic" values such as string, number, null, false, true
  185. */
  186. /*--------------------------------------------------------------------*/
  187. int FUNCTION_ATTRIBUTE
  188. jsonparse_copy_value(struct jsonparse_state *state, char *str, int size)
  189. {
  190. int i;
  191. if(state->vtype == 0) {
  192. return 0;
  193. }
  194. size = size <= state->vlen ? (size - 1) : state->vlen;
  195. for(i = 0; i < size; i++) {
  196. str[i] = state->json[state->vstart + i];
  197. }
  198. str[i] = 0;
  199. return state->vtype;
  200. }
  201. /*--------------------------------------------------------------------*/
  202. int FUNCTION_ATTRIBUTE
  203. jsonparse_get_value_as_int(struct jsonparse_state *state)
  204. {
  205. if(state->vtype != JSON_TYPE_NUMBER) {
  206. return 0;
  207. }
  208. return atoi(&state->json[state->vstart]);
  209. }
  210. /*--------------------------------------------------------------------*/
  211. long FUNCTION_ATTRIBUTE
  212. jsonparse_get_value_as_long(struct jsonparse_state *state)
  213. {
  214. if(state->vtype != JSON_TYPE_NUMBER) {
  215. return 0;
  216. }
  217. return atol(&state->json[state->vstart]);
  218. }
  219. /*--------------------------------------------------------------------*/
  220. /* strcmp - assume no strange chars that needs to be stuffed in string... */
  221. /*--------------------------------------------------------------------*/
  222. int FUNCTION_ATTRIBUTE
  223. jsonparse_strcmp_value(struct jsonparse_state *state, const char *str)
  224. {
  225. if(state->vtype == 0) {
  226. return -1;
  227. }
  228. return strncmp(str, &state->json[state->vstart], state->vlen);
  229. }
  230. /*--------------------------------------------------------------------*/
  231. int FUNCTION_ATTRIBUTE
  232. jsonparse_get_len(struct jsonparse_state *state)
  233. {
  234. return state->vlen;
  235. }
  236. /*--------------------------------------------------------------------*/
  237. int FUNCTION_ATTRIBUTE
  238. jsonparse_get_type(struct jsonparse_state *state)
  239. {
  240. if(state->depth == 0) {
  241. return 0;
  242. }
  243. return state->stack[state->depth - 1];
  244. }
  245. /*--------------------------------------------------------------------*/
  246. int FUNCTION_ATTRIBUTE
  247. jsonparse_has_next(struct jsonparse_state *state)
  248. {
  249. return state->pos < state->len;
  250. }
  251. /*--------------------------------------------------------------------*/