test-blobmsg-types.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include <stdio.h>
  2. #include <float.h>
  3. #include <limits.h>
  4. #include <stdint.h>
  5. #include <inttypes.h>
  6. #include "blobmsg.h"
  7. #include "blobmsg_json.h"
  8. enum {
  9. FOO_STRING,
  10. FOO_INT64_MAX,
  11. FOO_INT64_MIN,
  12. FOO_INT32_MAX,
  13. FOO_INT32_MIN,
  14. FOO_INT16_MAX,
  15. FOO_INT16_MIN,
  16. FOO_INT8_MAX,
  17. FOO_INT8_MIN,
  18. FOO_DOUBLE_MAX,
  19. FOO_DOUBLE_MIN,
  20. __FOO_MAX
  21. };
  22. static const struct blobmsg_policy pol[] = {
  23. [FOO_STRING] = {
  24. .name = "string",
  25. .type = BLOBMSG_TYPE_STRING,
  26. },
  27. [FOO_INT64_MAX] = {
  28. .name = "int64_max",
  29. .type = BLOBMSG_TYPE_INT64,
  30. },
  31. [FOO_INT64_MIN] = {
  32. .name = "int64_min",
  33. .type = BLOBMSG_TYPE_INT64,
  34. },
  35. [FOO_INT32_MAX] = {
  36. .name = "int32_max",
  37. .type = BLOBMSG_TYPE_INT32,
  38. },
  39. [FOO_INT32_MIN] = {
  40. .name = "int32_min",
  41. .type = BLOBMSG_TYPE_INT32,
  42. },
  43. [FOO_INT16_MAX] = {
  44. .name = "int16_max",
  45. .type = BLOBMSG_TYPE_INT16,
  46. },
  47. [FOO_INT16_MIN] = {
  48. .name = "int16_min",
  49. .type = BLOBMSG_TYPE_INT16,
  50. },
  51. [FOO_INT8_MAX] = {
  52. .name = "int8_max",
  53. .type = BLOBMSG_TYPE_INT8,
  54. },
  55. [FOO_INT8_MIN] = {
  56. .name = "int8_min",
  57. .type = BLOBMSG_TYPE_INT8,
  58. },
  59. [FOO_DOUBLE_MAX] = {
  60. .name = "double_max",
  61. .type = BLOBMSG_TYPE_DOUBLE,
  62. },
  63. [FOO_DOUBLE_MIN] = {
  64. .name = "double_min",
  65. .type = BLOBMSG_TYPE_DOUBLE,
  66. },
  67. };
  68. static const struct blobmsg_policy pol_json[] = {
  69. [FOO_STRING] = {
  70. .name = "string",
  71. .type = BLOBMSG_TYPE_STRING,
  72. },
  73. [FOO_INT64_MAX] = {
  74. .name = "int64_max",
  75. .type = BLOBMSG_TYPE_INT64,
  76. },
  77. [FOO_INT64_MIN] = {
  78. .name = "int64_min",
  79. .type = BLOBMSG_TYPE_INT64,
  80. },
  81. [FOO_INT32_MAX] = {
  82. .name = "int32_max",
  83. .type = BLOBMSG_TYPE_INT32,
  84. },
  85. [FOO_INT32_MIN] = {
  86. .name = "int32_min",
  87. .type = BLOBMSG_TYPE_INT32,
  88. },
  89. [FOO_INT16_MAX] = {
  90. .name = "int16_max",
  91. .type = BLOBMSG_TYPE_INT32,
  92. },
  93. [FOO_INT16_MIN] = {
  94. .name = "int16_min",
  95. .type = BLOBMSG_TYPE_INT32,
  96. },
  97. [FOO_INT8_MAX] = {
  98. .name = "int8_max",
  99. .type = BLOBMSG_TYPE_INT8,
  100. },
  101. [FOO_INT8_MIN] = {
  102. .name = "int8_min",
  103. .type = BLOBMSG_TYPE_INT8,
  104. },
  105. [FOO_DOUBLE_MAX] = {
  106. .name = "double_max",
  107. .type = BLOBMSG_TYPE_DOUBLE,
  108. },
  109. [FOO_DOUBLE_MIN] = {
  110. .name = "double_min",
  111. .type = BLOBMSG_TYPE_DOUBLE,
  112. },
  113. };
  114. #ifndef ARRAY_SIZE
  115. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  116. #endif
  117. static void dump_message(struct blob_buf *buf)
  118. {
  119. struct blob_attr *tb[ARRAY_SIZE(pol)];
  120. if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  121. fprintf(stderr, "Parse failed\n");
  122. return;
  123. }
  124. if (tb[FOO_STRING])
  125. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  126. if (tb[FOO_INT64_MAX])
  127. fprintf(stderr, "int64_max: %" PRId64 "\n", (int64_t)blobmsg_get_u64(tb[FOO_INT64_MAX]));
  128. if (tb[FOO_INT64_MIN])
  129. fprintf(stderr, "int64_min: %" PRId64 "\n", (int64_t)blobmsg_get_u64(tb[FOO_INT64_MIN]));
  130. if (tb[FOO_INT32_MAX])
  131. fprintf(stderr, "int32_max: %" PRId32 "\n", (int32_t)blobmsg_get_u32(tb[FOO_INT32_MAX]));
  132. if (tb[FOO_INT32_MIN])
  133. fprintf(stderr, "int32_min: %" PRId32 "\n", (int32_t)blobmsg_get_u32(tb[FOO_INT32_MIN]));
  134. if (tb[FOO_INT16_MAX])
  135. fprintf(stderr, "int16_max: %" PRId16 "\n", (int16_t)blobmsg_get_u16(tb[FOO_INT16_MAX]));
  136. if (tb[FOO_INT16_MIN])
  137. fprintf(stderr, "int16_min: %" PRId16 "\n", (int16_t)blobmsg_get_u16(tb[FOO_INT16_MIN]));
  138. if (tb[FOO_INT8_MAX])
  139. fprintf(stderr, "int8_max: %" PRId8 "\n", (int8_t)blobmsg_get_u8(tb[FOO_INT8_MAX]));
  140. if (tb[FOO_INT8_MIN])
  141. fprintf(stderr, "int8_min: %" PRId8 "\n", (int8_t)blobmsg_get_u8(tb[FOO_INT8_MIN]));
  142. if (tb[FOO_DOUBLE_MAX])
  143. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  144. if (tb[FOO_DOUBLE_MIN])
  145. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  146. }
  147. static void dump_message_cast_u64(struct blob_buf *buf)
  148. {
  149. struct blob_attr *tb[ARRAY_SIZE(pol)];
  150. if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  151. fprintf(stderr, "Parse failed\n");
  152. return;
  153. }
  154. if (tb[FOO_STRING])
  155. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  156. if (tb[FOO_INT64_MAX])
  157. fprintf(stderr, "int64_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MAX]));
  158. if (tb[FOO_INT64_MIN])
  159. fprintf(stderr, "int64_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MIN]));
  160. if (tb[FOO_INT32_MAX])
  161. fprintf(stderr, "int32_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MAX]));
  162. if (tb[FOO_INT32_MIN])
  163. fprintf(stderr, "int32_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MIN]));
  164. if (tb[FOO_INT16_MAX])
  165. fprintf(stderr, "int16_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MAX]));
  166. if (tb[FOO_INT16_MIN])
  167. fprintf(stderr, "int16_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MIN]));
  168. if (tb[FOO_INT8_MAX])
  169. fprintf(stderr, "int8_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MAX]));
  170. if (tb[FOO_INT8_MIN])
  171. fprintf(stderr, "int8_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MIN]));
  172. if (tb[FOO_DOUBLE_MAX])
  173. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  174. if (tb[FOO_DOUBLE_MIN])
  175. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  176. }
  177. static void dump_message_cast_s64(struct blob_buf *buf)
  178. {
  179. struct blob_attr *tb[ARRAY_SIZE(pol)];
  180. if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  181. fprintf(stderr, "Parse failed\n");
  182. return;
  183. }
  184. if (tb[FOO_STRING])
  185. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  186. if (tb[FOO_INT64_MAX])
  187. fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MAX]));
  188. if (tb[FOO_INT64_MIN])
  189. fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MIN]));
  190. if (tb[FOO_INT32_MAX])
  191. fprintf(stderr, "int32_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MAX]));
  192. if (tb[FOO_INT32_MIN])
  193. fprintf(stderr, "int32_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MIN]));
  194. if (tb[FOO_INT16_MAX])
  195. fprintf(stderr, "int16_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MAX]));
  196. if (tb[FOO_INT16_MIN])
  197. fprintf(stderr, "int16_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MIN]));
  198. if (tb[FOO_INT8_MAX])
  199. fprintf(stderr, "int8_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MAX]));
  200. if (tb[FOO_INT8_MIN])
  201. fprintf(stderr, "int8_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MIN]));
  202. if (tb[FOO_DOUBLE_MAX])
  203. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  204. if (tb[FOO_DOUBLE_MIN])
  205. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  206. }
  207. static void dump_message_json(struct blob_buf *buf)
  208. {
  209. struct blob_attr *tb[ARRAY_SIZE(pol)];
  210. if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  211. fprintf(stderr, "Parse failed\n");
  212. return;
  213. }
  214. if (tb[FOO_STRING])
  215. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  216. if (tb[FOO_INT64_MAX])
  217. fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_get_u64(tb[FOO_INT64_MAX]));
  218. if (tb[FOO_INT64_MIN])
  219. fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_get_u64(tb[FOO_INT64_MIN]));
  220. if (tb[FOO_INT32_MAX])
  221. fprintf(stderr, "int32_max: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT32_MAX]));
  222. if (tb[FOO_INT32_MIN])
  223. fprintf(stderr, "int32_min: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT32_MIN]));
  224. /* u16 is unknown to json, retrieve as u32 */
  225. if (tb[FOO_INT16_MAX])
  226. fprintf(stderr, "int16_max: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT16_MAX]));
  227. /* u16 is unknown to json, retrieve as u32 */
  228. if (tb[FOO_INT16_MIN])
  229. fprintf(stderr, "int16_min: %" PRId32 "\n", blobmsg_get_u32(tb[FOO_INT16_MIN]));
  230. /* u8 is converted to boolean (true: all values != 0/false: value 0) in json */
  231. if (tb[FOO_INT8_MAX])
  232. fprintf(stderr, "int8_max: %" PRId8 "\n", blobmsg_get_u8(tb[FOO_INT8_MAX]));
  233. /* u8 is converted to boolean (true: all values != 0/false: value 0) in json */
  234. if (tb[FOO_INT8_MIN])
  235. fprintf(stderr, "int8_min: %" PRId8 "\n", blobmsg_get_u8(tb[FOO_INT8_MIN]));
  236. if (tb[FOO_DOUBLE_MAX])
  237. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  238. if (tb[FOO_DOUBLE_MIN])
  239. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  240. }
  241. static void dump_message_cast_u64_json(struct blob_buf *buf)
  242. {
  243. struct blob_attr *tb[ARRAY_SIZE(pol)];
  244. if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  245. fprintf(stderr, "Parse failed\n");
  246. return;
  247. }
  248. if (tb[FOO_STRING])
  249. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  250. if (tb[FOO_INT64_MAX])
  251. fprintf(stderr, "int64_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MAX]));
  252. if (tb[FOO_INT64_MIN])
  253. fprintf(stderr, "int64_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT64_MIN]));
  254. if (tb[FOO_INT32_MAX])
  255. fprintf(stderr, "int32_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MAX]));
  256. if (tb[FOO_INT32_MIN])
  257. fprintf(stderr, "int32_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT32_MIN]));
  258. if (tb[FOO_INT16_MAX])
  259. fprintf(stderr, "int16_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MAX]));
  260. if (tb[FOO_INT16_MIN])
  261. fprintf(stderr, "int16_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT16_MIN]));
  262. if (tb[FOO_INT8_MAX])
  263. fprintf(stderr, "int8_max: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MAX]));
  264. if (tb[FOO_INT8_MIN])
  265. fprintf(stderr, "int8_min: %" PRIu64 "\n", blobmsg_cast_u64(tb[FOO_INT8_MIN]));
  266. if (tb[FOO_DOUBLE_MAX])
  267. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  268. if (tb[FOO_DOUBLE_MIN])
  269. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  270. }
  271. static void dump_message_cast_s64_json(struct blob_buf *buf)
  272. {
  273. struct blob_attr *tb[ARRAY_SIZE(pol)];
  274. if (blobmsg_parse(pol_json, ARRAY_SIZE(pol_json), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
  275. fprintf(stderr, "Parse failed\n");
  276. return;
  277. }
  278. if (tb[FOO_STRING])
  279. fprintf(stderr, "string: %s\n", blobmsg_get_string(tb[FOO_STRING]));
  280. if (tb[FOO_INT64_MAX])
  281. fprintf(stderr, "int64_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MAX]));
  282. if (tb[FOO_INT64_MIN])
  283. fprintf(stderr, "int64_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT64_MIN]));
  284. if (tb[FOO_INT32_MAX])
  285. fprintf(stderr, "int32_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MAX]));
  286. if (tb[FOO_INT32_MIN])
  287. fprintf(stderr, "int32_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT32_MIN]));
  288. if (tb[FOO_INT16_MAX])
  289. fprintf(stderr, "int16_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MAX]));
  290. if (tb[FOO_INT16_MIN])
  291. fprintf(stderr, "int16_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT16_MIN]));
  292. if (tb[FOO_INT8_MAX])
  293. fprintf(stderr, "int8_max: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MAX]));
  294. if (tb[FOO_INT8_MIN])
  295. fprintf(stderr, "int8_min: %" PRId64 "\n", blobmsg_cast_s64(tb[FOO_INT8_MIN]));
  296. if (tb[FOO_DOUBLE_MAX])
  297. fprintf(stderr, "double_max: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MAX]));
  298. if (tb[FOO_DOUBLE_MIN])
  299. fprintf(stderr, "double_min: %e\n", blobmsg_get_double(tb[FOO_DOUBLE_MIN]));
  300. }
  301. static void
  302. fill_message(struct blob_buf *buf)
  303. {
  304. blobmsg_add_string(buf, "string", "Hello, world!");
  305. blobmsg_add_u64(buf, "int64_max", INT64_MAX);
  306. blobmsg_add_u64(buf, "int64_min", INT64_MIN);
  307. blobmsg_add_u32(buf, "int32_max", INT32_MAX);
  308. blobmsg_add_u32(buf, "int32_min", INT32_MIN);
  309. blobmsg_add_u16(buf, "int16_max", INT16_MAX);
  310. blobmsg_add_u16(buf, "int16_min", INT16_MIN);
  311. blobmsg_add_u8(buf, "int8_max", INT8_MAX);
  312. blobmsg_add_u8(buf, "int8_min", INT8_MIN);
  313. blobmsg_add_double(buf, "double_max", DBL_MAX);
  314. blobmsg_add_double(buf, "double_min", DBL_MIN);
  315. }
  316. int main(int argc, char **argv)
  317. {
  318. char *json = NULL;
  319. static struct blob_buf buf;
  320. blobmsg_buf_init(&buf);
  321. fill_message(&buf);
  322. fprintf(stderr, "[*] blobmsg dump:\n");
  323. dump_message(&buf);
  324. fprintf(stderr, "[*] blobmsg dump cast_u64:\n");
  325. dump_message_cast_u64(&buf);
  326. fprintf(stderr, "[*] blobmsg dump cast_s64:\n");
  327. dump_message_cast_s64(&buf);
  328. json = blobmsg_format_json(buf.head, true);
  329. if (!json)
  330. exit(EXIT_FAILURE);
  331. fprintf(stderr, "\n[*] blobmsg to json: %s\n", json);
  332. blobmsg_buf_init(&buf);
  333. if (!blobmsg_add_json_from_string(&buf, json))
  334. exit(EXIT_FAILURE);
  335. fprintf(stderr, "\n[*] blobmsg from json:\n");
  336. dump_message_json(&buf);
  337. fprintf(stderr, "\n[*] blobmsg from json/cast_u64:\n");
  338. dump_message_cast_u64_json(&buf);
  339. fprintf(stderr, "\n[*] blobmsg from json/cast_s64:\n");
  340. dump_message_cast_s64_json(&buf);
  341. if (buf.buf)
  342. free(buf.buf);
  343. free(json);
  344. return 0;
  345. }