attr_container.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "bi-inc/attr_container.h"
  6. typedef union jvalue {
  7. bool z;
  8. int8_t b;
  9. uint16_t c;
  10. int16_t s;
  11. int32_t i;
  12. int64_t j;
  13. float f;
  14. double d;
  15. } jvalue;
  16. static inline int16_t
  17. get_int16(const char *buf)
  18. {
  19. int16_t ret;
  20. bh_memcpy_s(&ret, sizeof(int16_t), buf, sizeof(int16_t));
  21. return ret;
  22. }
  23. static inline uint16_t
  24. get_uint16(const char *buf)
  25. {
  26. return get_int16(buf);
  27. }
  28. static inline int32_t
  29. get_int32(const char *buf)
  30. {
  31. int32_t ret;
  32. bh_memcpy_s(&ret, sizeof(int32_t), buf, sizeof(int32_t));
  33. return ret;
  34. }
  35. static inline uint32_t
  36. get_uint32(const char *buf)
  37. {
  38. return get_int32(buf);
  39. }
  40. static inline int64_t
  41. get_int64(const char *buf)
  42. {
  43. int64_t ret;
  44. bh_memcpy_s(&ret, sizeof(int64_t), buf, sizeof(int64_t));
  45. return ret;
  46. }
  47. static inline uint64_t
  48. get_uint64(const char *buf)
  49. {
  50. return get_int64(buf);
  51. }
  52. static inline void
  53. set_int16(char *buf, int16_t v)
  54. {
  55. bh_memcpy_s(buf, sizeof(int16_t), &v, sizeof(int16_t));
  56. }
  57. static inline void
  58. set_uint16(char *buf, uint16_t v)
  59. {
  60. bh_memcpy_s(buf, sizeof(uint16_t), &v, sizeof(uint16_t));
  61. }
  62. static inline void
  63. set_int32(char *buf, int32_t v)
  64. {
  65. bh_memcpy_s(buf, sizeof(int32_t), &v, sizeof(int32_t));
  66. }
  67. static inline void
  68. set_uint32(char *buf, uint32_t v)
  69. {
  70. bh_memcpy_s(buf, sizeof(uint32_t), &v, sizeof(uint32_t));
  71. }
  72. static inline void
  73. set_int64(char *buf, int64_t v)
  74. {
  75. bh_memcpy_s(buf, sizeof(int64_t), &v, sizeof(int64_t));
  76. }
  77. static inline void
  78. set_uint64(char *buf, uint64_t v)
  79. {
  80. bh_memcpy_s(buf, sizeof(uint64_t), &v, sizeof(uint64_t));
  81. }
  82. char *
  83. attr_container_get_attr_begin(const attr_container_t *attr_cont,
  84. uint32_t *p_total_length, uint16_t *p_attr_num)
  85. {
  86. char *p = (char *)attr_cont->buf;
  87. uint16_t str_len, attr_num;
  88. uint32_t total_length;
  89. /* skip total length */
  90. total_length = get_uint32(p);
  91. p += sizeof(uint32_t);
  92. if (!total_length)
  93. return NULL;
  94. /* tag length */
  95. str_len = get_uint16(p);
  96. p += sizeof(uint16_t);
  97. if (!str_len)
  98. return NULL;
  99. /* tag content */
  100. p += str_len;
  101. if ((uint32_t)(p - attr_cont->buf) >= total_length)
  102. return NULL;
  103. /* attribute num */
  104. attr_num = get_uint16(p);
  105. p += sizeof(uint16_t);
  106. if ((uint32_t)(p - attr_cont->buf) >= total_length)
  107. return NULL;
  108. if (p_total_length)
  109. *p_total_length = total_length;
  110. if (p_attr_num)
  111. *p_attr_num = attr_num;
  112. /* first attribute */
  113. return p;
  114. }
  115. static char *
  116. attr_container_get_attr_next(const char *curr_attr)
  117. {
  118. char *p = (char *)curr_attr;
  119. uint8_t type;
  120. /* key length and key */
  121. p += sizeof(uint16_t) + get_uint16(p);
  122. type = *p++;
  123. /* Short type to Boolean type */
  124. if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN) {
  125. p += 1 << (type & 3);
  126. return p;
  127. }
  128. /* String type */
  129. else if (type == ATTR_TYPE_STRING) {
  130. p += sizeof(uint16_t) + get_uint16(p);
  131. return p;
  132. }
  133. /* ByteArray type */
  134. else if (type == ATTR_TYPE_BYTEARRAY) {
  135. p += sizeof(uint32_t) + get_uint32(p);
  136. return p;
  137. }
  138. return NULL;
  139. }
  140. static const char *
  141. attr_container_find_attr(const attr_container_t *attr_cont, const char *key)
  142. {
  143. uint32_t total_length;
  144. uint16_t str_len, attr_num, i;
  145. const char *p = attr_cont->buf;
  146. if (!key)
  147. return NULL;
  148. if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
  149. &attr_num)))
  150. return NULL;
  151. for (i = 0; i < attr_num; i++) {
  152. /* key length */
  153. if (!(str_len = get_uint16(p)))
  154. return NULL;
  155. if (str_len == strlen(key) + 1
  156. && memcmp(p + sizeof(uint16_t), key, str_len) == 0) {
  157. if ((uint32_t)(p + sizeof(uint16_t) + str_len - attr_cont->buf)
  158. >= total_length)
  159. return NULL;
  160. return p;
  161. }
  162. if (!(p = attr_container_get_attr_next(p)))
  163. return NULL;
  164. }
  165. return NULL;
  166. }
  167. char *
  168. attr_container_get_attr_end(const attr_container_t *attr_cont)
  169. {
  170. uint32_t total_length;
  171. uint16_t attr_num, i;
  172. char *p;
  173. if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
  174. &attr_num)))
  175. return NULL;
  176. for (i = 0; i < attr_num; i++)
  177. if (!(p = attr_container_get_attr_next(p)))
  178. return NULL;
  179. return p;
  180. }
  181. static char *
  182. attr_container_get_msg_end(attr_container_t *attr_cont)
  183. {
  184. char *p = attr_cont->buf;
  185. return p + get_uint32(p);
  186. }
  187. uint16_t
  188. attr_container_get_attr_num(const attr_container_t *attr_cont)
  189. {
  190. uint16_t str_len;
  191. /* skip total length */
  192. const char *p = attr_cont->buf + sizeof(uint32_t);
  193. str_len = get_uint16(p);
  194. /* skip tag length and tag */
  195. p += sizeof(uint16_t) + str_len;
  196. /* attribute num */
  197. return get_uint16(p);
  198. }
  199. static void
  200. attr_container_inc_attr_num(attr_container_t *attr_cont)
  201. {
  202. uint16_t str_len, attr_num;
  203. /* skip total length */
  204. char *p = attr_cont->buf + sizeof(uint32_t);
  205. str_len = get_uint16(p);
  206. /* skip tag length and tag */
  207. p += sizeof(uint16_t) + str_len;
  208. /* attribute num */
  209. attr_num = get_uint16(p) + 1;
  210. set_uint16(p, attr_num);
  211. }
  212. attr_container_t *
  213. attr_container_create(const char *tag)
  214. {
  215. attr_container_t *attr_cont;
  216. int length, tag_length;
  217. char *p;
  218. tag_length = tag ? strlen(tag) + 1 : 1;
  219. length = offsetof(attr_container_t, buf) +
  220. /* total length + tag length + tag + reserved 100 bytes */
  221. sizeof(uint32_t) + sizeof(uint16_t) + tag_length + 100;
  222. if (!(attr_cont = attr_container_malloc(length))) {
  223. attr_container_printf(
  224. "Create attr_container failed: allocate memory failed.\r\n");
  225. return NULL;
  226. }
  227. memset(attr_cont, 0, length);
  228. p = attr_cont->buf;
  229. /* total length */
  230. set_uint32(p, length - offsetof(attr_container_t, buf));
  231. p += 4;
  232. /* tag length, tag */
  233. set_uint16(p, tag_length);
  234. p += 2;
  235. if (tag)
  236. bh_memcpy_s(p, tag_length, tag, tag_length);
  237. return attr_cont;
  238. }
  239. void
  240. attr_container_destroy(const attr_container_t *attr_cont)
  241. {
  242. if (attr_cont)
  243. attr_container_free((char *)attr_cont);
  244. }
  245. static bool
  246. check_set_attr(attr_container_t **p_attr_cont, const char *key)
  247. {
  248. uint32_t flags;
  249. if (!p_attr_cont || !*p_attr_cont || !key || strlen(key) == 0) {
  250. attr_container_printf(
  251. "Set attribute failed: invalid input arguments.\r\n");
  252. return false;
  253. }
  254. flags = get_uint32((char *)*p_attr_cont);
  255. if (flags & ATTR_CONT_READONLY_SHIFT) {
  256. attr_container_printf(
  257. "Set attribute failed: attribute container is readonly.\r\n");
  258. return false;
  259. }
  260. return true;
  261. }
  262. bool
  263. attr_container_set_attr(attr_container_t **p_attr_cont, const char *key,
  264. int type, const void *value, int value_length)
  265. {
  266. attr_container_t *attr_cont, *attr_cont1;
  267. uint16_t str_len;
  268. uint32_t total_length, attr_len;
  269. char *p, *p1, *attr_end, *msg_end, *attr_buf;
  270. if (!check_set_attr(p_attr_cont, key)) {
  271. return false;
  272. }
  273. attr_cont = *p_attr_cont;
  274. p = attr_cont->buf;
  275. total_length = get_uint32(p);
  276. if (!(attr_end = attr_container_get_attr_end(attr_cont))) {
  277. attr_container_printf("Set attr failed: get attr end failed.\r\n");
  278. return false;
  279. }
  280. msg_end = attr_container_get_msg_end(attr_cont);
  281. /* key len + key + '\0' + type */
  282. attr_len = sizeof(uint16_t) + strlen(key) + 1 + 1;
  283. if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN)
  284. attr_len += 1 << (type & 3);
  285. else if (type == ATTR_TYPE_STRING)
  286. attr_len += sizeof(uint16_t) + value_length;
  287. else if (type == ATTR_TYPE_BYTEARRAY)
  288. attr_len += sizeof(uint32_t) + value_length;
  289. if (!(p = attr_buf = attr_container_malloc(attr_len))) {
  290. attr_container_printf("Set attr failed: allocate memory failed.\r\n");
  291. return false;
  292. }
  293. /* Set the attr buf */
  294. str_len = (uint16_t)(strlen(key) + 1);
  295. set_uint16(p, str_len);
  296. p += sizeof(uint16_t);
  297. bh_memcpy_s(p, str_len, key, str_len);
  298. p += str_len;
  299. *p++ = type;
  300. if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN)
  301. bh_memcpy_s(p, 1 << (type & 3), value, 1 << (type & 3));
  302. else if (type == ATTR_TYPE_STRING) {
  303. set_uint16(p, value_length);
  304. p += sizeof(uint16_t);
  305. bh_memcpy_s(p, value_length, value, value_length);
  306. }
  307. else if (type == ATTR_TYPE_BYTEARRAY) {
  308. set_uint32(p, value_length);
  309. p += sizeof(uint32_t);
  310. bh_memcpy_s(p, value_length, value, value_length);
  311. }
  312. if ((p = (char *)attr_container_find_attr(attr_cont, key))) {
  313. /* key found */
  314. p1 = attr_container_get_attr_next(p);
  315. if (p1 - p == attr_len) {
  316. bh_memcpy_s(p, attr_len, attr_buf, attr_len);
  317. attr_container_free(attr_buf);
  318. return true;
  319. }
  320. if ((uint32_t)(p1 - p + msg_end - attr_end) >= attr_len) {
  321. memmove(p, p1, attr_end - p1);
  322. bh_memcpy_s(p + (attr_end - p1), attr_len, attr_buf, attr_len);
  323. attr_container_free(attr_buf);
  324. return true;
  325. }
  326. total_length += attr_len + 100;
  327. if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
  328. + total_length))) {
  329. attr_container_printf(
  330. "Set attr failed: allocate memory failed.\r\n");
  331. attr_container_free(attr_buf);
  332. return false;
  333. }
  334. bh_memcpy_s(attr_cont1, p - (char *)attr_cont, attr_cont,
  335. p - (char *)attr_cont);
  336. bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont),
  337. attr_end - p1, p1, attr_end - p1);
  338. bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont)
  339. + (unsigned)(attr_end - p1),
  340. attr_len, attr_buf, attr_len);
  341. p = attr_cont1->buf;
  342. set_uint32(p, total_length);
  343. *p_attr_cont = attr_cont1;
  344. /* Free original buffer */
  345. attr_container_free(attr_cont);
  346. attr_container_free(attr_buf);
  347. return true;
  348. }
  349. else {
  350. /* key not found */
  351. if ((uint32_t)(msg_end - attr_end) >= attr_len) {
  352. bh_memcpy_s(attr_end, msg_end - attr_end, attr_buf, attr_len);
  353. attr_container_inc_attr_num(attr_cont);
  354. attr_container_free(attr_buf);
  355. return true;
  356. }
  357. total_length += attr_len + 100;
  358. if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
  359. + total_length))) {
  360. attr_container_printf(
  361. "Set attr failed: allocate memory failed.\r\n");
  362. attr_container_free(attr_buf);
  363. return false;
  364. }
  365. bh_memcpy_s(attr_cont1, attr_end - (char *)attr_cont, attr_cont,
  366. attr_end - (char *)attr_cont);
  367. bh_memcpy_s((char *)attr_cont1
  368. + (unsigned)(attr_end - (char *)attr_cont),
  369. attr_len, attr_buf, attr_len);
  370. attr_container_inc_attr_num(attr_cont1);
  371. p = attr_cont1->buf;
  372. set_uint32(p, total_length);
  373. *p_attr_cont = attr_cont1;
  374. /* Free original buffer */
  375. attr_container_free(attr_cont);
  376. attr_container_free(attr_buf);
  377. return true;
  378. }
  379. return false;
  380. }
  381. bool
  382. attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
  383. short value)
  384. {
  385. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_SHORT, &value,
  386. 2);
  387. }
  388. bool
  389. attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
  390. int value)
  391. {
  392. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT, &value, 4);
  393. }
  394. bool
  395. attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
  396. int64_t value)
  397. {
  398. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT64, &value,
  399. 8);
  400. }
  401. bool
  402. attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
  403. int8_t value)
  404. {
  405. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTE, &value, 1);
  406. }
  407. bool
  408. attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
  409. uint16_t value)
  410. {
  411. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT16, &value,
  412. 2);
  413. }
  414. bool
  415. attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
  416. float value)
  417. {
  418. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_FLOAT, &value,
  419. 4);
  420. }
  421. bool
  422. attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
  423. double value)
  424. {
  425. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_DOUBLE, &value,
  426. 8);
  427. }
  428. bool
  429. attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
  430. bool value)
  431. {
  432. int8_t value1 = value ? 1 : 0;
  433. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BOOLEAN, &value1,
  434. 1);
  435. }
  436. bool
  437. attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
  438. const char *value)
  439. {
  440. if (!value) {
  441. attr_container_printf("Set attr failed: invald input arguments.\r\n");
  442. return false;
  443. }
  444. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_STRING, value,
  445. strlen(value) + 1);
  446. }
  447. bool
  448. attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
  449. const int8_t *value, unsigned length)
  450. {
  451. if (!value) {
  452. attr_container_printf("Set attr failed: invald input arguments.\r\n");
  453. return false;
  454. }
  455. return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTEARRAY, value,
  456. length);
  457. }
  458. static const char *
  459. attr_container_get_attr(const attr_container_t *attr_cont, const char *key)
  460. {
  461. const char *attr_addr;
  462. if (!attr_cont || !key) {
  463. attr_container_printf(
  464. "Get attribute failed: invalid input arguments.\r\n");
  465. return NULL;
  466. }
  467. if (!(attr_addr = attr_container_find_attr(attr_cont, key))) {
  468. attr_container_printf("Get attribute failed: lookup key failed.\r\n");
  469. return false;
  470. }
  471. /* key len + key + '\0' */
  472. return attr_addr + 2 + strlen(key) + 1;
  473. }
  474. #define TEMPLATE_ATTR_BUF_TO_VALUE(attr, key, var_name) \
  475. do { \
  476. jvalue val; \
  477. const char *addr = attr_container_get_attr(attr, key); \
  478. uint8_t type; \
  479. if (!addr) \
  480. return 0; \
  481. val.j = 0; \
  482. type = *(uint8_t *)addr++; \
  483. switch (type) { \
  484. case ATTR_TYPE_SHORT: \
  485. case ATTR_TYPE_INT: \
  486. case ATTR_TYPE_INT64: \
  487. case ATTR_TYPE_BYTE: \
  488. case ATTR_TYPE_UINT16: \
  489. case ATTR_TYPE_FLOAT: \
  490. case ATTR_TYPE_DOUBLE: \
  491. case ATTR_TYPE_BOOLEAN: \
  492. bh_memcpy_s(&val, sizeof(val.var_name), addr, \
  493. 1 << (type & 3)); \
  494. break; \
  495. case ATTR_TYPE_STRING: \
  496. { \
  497. unsigned len = get_uint16(addr); \
  498. addr += 2; \
  499. if (len > sizeof(val.var_name)) \
  500. len = sizeof(val.var_name); \
  501. bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
  502. break; \
  503. } \
  504. case ATTR_TYPE_BYTEARRAY: \
  505. { \
  506. unsigned len = get_uint32(addr); \
  507. addr += 4; \
  508. if (len > sizeof(val.var_name)) \
  509. len = sizeof(val.var_name); \
  510. bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
  511. break; \
  512. } \
  513. default: \
  514. bh_assert(0); \
  515. break; \
  516. } \
  517. return val.var_name; \
  518. } while (0)
  519. short
  520. attr_container_get_as_short(const attr_container_t *attr_cont, const char *key)
  521. {
  522. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, s);
  523. }
  524. int
  525. attr_container_get_as_int(const attr_container_t *attr_cont, const char *key)
  526. {
  527. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i);
  528. }
  529. int64_t
  530. attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key)
  531. {
  532. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, j);
  533. }
  534. int8_t
  535. attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key)
  536. {
  537. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, b);
  538. }
  539. uint16_t
  540. attr_container_get_as_uint16(const attr_container_t *attr_cont, const char *key)
  541. {
  542. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, s);
  543. }
  544. float
  545. attr_container_get_as_float(const attr_container_t *attr_cont, const char *key)
  546. {
  547. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, f);
  548. }
  549. double
  550. attr_container_get_as_double(const attr_container_t *attr_cont, const char *key)
  551. {
  552. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, d);
  553. }
  554. bool
  555. attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key)
  556. {
  557. TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, z);
  558. }
  559. const int8_t *
  560. attr_container_get_as_bytearray(const attr_container_t *attr_cont,
  561. const char *key, unsigned *array_length)
  562. {
  563. const char *addr = attr_container_get_attr(attr_cont, key);
  564. uint8_t type;
  565. uint32_t length;
  566. if (!addr)
  567. return NULL;
  568. if (!array_length) {
  569. attr_container_printf("Get attribute failed: invalid input arguments.");
  570. return NULL;
  571. }
  572. type = *(uint8_t *)addr++;
  573. switch (type) {
  574. case ATTR_TYPE_SHORT:
  575. case ATTR_TYPE_INT:
  576. case ATTR_TYPE_INT64:
  577. case ATTR_TYPE_BYTE:
  578. case ATTR_TYPE_UINT16:
  579. case ATTR_TYPE_FLOAT:
  580. case ATTR_TYPE_DOUBLE:
  581. case ATTR_TYPE_BOOLEAN:
  582. length = 1 << (type & 3);
  583. break;
  584. case ATTR_TYPE_STRING:
  585. length = get_uint16(addr);
  586. addr += 2;
  587. break;
  588. case ATTR_TYPE_BYTEARRAY:
  589. length = get_uint32(addr);
  590. addr += 4;
  591. break;
  592. default:
  593. return NULL;
  594. }
  595. *array_length = length;
  596. return (const int8_t *)addr;
  597. }
  598. char *
  599. attr_container_get_as_string(const attr_container_t *attr_cont, const char *key)
  600. {
  601. unsigned array_length;
  602. return (char *)attr_container_get_as_bytearray(attr_cont, key,
  603. &array_length);
  604. }
  605. const char *
  606. attr_container_get_tag(const attr_container_t *attr_cont)
  607. {
  608. return attr_cont ? attr_cont->buf + sizeof(uint32_t) + sizeof(uint16_t)
  609. : NULL;
  610. }
  611. bool
  612. attr_container_contain_key(const attr_container_t *attr_cont, const char *key)
  613. {
  614. if (!attr_cont || !key || !strlen(key)) {
  615. attr_container_printf(
  616. "Check contain key failed: invalid input arguments.\r\n");
  617. return false;
  618. }
  619. return attr_container_find_attr(attr_cont, key) ? true : false;
  620. }
  621. unsigned int
  622. attr_container_get_serialize_length(const attr_container_t *attr_cont)
  623. {
  624. const char *p;
  625. if (!attr_cont) {
  626. attr_container_printf("Get container serialize length failed: invalid "
  627. "input arguments.\r\n");
  628. return 0;
  629. }
  630. p = attr_cont->buf;
  631. return sizeof(uint16_t) + get_uint32(p);
  632. }
  633. bool
  634. attr_container_serialize(char *buf, const attr_container_t *attr_cont)
  635. {
  636. const char *p;
  637. uint16_t flags;
  638. uint32_t length;
  639. if (!buf || !attr_cont) {
  640. attr_container_printf(
  641. "Container serialize failed: invalid input arguments.\r\n");
  642. return false;
  643. }
  644. p = attr_cont->buf;
  645. length = sizeof(uint16_t) + get_uint32(p);
  646. bh_memcpy_s(buf, length, attr_cont, length);
  647. /* Set readonly */
  648. flags = get_uint16((const char *)attr_cont);
  649. set_uint16(buf, flags | (1 << ATTR_CONT_READONLY_SHIFT));
  650. return true;
  651. }
  652. bool
  653. attr_container_is_constant(const attr_container_t *attr_cont)
  654. {
  655. uint16_t flags;
  656. if (!attr_cont) {
  657. attr_container_printf(
  658. "Container check const: invalid input arguments.\r\n");
  659. return false;
  660. }
  661. flags = get_uint16((const char *)attr_cont);
  662. return (flags & (1 << ATTR_CONT_READONLY_SHIFT)) ? true : false;
  663. }
  664. void
  665. attr_container_dump(const attr_container_t *attr_cont)
  666. {
  667. uint32_t total_length;
  668. uint16_t attr_num, i, type;
  669. const char *p, *tag, *key;
  670. jvalue value;
  671. if (!attr_cont)
  672. return;
  673. tag = attr_container_get_tag(attr_cont);
  674. if (!tag)
  675. return;
  676. attr_container_printf("Attribute container dump:\n");
  677. attr_container_printf("Tag: %s\n", tag);
  678. p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num);
  679. if (!p)
  680. return;
  681. attr_container_printf("Attribute list:\n");
  682. for (i = 0; i < attr_num; i++) {
  683. key = p + 2;
  684. /* Skip key len and key */
  685. p += 2 + get_uint16(p);
  686. type = *p++;
  687. attr_container_printf(" key: %s", key);
  688. switch (type) {
  689. case ATTR_TYPE_SHORT:
  690. bh_memcpy_s(&value.s, sizeof(int16_t), p, sizeof(int16_t));
  691. attr_container_printf(", type: short, value: 0x%x\n",
  692. value.s & 0xFFFF);
  693. p += 2;
  694. break;
  695. case ATTR_TYPE_INT:
  696. bh_memcpy_s(&value.i, sizeof(int32_t), p, sizeof(int32_t));
  697. attr_container_printf(", type: int, value: 0x%x\n", value.i);
  698. p += 4;
  699. break;
  700. case ATTR_TYPE_INT64:
  701. bh_memcpy_s(&value.j, sizeof(uint64_t), p, sizeof(uint64_t));
  702. attr_container_printf(", type: int64, value: 0x%llx\n",
  703. (long long unsigned int)(value.j));
  704. p += 8;
  705. break;
  706. case ATTR_TYPE_BYTE:
  707. bh_memcpy_s(&value.b, 1, p, 1);
  708. attr_container_printf(", type: byte, value: 0x%x\n",
  709. value.b & 0xFF);
  710. p++;
  711. break;
  712. case ATTR_TYPE_UINT16:
  713. bh_memcpy_s(&value.c, sizeof(uint16_t), p, sizeof(uint16_t));
  714. attr_container_printf(", type: uint16, value: 0x%x\n", value.c);
  715. p += 2;
  716. break;
  717. case ATTR_TYPE_FLOAT:
  718. bh_memcpy_s(&value.f, sizeof(float), p, sizeof(float));
  719. attr_container_printf(", type: float, value: %f\n", value.f);
  720. p += 4;
  721. break;
  722. case ATTR_TYPE_DOUBLE:
  723. bh_memcpy_s(&value.d, sizeof(double), p, sizeof(double));
  724. attr_container_printf(", type: double, value: %f\n", value.d);
  725. p += 8;
  726. break;
  727. case ATTR_TYPE_BOOLEAN:
  728. bh_memcpy_s(&value.z, 1, p, 1);
  729. attr_container_printf(", type: bool, value: 0x%x\n", value.z);
  730. p++;
  731. break;
  732. case ATTR_TYPE_STRING:
  733. attr_container_printf(", type: string, value: %s\n",
  734. p + sizeof(uint16_t));
  735. p += sizeof(uint16_t) + get_uint16(p);
  736. break;
  737. case ATTR_TYPE_BYTEARRAY:
  738. attr_container_printf(", type: byte array, length: %d\n",
  739. get_uint32(p));
  740. p += sizeof(uint32_t) + get_uint32(p);
  741. break;
  742. default:
  743. bh_assert(0);
  744. break;
  745. }
  746. }
  747. attr_container_printf("\n");
  748. }