check_types_custom.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "ua_types.h"
  2. #include "ua_types_generated_handling.h"
  3. #include "ua_types_encoding_binary.h"
  4. #include "ua_util.h"
  5. #include "check.h"
  6. /* The custom datatype for describing a 3d position */
  7. typedef struct {
  8. UA_Float x;
  9. UA_Float y;
  10. UA_Float z;
  11. } Point;
  12. /* The datatype description for the Point datatype */
  13. #define padding_y offsetof(Point,y) - offsetof(Point,x) - sizeof(UA_Float)
  14. #define padding_z offsetof(Point,z) - offsetof(Point,y) - sizeof(UA_Float)
  15. static UA_DataTypeMember members[3] = {
  16. /* x */
  17. {
  18. #ifdef UA_ENABLE_TYPENAMES
  19. "x", /* .memberName */
  20. #endif
  21. UA_TYPES_FLOAT, /* .memberTypeIndex, points into UA_TYPES since
  22. .namespaceZero is true */
  23. 0, /* .padding */
  24. true, /* .namespaceZero, see .memberTypeIndex */
  25. false /* .isArray */
  26. },
  27. /* y */
  28. {
  29. #ifdef UA_ENABLE_TYPENAMES
  30. "y",
  31. #endif
  32. UA_TYPES_FLOAT, padding_y, true, false
  33. },
  34. /* z */
  35. {
  36. #ifdef UA_ENABLE_TYPENAMES
  37. "y",
  38. #endif
  39. UA_TYPES_FLOAT, padding_z, true, false
  40. }
  41. };
  42. static const UA_DataType PointType = {
  43. #ifdef UA_ENABLE_TYPENAMES
  44. "Point", /* .typeName */
  45. #endif
  46. {1, UA_NODEIDTYPE_NUMERIC, {1}}, /* .typeId */
  47. sizeof(Point), /* .memSize */
  48. 0, /* .typeIndex, in the array of custom types */
  49. 3, /* .membersSize */
  50. false, /* .builtin */
  51. true, /* .pointerFree */
  52. false, /* .overlayable (depends on endianness and
  53. the absence of padding) */
  54. 0, /* .binaryEncodingId, the numeric
  55. identifier used on the wire (the
  56. namespaceindex is from .typeId) */
  57. members
  58. };
  59. START_TEST(parseCustomScalar) {
  60. Point p;
  61. p.x = 1.0;
  62. p.y = 2.0;
  63. p.z = 3.0;
  64. UA_Variant var;
  65. UA_Variant_init(&var);
  66. UA_Variant_setScalar(&var, &p, &PointType);
  67. size_t buflen = UA_calcSizeBinary(&var, &UA_TYPES[UA_TYPES_VARIANT]);
  68. UA_ByteString buf;
  69. UA_StatusCode retval = UA_ByteString_allocBuffer(&buf, buflen);
  70. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  71. size_t offset = 0;
  72. retval = UA_encodeBinary(&var, &UA_TYPES[UA_TYPES_VARIANT], NULL, NULL,
  73. &buf, &offset);
  74. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  75. UA_Variant var2;
  76. offset = 0;
  77. retval = UA_decodeBinary(&buf, &offset, &var2, &UA_TYPES[UA_TYPES_VARIANT], 1, &PointType);
  78. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  79. ck_assert_ptr_eq(var2.type, &PointType);
  80. Point *p2 = (Point*)var2.data;
  81. ck_assert(p.x == p2->x);
  82. UA_Variant_deleteMembers(&var2);
  83. UA_ByteString_deleteMembers(&buf);
  84. } END_TEST
  85. START_TEST(parseCustomArray) {
  86. Point ps[10];
  87. for(size_t i = 0; i < 10; ++i) {
  88. ps[i].x = (UA_Float)(1*i);
  89. ps[i].y = (UA_Float)(2*i);
  90. ps[i].z = (UA_Float)(3*i);
  91. }
  92. UA_Variant var;
  93. UA_Variant_init(&var);
  94. UA_Variant_setArray(&var, (void*)ps, 10, &PointType);
  95. size_t buflen = UA_calcSizeBinary(&var, &UA_TYPES[UA_TYPES_VARIANT]);
  96. UA_ByteString buf;
  97. UA_StatusCode retval = UA_ByteString_allocBuffer(&buf, buflen);
  98. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  99. size_t offset = 0;
  100. retval = UA_encodeBinary(&var, &UA_TYPES[UA_TYPES_VARIANT], NULL, NULL,
  101. &buf, &offset);
  102. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  103. UA_Variant var2;
  104. offset = 0;
  105. retval = UA_decodeBinary(&buf, &offset, &var2, &UA_TYPES[UA_TYPES_VARIANT], 1, &PointType);
  106. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  107. ck_assert_ptr_eq(var2.type, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
  108. ck_assert_int_eq(var2.arrayLength, 10);
  109. UA_ExtensionObject *eo = (UA_ExtensionObject*)var2.data;
  110. ck_assert_int_eq(eo->encoding, UA_EXTENSIONOBJECT_DECODED);
  111. ck_assert_ptr_eq(eo->content.decoded.type, &PointType);
  112. Point *p2 = (Point*)eo->content.decoded.data;
  113. ck_assert(p2->x == 0.0);
  114. UA_Variant_deleteMembers(&var2);
  115. UA_ByteString_deleteMembers(&buf);
  116. } END_TEST
  117. int main(void) {
  118. Suite *s = suite_create("Test Custom DataType Encoding");
  119. TCase *tc = tcase_create("test cases");
  120. tcase_add_test(tc, parseCustomScalar);
  121. tcase_add_test(tc, parseCustomArray);
  122. suite_add_tcase(s, tc);
  123. SRunner *sr = srunner_create(s);
  124. srunner_set_fork_status(sr, CK_NOFORK);
  125. srunner_run_all (sr, CK_NORMAL);
  126. int number_failed = srunner_ntests_failed(sr);
  127. srunner_free(sr);
  128. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  129. }