check_types_custom.c 4.9 KB

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