main.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * lws-api-test-lws_struct-sqlite
  3. *
  4. * Written in 2010-2020 by Andy Green <[email protected]>
  5. *
  6. * This file is made available under the Creative Commons CC0 1.0
  7. * Universal Public Domain Dedication.
  8. *
  9. * lws_struct apis are used to serialize and deserialize your C structs and
  10. * linked-lists in a standardized way that's very modest on memory but
  11. * convenient and easy to maintain.
  12. *
  13. * The API test shows how to serialize and deserialize a struct with a linked-
  14. * list of child structs in JSON using lws_struct APIs.
  15. */
  16. #include <libwebsockets.h>
  17. typedef struct teststruct {
  18. lws_dll2_t list; /* not directly serialized */
  19. char str1[32];
  20. const char *str2;
  21. uint8_t u8;
  22. uint16_t u16;
  23. uint32_t u32;
  24. uint64_t u64;
  25. int32_t s32;
  26. } teststruct_t;
  27. /*
  28. * These are the members that we will serialize and deserialize, not every
  29. * member in the struct (eg, the dll2 list member)
  30. */
  31. static const lws_struct_map_t lsm_teststruct[] = {
  32. LSM_CARRAY (teststruct_t, str1, "str1"),
  33. LSM_STRING_PTR (teststruct_t, str2, "str2"),
  34. LSM_UNSIGNED (teststruct_t, u8, "u8"),
  35. LSM_UNSIGNED (teststruct_t, u16, "u16"),
  36. LSM_UNSIGNED (teststruct_t, u32, "u32"),
  37. LSM_UNSIGNED (teststruct_t, u64, "u64"),
  38. LSM_SIGNED (teststruct_t, s32, "s32"),
  39. };
  40. static const lws_struct_map_t lsm_schema_apitest[] = {
  41. LSM_SCHEMA_DLL2 (teststruct_t, list, NULL, lsm_teststruct, "apitest")
  42. };
  43. static const char *test_string =
  44. "No one would have believed in the last years of the nineteenth "
  45. "century that this world was being watched keenly and closely by "
  46. "intelligences greater than man's and yet as mortal as his own; that as "
  47. "men busied themselves about their various concerns they were "
  48. "scrutinised and studied, perhaps almost as narrowly as a man with a "
  49. "microscope might scrutinise the transient creatures that swarm and "
  50. "multiply in a drop of water. With infinite complacency men went to "
  51. "and fro over this globe about their little affairs, serene in their "
  52. "assurance of their empire over matter. It is possible that the "
  53. "infusoria under the microscope do the same. No one gave a thought to "
  54. "the older worlds of space as sources of human danger, or thought of "
  55. "them only to dismiss the idea of life upon them as impossible or "
  56. "improbable. It is curious to recall some of the mental habits of "
  57. "those departed days. At most terrestrial men fancied there might be "
  58. "other men upon Mars, perhaps inferior to themselves and ready to "
  59. "welcome a missionary enterprise. Yet across the gulf of space, minds "
  60. "that are to our minds as ours are to those of the beasts that perish, "
  61. "intellects vast and cool and unsympathetic, regarded this earth with "
  62. "envious eyes, and slowly and surely drew their plans against us. And "
  63. "early in the twentieth century came the great disillusionment. ";
  64. int main(int argc, const char **argv)
  65. {
  66. int e = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
  67. struct lws_context_creation_info info;
  68. struct lws_context *context;
  69. struct lwsac *ac = NULL;
  70. lws_dll2_owner_t resown;
  71. teststruct_t ts, *pts;
  72. const char *p;
  73. sqlite3 *db;
  74. if ((p = lws_cmdline_option(argc, argv, "-d")))
  75. logs = atoi(p);
  76. lws_set_log_level(logs, NULL);
  77. lwsl_user("LWS API selftest: lws_struct SQLite\n");
  78. memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
  79. info.port = CONTEXT_PORT_NO_LISTEN;
  80. context = lws_create_context(&info);
  81. if (!context) {
  82. lwsl_err("lws init failed\n");
  83. return 1;
  84. }
  85. unlink("_lws_apitest.sq3");
  86. if (lws_struct_sq3_open(context, "_lws_apitest.sq3", 1, &db)) {
  87. lwsl_err("%s: failed to open table\n", __func__);
  88. goto bail;
  89. }
  90. /* 1. populate the struct */
  91. memset(&ts, 0, sizeof(ts));
  92. lws_strncpy(ts.str1, "hello", sizeof(ts.str1));
  93. ts.str2 = test_string;
  94. ts.u8 = 1;
  95. ts.u16 = 512,
  96. ts.u32 = 0x55aa1234; /* 1437209140, */
  97. ts.u64 = 0x34abcdef01ull;
  98. ts.s32 = -1;
  99. /* add our struct to the dll2 owner list */
  100. lws_dll2_owner_clear(&resown);
  101. lws_dll2_add_head(&ts.list, &resown);
  102. /* gratuitously create the table */
  103. if (lws_struct_sq3_create_table(db, lsm_schema_apitest)) {
  104. lwsl_err("%s: Create table failed\n", __func__);
  105. e++;
  106. goto done;
  107. }
  108. /* serialize the items on the dll2 owner */
  109. if (lws_struct_sq3_serialize(db, lsm_schema_apitest, &resown, 0)) {
  110. lwsl_err("%s: Serialize failed\n", __func__);
  111. e++;
  112. goto done;
  113. }
  114. /* resown should be cleared by deserialize, ac is already NULL */
  115. lws_dll2_owner_clear(&resown); /* make sure old resown data is gone */
  116. if (lws_struct_sq3_deserialize(db, NULL, NULL, lsm_schema_apitest,
  117. &resown, &ac, 0, 1)) {
  118. lwsl_err("%s: Deserialize failed\n", __func__);
  119. e++;
  120. goto done;
  121. }
  122. /* we should have 1 entry in resown now (created into the ac) */
  123. if (resown.count != 1) {
  124. lwsl_err("%s: Expected 1 result got %d\n", __func__,
  125. resown.count);
  126. e++;
  127. goto done;
  128. }
  129. /*
  130. * Convert the pointer to the embedded lws_dll2 into a pointer
  131. * to the actual struct with the correct type
  132. */
  133. pts = lws_container_of(lws_dll2_get_head(&resown),
  134. teststruct_t, list);
  135. if (strcmp(pts->str1, "hello") ||
  136. strcmp(pts->str2, test_string) ||
  137. pts->u8 != 1 ||
  138. pts->u16 != 512 ||
  139. pts->u32 != 0x55aa1234 ||
  140. pts->u64 != 0x34abcdef01ull ||
  141. pts->s32 != -1) {
  142. lwsl_err("%s: unexpected deser values: %s\n", __func__, pts->str1);
  143. lwsl_err("%s: %s\n", __func__, pts->str2);
  144. lwsl_err("%s: %u %u %u 0x%llx %d\n", __func__, pts->u8, pts->u16,
  145. pts->u32, (unsigned long long)pts->u64, pts->s32);
  146. e++;
  147. goto done;
  148. }
  149. done:
  150. lwsac_free(&ac);
  151. lws_struct_sq3_close(&db);
  152. if (e)
  153. goto bail;
  154. lws_context_destroy(context);
  155. lwsl_user("Completed: PASS\n");
  156. return 0;
  157. bail:
  158. lws_context_destroy(context);
  159. lwsl_user("Completed: FAIL\n");
  160. return 1;
  161. }