attr-container.c 24 KB

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