properties.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // properties.cpp
  2. /*******************************************************************************
  3. * Copyright (c) 2019 Frank Pagliughi <fpagliughi@mindspring.com>
  4. *
  5. * All rights reserved. This program and the accompanying materials
  6. * are made available under the terms of the Eclipse Public License v1.0
  7. * and Eclipse Distribution License v1.0 which accompany this distribution.
  8. *
  9. * The Eclipse Public License is available at
  10. * http://www.eclipse.org/legal/epl-v10.html
  11. * and the Eclipse Distribution License is available at
  12. * http://www.eclipse.org/org/documents/edl-v10.php.
  13. *
  14. * Contributors:
  15. * Frank Pagliughi - initial implementation and documentation
  16. *******************************************************************************/
  17. #include "mqtt/properties.h"
  18. namespace mqtt {
  19. /////////////////////////////////////////////////////////////////////////////
  20. property::property(code c, int32_t val)
  21. {
  22. prop_.identifier = ::MQTTPropertyCodes(c);
  23. switch (::MQTTProperty_getType(prop_.identifier)) {
  24. case MQTTPROPERTY_TYPE_BYTE:
  25. prop_.value.byte = uint8_t(val);
  26. break;
  27. case MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER:
  28. prop_.value.integer2 = int16_t(val);
  29. break;
  30. case MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER:
  31. case MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER:
  32. prop_.value.integer4 = val;
  33. break;
  34. default:
  35. // TODO: Throw an exception
  36. break;
  37. }
  38. }
  39. property::property(code c, string_ref val)
  40. {
  41. prop_.identifier = ::MQTTPropertyCodes(c);
  42. size_t n = val.size();
  43. prop_.value.data.len = int(n);
  44. prop_.value.data.data = (char*) malloc(n);
  45. std::memcpy(prop_.value.data.data, val.data(), n);
  46. }
  47. property::property(code c, string_ref name, string_ref val)
  48. {
  49. prop_.identifier = MQTTPropertyCodes(c);
  50. size_t n = name.size();
  51. prop_.value.data.len = int(n);
  52. prop_.value.data.data = (char*) malloc(n);
  53. std::memcpy(prop_.value.data.data, name.data(), n);
  54. n = val.size();
  55. prop_.value.value.len = int(n);
  56. prop_.value.value.data = (char*) malloc(n);
  57. std::memcpy(prop_.value.value.data, val.data(), n);
  58. }
  59. property::property(const MQTTProperty& cprop)
  60. {
  61. copy(cprop);
  62. }
  63. property::property(MQTTProperty&& cprop)
  64. :prop_(cprop)
  65. {
  66. memset(&cprop, 0, sizeof(MQTTProperty));
  67. }
  68. property::property(const property& other)
  69. {
  70. copy(other.prop_);
  71. }
  72. property::property(property&& other)
  73. {
  74. std::memcpy(&prop_, &other.prop_, sizeof(MQTTProperty));
  75. memset(&other.prop_, 0, sizeof(MQTTProperty));
  76. }
  77. property::~property()
  78. {
  79. switch (::MQTTProperty_getType(prop_.identifier)) {
  80. case MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR:
  81. free(prop_.value.value.data);
  82. // Fall-through
  83. case MQTTPROPERTY_TYPE_BINARY_DATA:
  84. case MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING:
  85. free(prop_.value.data.data);
  86. break;
  87. default:
  88. // Nothing necessary
  89. break;
  90. }
  91. }
  92. void property::copy(const MQTTProperty& cprop)
  93. {
  94. size_t n;
  95. std::memcpy(&prop_, &cprop, sizeof(MQTTProperty));
  96. switch (::MQTTProperty_getType(prop_.identifier)) {
  97. case MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR:
  98. n = prop_.value.value.len;
  99. prop_.value.value.data = (char*) malloc(n);
  100. memcpy(prop_.value.value.data, cprop.value.value.data, n);
  101. // Fall-through
  102. case MQTTPROPERTY_TYPE_BINARY_DATA:
  103. case MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING:
  104. n = prop_.value.data.len;
  105. prop_.value.data.data = (char*) malloc(n);
  106. memcpy(prop_.value.data.data, cprop.value.data.data, n);
  107. break;
  108. default:
  109. // Nothing necessary
  110. break;
  111. }
  112. }
  113. property& property::operator=(const property& rhs)
  114. {
  115. if (&rhs != this)
  116. copy(rhs.prop_);
  117. return *this;
  118. }
  119. property& property::operator=(property&& rhs)
  120. {
  121. if (&rhs != this) {
  122. std::memcpy(&prop_, &rhs.prop_, sizeof(MQTTProperty));
  123. memset(&rhs.prop_, 0, sizeof(MQTTProperty));
  124. }
  125. return *this;
  126. }
  127. /////////////////////////////////////////////////////////////////////////////
  128. properties::properties(std::initializer_list<property> props)
  129. {
  130. std::memset(&props_, 0, sizeof(properties));
  131. for (const auto& prop : props)
  132. ::MQTTProperties_add(&props_, &prop.c_struct());
  133. }
  134. void properties::clear()
  135. {
  136. ::MQTTProperties_free(&props_);
  137. memset(&props_, 0, sizeof(MQTTProperties));
  138. }
  139. property properties::get(property::code propid, size_t idx /*=0*/)
  140. {
  141. MQTTProperty* prop = MQTTProperties_getPropertyAt(&props_,
  142. MQTTPropertyCodes(propid), int(idx));
  143. if (!prop)
  144. throw bad_cast();
  145. return property(*prop);
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // end namespace 'mqtt'
  149. }