json.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /*
  2. * Copyright (c) 2017 Intel Corporation
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <sys/__assert.h>
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <limits.h>
  10. #include <sys/printk.h>
  11. #include <sys/util.h>
  12. #include <stdbool.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <zephyr/types.h>
  16. #include <data/json.h>
  17. struct token {
  18. enum json_tokens type;
  19. char *start;
  20. char *end;
  21. };
  22. struct lexer {
  23. void *(*state)(struct lexer *lexer);
  24. char *start;
  25. char *pos;
  26. char *end;
  27. struct token token;
  28. };
  29. struct json_obj {
  30. struct lexer lexer;
  31. };
  32. struct json_obj_key_value {
  33. const char *key;
  34. size_t key_len;
  35. struct token value;
  36. };
  37. static bool lexer_consume(struct lexer *lexer, struct token *token,
  38. enum json_tokens empty_token)
  39. {
  40. if (lexer->token.type == empty_token) {
  41. return false;
  42. }
  43. *token = lexer->token;
  44. lexer->token.type = empty_token;
  45. return true;
  46. }
  47. static bool lexer_next(struct lexer *lexer, struct token *token)
  48. {
  49. while (lexer->state) {
  50. if (lexer_consume(lexer, token, JSON_TOK_NONE)) {
  51. return true;
  52. }
  53. lexer->state = lexer->state(lexer);
  54. }
  55. return lexer_consume(lexer, token, JSON_TOK_EOF);
  56. }
  57. static void *lexer_json(struct lexer *lexer);
  58. static void emit(struct lexer *lexer, enum json_tokens token)
  59. {
  60. lexer->token.type = token;
  61. lexer->token.start = lexer->start;
  62. lexer->token.end = lexer->pos;
  63. lexer->start = lexer->pos;
  64. }
  65. static int next(struct lexer *lexer)
  66. {
  67. if (lexer->pos >= lexer->end) {
  68. lexer->pos = lexer->end + 1;
  69. return '\0';
  70. }
  71. return *lexer->pos++;
  72. }
  73. static void ignore(struct lexer *lexer)
  74. {
  75. lexer->start = lexer->pos;
  76. }
  77. static void backup(struct lexer *lexer)
  78. {
  79. lexer->pos--;
  80. }
  81. static int peek(struct lexer *lexer)
  82. {
  83. int chr = next(lexer);
  84. backup(lexer);
  85. return chr;
  86. }
  87. static void *lexer_string(struct lexer *lexer)
  88. {
  89. ignore(lexer);
  90. while (true) {
  91. int chr = next(lexer);
  92. if (chr == '\0') {
  93. emit(lexer, JSON_TOK_ERROR);
  94. return NULL;
  95. }
  96. if (chr == '\\') {
  97. switch (next(lexer)) {
  98. case '"':
  99. case '\\':
  100. case '/':
  101. case 'b':
  102. case 'f':
  103. case 'n':
  104. case 'r':
  105. case 't':
  106. continue;
  107. case 'u':
  108. if (!isxdigit(next(lexer))) {
  109. goto error;
  110. }
  111. if (!isxdigit(next(lexer))) {
  112. goto error;
  113. }
  114. if (!isxdigit(next(lexer))) {
  115. goto error;
  116. }
  117. if (!isxdigit(next(lexer))) {
  118. goto error;
  119. }
  120. break;
  121. default:
  122. goto error;
  123. }
  124. }
  125. if (chr == '"') {
  126. backup(lexer);
  127. emit(lexer, JSON_TOK_STRING);
  128. next(lexer);
  129. ignore(lexer);
  130. return lexer_json;
  131. }
  132. }
  133. error:
  134. emit(lexer, JSON_TOK_ERROR);
  135. return NULL;
  136. }
  137. static int accept_run(struct lexer *lexer, const char *run)
  138. {
  139. for (; *run; run++) {
  140. if (next(lexer) != *run) {
  141. return -EINVAL;
  142. }
  143. }
  144. return 0;
  145. }
  146. static void *lexer_boolean(struct lexer *lexer)
  147. {
  148. backup(lexer);
  149. switch (next(lexer)) {
  150. case 't':
  151. if (!accept_run(lexer, "rue")) {
  152. emit(lexer, JSON_TOK_TRUE);
  153. return lexer_json;
  154. }
  155. break;
  156. case 'f':
  157. if (!accept_run(lexer, "alse")) {
  158. emit(lexer, JSON_TOK_FALSE);
  159. return lexer_json;
  160. }
  161. break;
  162. }
  163. emit(lexer, JSON_TOK_ERROR);
  164. return NULL;
  165. }
  166. static void *lexer_null(struct lexer *lexer)
  167. {
  168. if (accept_run(lexer, "ull") < 0) {
  169. emit(lexer, JSON_TOK_ERROR);
  170. return NULL;
  171. }
  172. emit(lexer, JSON_TOK_NULL);
  173. return lexer_json;
  174. }
  175. static void *lexer_number(struct lexer *lexer)
  176. {
  177. while (true) {
  178. int chr = next(lexer);
  179. if (isdigit(chr) || chr == '.') {
  180. continue;
  181. }
  182. backup(lexer);
  183. emit(lexer, JSON_TOK_NUMBER);
  184. return lexer_json;
  185. }
  186. }
  187. static void *lexer_json(struct lexer *lexer)
  188. {
  189. while (true) {
  190. int chr = next(lexer);
  191. switch (chr) {
  192. case '\0':
  193. emit(lexer, JSON_TOK_EOF);
  194. return NULL;
  195. case '}':
  196. case '{':
  197. case '[':
  198. case ']':
  199. case ',':
  200. case ':':
  201. emit(lexer, (enum json_tokens)chr);
  202. return lexer_json;
  203. case '"':
  204. return lexer_string;
  205. case 'n':
  206. return lexer_null;
  207. case 't':
  208. case 'f':
  209. return lexer_boolean;
  210. case '-':
  211. if (isdigit(peek(lexer))) {
  212. return lexer_number;
  213. }
  214. __fallthrough;
  215. default:
  216. if (isspace(chr)) {
  217. ignore(lexer);
  218. continue;
  219. }
  220. if (isdigit(chr)) {
  221. return lexer_number;
  222. }
  223. emit(lexer, JSON_TOK_ERROR);
  224. return NULL;
  225. }
  226. }
  227. }
  228. static void lexer_init(struct lexer *lexer, char *data, size_t len)
  229. {
  230. lexer->state = lexer_json;
  231. lexer->start = data;
  232. lexer->pos = data;
  233. lexer->end = data + len;
  234. lexer->token.type = JSON_TOK_NONE;
  235. }
  236. static int obj_init(struct json_obj *json, char *data, size_t len)
  237. {
  238. struct token token;
  239. lexer_init(&json->lexer, data, len);
  240. if (!lexer_next(&json->lexer, &token)) {
  241. return -EINVAL;
  242. }
  243. if (token.type != JSON_TOK_OBJECT_START) {
  244. return -EINVAL;
  245. }
  246. return 0;
  247. }
  248. static int element_token(enum json_tokens token)
  249. {
  250. switch (token) {
  251. case JSON_TOK_OBJECT_START:
  252. case JSON_TOK_LIST_START:
  253. case JSON_TOK_STRING:
  254. case JSON_TOK_NUMBER:
  255. case JSON_TOK_TRUE:
  256. case JSON_TOK_FALSE:
  257. return 0;
  258. default:
  259. return -EINVAL;
  260. }
  261. }
  262. static int obj_next(struct json_obj *json,
  263. struct json_obj_key_value *kv)
  264. {
  265. struct token token;
  266. if (!lexer_next(&json->lexer, &token)) {
  267. return -EINVAL;
  268. }
  269. /* Match end of object or next key */
  270. switch (token.type) {
  271. case JSON_TOK_OBJECT_END:
  272. kv->key = NULL;
  273. kv->key_len = 0;
  274. kv->value = token;
  275. return 0;
  276. case JSON_TOK_COMMA:
  277. if (!lexer_next(&json->lexer, &token)) {
  278. return -EINVAL;
  279. }
  280. if (token.type != JSON_TOK_STRING) {
  281. return -EINVAL;
  282. }
  283. __fallthrough;
  284. case JSON_TOK_STRING:
  285. kv->key = token.start;
  286. kv->key_len = (size_t)(token.end - token.start);
  287. break;
  288. default:
  289. return -EINVAL;
  290. }
  291. /* Match : after key */
  292. if (!lexer_next(&json->lexer, &token)) {
  293. return -EINVAL;
  294. }
  295. if (token.type != JSON_TOK_COLON) {
  296. return -EINVAL;
  297. }
  298. /* Match value */
  299. if (!lexer_next(&json->lexer, &kv->value)) {
  300. return -EINVAL;
  301. }
  302. return element_token(kv->value.type);
  303. }
  304. static int arr_next(struct json_obj *json, struct token *value)
  305. {
  306. if (!lexer_next(&json->lexer, value)) {
  307. return -EINVAL;
  308. }
  309. if (value->type == JSON_TOK_LIST_END) {
  310. return 0;
  311. }
  312. if (value->type == JSON_TOK_COMMA) {
  313. if (!lexer_next(&json->lexer, value)) {
  314. return -EINVAL;
  315. }
  316. }
  317. return element_token(value->type);
  318. }
  319. static int decode_num(const struct token *token, int32_t *num)
  320. {
  321. /* FIXME: strtod() is not available in newlib/minimal libc,
  322. * so using strtol() here.
  323. */
  324. char *endptr;
  325. char prev_end;
  326. prev_end = *token->end;
  327. *token->end = '\0';
  328. errno = 0;
  329. *num = strtol(token->start, &endptr, 10);
  330. *token->end = prev_end;
  331. if (errno != 0) {
  332. return -errno;
  333. }
  334. if (endptr != token->end) {
  335. return -EINVAL;
  336. }
  337. return 0;
  338. }
  339. static bool equivalent_types(enum json_tokens type1, enum json_tokens type2)
  340. {
  341. if (type1 == JSON_TOK_TRUE || type1 == JSON_TOK_FALSE) {
  342. return type2 == JSON_TOK_TRUE || type2 == JSON_TOK_FALSE;
  343. }
  344. return type1 == type2;
  345. }
  346. static int obj_parse(struct json_obj *obj,
  347. const struct json_obj_descr *descr, size_t descr_len,
  348. void *val);
  349. static int arr_parse(struct json_obj *obj,
  350. const struct json_obj_descr *elem_descr,
  351. size_t max_elements, void *field, void *val);
  352. static int decode_value(struct json_obj *obj,
  353. const struct json_obj_descr *descr,
  354. struct token *value, void *field, void *val)
  355. {
  356. if (!equivalent_types(value->type, descr->type)) {
  357. return -EINVAL;
  358. }
  359. switch (descr->type) {
  360. case JSON_TOK_OBJECT_START:
  361. return obj_parse(obj, descr->object.sub_descr,
  362. descr->object.sub_descr_len,
  363. field);
  364. case JSON_TOK_LIST_START:
  365. return arr_parse(obj, descr->array.element_descr,
  366. descr->array.n_elements, field, val);
  367. case JSON_TOK_FALSE:
  368. case JSON_TOK_TRUE: {
  369. bool *v = field;
  370. *v = value->type == JSON_TOK_TRUE;
  371. return 0;
  372. }
  373. case JSON_TOK_NUMBER: {
  374. int32_t *num = field;
  375. return decode_num(value, num);
  376. }
  377. case JSON_TOK_STRING: {
  378. char **str = field;
  379. *value->end = '\0';
  380. *str = value->start;
  381. return 0;
  382. }
  383. default:
  384. return -EINVAL;
  385. }
  386. }
  387. static ptrdiff_t get_elem_size(const struct json_obj_descr *descr)
  388. {
  389. switch (descr->type) {
  390. case JSON_TOK_NUMBER:
  391. return sizeof(int32_t);
  392. case JSON_TOK_STRING:
  393. return sizeof(char *);
  394. case JSON_TOK_TRUE:
  395. case JSON_TOK_FALSE:
  396. return sizeof(bool);
  397. case JSON_TOK_LIST_START:
  398. return descr->array.n_elements * get_elem_size(descr->array.element_descr);
  399. case JSON_TOK_OBJECT_START: {
  400. ptrdiff_t total = 0;
  401. size_t i;
  402. for (i = 0; i < descr->object.sub_descr_len; i++) {
  403. ptrdiff_t s = get_elem_size(&descr->object.sub_descr[i]);
  404. total += ROUND_UP(s, 1 << descr->align_shift);
  405. }
  406. return total;
  407. }
  408. default:
  409. return -EINVAL;
  410. }
  411. }
  412. static int arr_parse(struct json_obj *obj,
  413. const struct json_obj_descr *elem_descr,
  414. size_t max_elements, void *field, void *val)
  415. {
  416. ptrdiff_t elem_size = get_elem_size(elem_descr);
  417. void *last_elem = (char *)field + elem_size * max_elements;
  418. size_t *elements = NULL;
  419. struct token value;
  420. if (val) {
  421. elements = (size_t *)((char *)val + elem_descr->offset);
  422. }
  423. __ASSERT_NO_MSG(elem_size > 0);
  424. if (elements) {
  425. *elements = 0;
  426. }
  427. while (!arr_next(obj, &value)) {
  428. if (value.type == JSON_TOK_LIST_END) {
  429. return 0;
  430. }
  431. if (field == last_elem) {
  432. return -ENOSPC;
  433. }
  434. if (decode_value(obj, elem_descr, &value, field, NULL) < 0) {
  435. return -EINVAL;
  436. }
  437. if (elements) {
  438. (*elements)++;
  439. }
  440. field = (char *)field + elem_size;
  441. }
  442. return -EINVAL;
  443. }
  444. static int obj_parse(struct json_obj *obj, const struct json_obj_descr *descr,
  445. size_t descr_len, void *val)
  446. {
  447. struct json_obj_key_value kv;
  448. int32_t decoded_fields = 0;
  449. size_t i;
  450. int ret;
  451. while (!obj_next(obj, &kv)) {
  452. if (kv.value.type == JSON_TOK_OBJECT_END) {
  453. return decoded_fields;
  454. }
  455. for (i = 0; i < descr_len; i++) {
  456. void *decode_field = (char *)val + descr[i].offset;
  457. /* Field has been decoded already, skip */
  458. if (decoded_fields & (1 << i)) {
  459. continue;
  460. }
  461. /* Check if it's the i-th field */
  462. if (kv.key_len != descr[i].field_name_len) {
  463. continue;
  464. }
  465. if (memcmp(kv.key, descr[i].field_name,
  466. descr[i].field_name_len)) {
  467. continue;
  468. }
  469. /* Store the decoded value */
  470. ret = decode_value(obj, &descr[i], &kv.value,
  471. decode_field, val);
  472. if (ret < 0) {
  473. return ret;
  474. }
  475. decoded_fields |= 1<<i;
  476. break;
  477. }
  478. }
  479. return -EINVAL;
  480. }
  481. int json_obj_parse(char *payload, size_t len,
  482. const struct json_obj_descr *descr, size_t descr_len,
  483. void *val)
  484. {
  485. struct json_obj obj;
  486. int ret;
  487. __ASSERT_NO_MSG(descr_len < (sizeof(ret) * CHAR_BIT - 1));
  488. ret = obj_init(&obj, payload, len);
  489. if (ret < 0) {
  490. return ret;
  491. }
  492. return obj_parse(&obj, descr, descr_len, val);
  493. }
  494. static char escape_as(char chr)
  495. {
  496. switch (chr) {
  497. case '"':
  498. return '"';
  499. case '\\':
  500. return '\\';
  501. case '\b':
  502. return 'b';
  503. case '\f':
  504. return 'f';
  505. case '\n':
  506. return 'n';
  507. case '\r':
  508. return 'r';
  509. case '\t':
  510. return 't';
  511. }
  512. return 0;
  513. }
  514. static int json_escape_internal(const char *str,
  515. json_append_bytes_t append_bytes,
  516. void *data)
  517. {
  518. const char *cur;
  519. int ret = 0;
  520. for (cur = str; ret == 0 && *cur; cur++) {
  521. char escaped = escape_as(*cur);
  522. if (escaped) {
  523. char bytes[2] = { '\\', escaped };
  524. ret = append_bytes(bytes, 2, data);
  525. } else {
  526. ret = append_bytes(cur, 1, data);
  527. }
  528. }
  529. return ret;
  530. }
  531. size_t json_calc_escaped_len(const char *str, size_t len)
  532. {
  533. size_t escaped_len = len;
  534. size_t pos;
  535. for (pos = 0; pos < len; pos++) {
  536. if (escape_as(str[pos])) {
  537. escaped_len++;
  538. }
  539. }
  540. return escaped_len;
  541. }
  542. ssize_t json_escape(char *str, size_t *len, size_t buf_size)
  543. {
  544. char *next; /* Points after next character to escape. */
  545. char *dest; /* Points after next place to write escaped character. */
  546. size_t escaped_len = json_calc_escaped_len(str, *len);
  547. if (escaped_len == *len) {
  548. /*
  549. * If no escape is necessary, there is nothing to do.
  550. */
  551. return 0;
  552. }
  553. if (escaped_len >= buf_size) {
  554. return -ENOMEM;
  555. }
  556. /*
  557. * By walking backwards in the buffer from the end positions
  558. * of both the original and escaped strings, we avoid using
  559. * extra space. Characters in the original string are
  560. * overwritten only after they have already been escaped.
  561. */
  562. str[escaped_len] = '\0';
  563. for (next = &str[*len], dest = &str[escaped_len]; next != str;) {
  564. char next_c = *(--next);
  565. char escape = escape_as(next_c);
  566. if (escape) {
  567. *(--dest) = escape;
  568. *(--dest) = '\\';
  569. } else {
  570. *(--dest) = next_c;
  571. }
  572. }
  573. *len = escaped_len;
  574. return 0;
  575. }
  576. static int encode(const struct json_obj_descr *descr, const void *val,
  577. json_append_bytes_t append_bytes, void *data);
  578. static int arr_encode(const struct json_obj_descr *elem_descr,
  579. const void *field, const void *val,
  580. json_append_bytes_t append_bytes, void *data)
  581. {
  582. ptrdiff_t elem_size = get_elem_size(elem_descr);
  583. /*
  584. * NOTE: Since an element descriptor's offset isn't meaningful
  585. * (array elements occur at multiple offsets in `val'), we use
  586. * its space in elem_descr to store the offset to the field
  587. * containing the number of elements.
  588. */
  589. size_t n_elem = *(size_t *)((char *)val + elem_descr->offset);
  590. size_t i;
  591. int ret;
  592. ret = append_bytes("[", 1, data);
  593. if (ret < 0) {
  594. return ret;
  595. }
  596. for (i = 0; i < n_elem; i++) {
  597. /*
  598. * Though "field" points at the next element in the
  599. * array which we need to encode, the value in
  600. * elem_descr->offset is actually the offset of the
  601. * length field in the "parent" struct containing the
  602. * array.
  603. *
  604. * To patch things up, we lie to encode() about where
  605. * the field is by exactly the amount it will offset
  606. * it. This is a size optimization for struct
  607. * json_obj_descr: the alternative is to keep a
  608. * separate field next to element_descr which is an
  609. * offset to the length field in the parent struct,
  610. * but that would add a size_t to every descriptor.
  611. */
  612. ret = encode(elem_descr, (char *)field - elem_descr->offset,
  613. append_bytes, data);
  614. if (ret < 0) {
  615. return ret;
  616. }
  617. if (i < n_elem - 1) {
  618. ret = append_bytes(",", 1, data);
  619. if (ret < 0) {
  620. return ret;
  621. }
  622. }
  623. field = (char *)field + elem_size;
  624. }
  625. return append_bytes("]", 1, data);
  626. }
  627. static int str_encode(const char **str, json_append_bytes_t append_bytes,
  628. void *data)
  629. {
  630. int ret;
  631. ret = append_bytes("\"", 1, data);
  632. if (ret < 0) {
  633. return ret;
  634. }
  635. ret = json_escape_internal(*str, append_bytes, data);
  636. if (!ret) {
  637. return append_bytes("\"", 1, data);
  638. }
  639. return ret;
  640. }
  641. static int num_encode(const int32_t *num, json_append_bytes_t append_bytes,
  642. void *data)
  643. {
  644. char buf[3 * sizeof(int32_t)];
  645. int ret;
  646. ret = snprintk(buf, sizeof(buf), "%d", *num);
  647. if (ret < 0) {
  648. return ret;
  649. }
  650. if (ret >= (int)sizeof(buf)) {
  651. return -ENOMEM;
  652. }
  653. return append_bytes(buf, (size_t)ret, data);
  654. }
  655. static int bool_encode(const bool *value, json_append_bytes_t append_bytes,
  656. void *data)
  657. {
  658. if (*value) {
  659. return append_bytes("true", 4, data);
  660. }
  661. return append_bytes("false", 5, data);
  662. }
  663. static int encode(const struct json_obj_descr *descr, const void *val,
  664. json_append_bytes_t append_bytes, void *data)
  665. {
  666. void *ptr = (char *)val + descr->offset;
  667. switch (descr->type) {
  668. case JSON_TOK_FALSE:
  669. case JSON_TOK_TRUE:
  670. return bool_encode(ptr, append_bytes, data);
  671. case JSON_TOK_STRING:
  672. return str_encode(ptr, append_bytes, data);
  673. case JSON_TOK_LIST_START:
  674. return arr_encode(descr->array.element_descr, ptr,
  675. val, append_bytes, data);
  676. case JSON_TOK_OBJECT_START:
  677. return json_obj_encode(descr->object.sub_descr,
  678. descr->object.sub_descr_len,
  679. ptr, append_bytes, data);
  680. case JSON_TOK_NUMBER:
  681. return num_encode(ptr, append_bytes, data);
  682. default:
  683. return -EINVAL;
  684. }
  685. }
  686. int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
  687. const void *val, json_append_bytes_t append_bytes,
  688. void *data)
  689. {
  690. size_t i;
  691. int ret;
  692. ret = append_bytes("{", 1, data);
  693. if (ret < 0) {
  694. return ret;
  695. }
  696. for (i = 0; i < descr_len; i++) {
  697. ret = str_encode((const char **)&descr[i].field_name,
  698. append_bytes, data);
  699. if (ret < 0) {
  700. return ret;
  701. }
  702. ret = append_bytes(":", 1, data);
  703. if (ret < 0) {
  704. return ret;
  705. }
  706. ret = encode(&descr[i], val, append_bytes, data);
  707. if (ret < 0) {
  708. return ret;
  709. }
  710. if (i < descr_len - 1) {
  711. ret = append_bytes(",", 1, data);
  712. if (ret < 0) {
  713. return ret;
  714. }
  715. }
  716. }
  717. return append_bytes("}", 1, data);
  718. }
  719. int json_arr_encode(const struct json_obj_descr *descr, const void *val,
  720. json_append_bytes_t append_bytes, void *data)
  721. {
  722. void *ptr = (char *)val + descr->offset;
  723. return arr_encode(descr->array.element_descr, ptr, val, append_bytes,
  724. data);
  725. }
  726. struct appender {
  727. char *buffer;
  728. size_t used;
  729. size_t size;
  730. };
  731. static int append_bytes_to_buf(const char *bytes, size_t len, void *data)
  732. {
  733. struct appender *appender = data;
  734. if (len >= appender->size - appender->used) {
  735. return -ENOMEM;
  736. }
  737. memcpy(appender->buffer + appender->used, bytes, len);
  738. appender->used += len;
  739. appender->buffer[appender->used] = '\0';
  740. return 0;
  741. }
  742. int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
  743. const void *val, char *buffer, size_t buf_size)
  744. {
  745. struct appender appender = { .buffer = buffer, .size = buf_size };
  746. return json_obj_encode(descr, descr_len, val, append_bytes_to_buf,
  747. &appender);
  748. }
  749. int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
  750. char *buffer, size_t buf_size)
  751. {
  752. struct appender appender = { .buffer = buffer, .size = buf_size };
  753. return json_arr_encode(descr, val, append_bytes_to_buf, &appender);
  754. }
  755. static int measure_bytes(const char *bytes, size_t len, void *data)
  756. {
  757. ssize_t *total = data;
  758. *total += (ssize_t)len;
  759. ARG_UNUSED(bytes);
  760. return 0;
  761. }
  762. ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
  763. size_t descr_len, const void *val)
  764. {
  765. ssize_t total = 0;
  766. int ret;
  767. ret = json_obj_encode(descr, descr_len, val, measure_bytes, &total);
  768. if (ret < 0) {
  769. return ret;
  770. }
  771. return total;
  772. }