Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
3.9 KiB

  1. /*
  2. Part of the SYSTEM MODULE
  3. Copyright (C) 2019-2021 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
  4. */
  5. #include "types.h"
  6. namespace espurna {
  7. void Callback::swap(Callback& other) noexcept {
  8. if (_type == other._type) {
  9. switch (_type) {
  10. case StorageType::Empty:
  11. break;
  12. case StorageType::Simple:
  13. std::swap(_storage.simple, other._storage.simple);
  14. break;
  15. case StorageType::Wrapper:
  16. std::swap(_storage.wrapper, other._storage.wrapper);
  17. break;
  18. }
  19. return;
  20. }
  21. auto moved = std::move(*this);
  22. *this = std::move(other);
  23. other = std::move(moved);
  24. }
  25. void Callback::operator()() const {
  26. switch (_type) {
  27. case StorageType::Empty:
  28. break;
  29. case StorageType::Simple:
  30. (*_storage.simple)();
  31. break;
  32. case StorageType::Wrapper:
  33. _storage.wrapper();
  34. break;
  35. }
  36. }
  37. void Callback::copy(const Callback& other) {
  38. _type = other._type;
  39. switch (other._type) {
  40. case StorageType::Empty:
  41. break;
  42. case StorageType::Simple:
  43. _storage.simple = other._storage.simple;
  44. break;
  45. case StorageType::Wrapper:
  46. new (&_storage.wrapper) WrapperType(
  47. other._storage.wrapper);
  48. break;
  49. }
  50. }
  51. void Callback::move(Callback& other) noexcept {
  52. _type = other._type;
  53. switch (other._type) {
  54. case StorageType::Empty:
  55. break;
  56. case StorageType::Simple:
  57. _storage.simple = other._storage.simple;
  58. break;
  59. case StorageType::Wrapper:
  60. new (&_storage.wrapper) WrapperType(
  61. std::move(other._storage.wrapper));
  62. break;
  63. }
  64. other._storage.simple = nullptr;
  65. other._type = StorageType::Empty;
  66. }
  67. void Callback::reset() {
  68. switch (_type) {
  69. case StorageType::Empty:
  70. case StorageType::Simple:
  71. break;
  72. case StorageType::Wrapper:
  73. _storage.wrapper.~WrapperType();
  74. break;
  75. }
  76. _storage.simple = nullptr;
  77. _type = StorageType::Empty;
  78. }
  79. Callback& Callback::operator=(Callback&& other) noexcept {
  80. reset();
  81. move(other);
  82. return *this;
  83. }
  84. bool StringView::equals(StringView other) const {
  85. if (other._len == _len) {
  86. if (inFlash(_ptr) && inFlash(other._ptr)) {
  87. return _ptr == other._ptr;
  88. } else if (inFlash(_ptr)) {
  89. return memcmp_P(other._ptr, _ptr, _len) == 0;
  90. } else if (inFlash(other._ptr)) {
  91. return memcmp_P(_ptr, other._ptr, _len) == 0;
  92. }
  93. return __builtin_memcmp(_ptr, other._ptr, _len) == 0;
  94. }
  95. return false;
  96. }
  97. bool StringView::equalsIgnoreCase(StringView other) const {
  98. if (other._len == _len) {
  99. if (inFlash(_ptr) && inFlash(other._ptr) && (_ptr == other._ptr)) {
  100. return true;
  101. } else if (inFlash(_ptr) || inFlash(other._ptr)) {
  102. String copy;
  103. const char* ptr = _ptr;
  104. if (inFlash(_ptr)) {
  105. copy = toString();
  106. ptr = copy.begin();
  107. }
  108. return strncasecmp_P(ptr, other._ptr, _len) == 0;
  109. }
  110. return __builtin_strncasecmp(_ptr, other._ptr, _len) == 0;
  111. }
  112. return false;
  113. }
  114. bool StringView::startsWith(StringView other) const {
  115. if (other._len <= _len) {
  116. return StringView(begin(), begin() + other._len).equals(other);
  117. }
  118. return false;
  119. }
  120. bool StringView::endsWith(StringView other) const {
  121. if (other._len <= _len) {
  122. return StringView(end() - other._len, end()).equals(other);
  123. }
  124. return false;
  125. }
  126. bool SplitStringView::next() {
  127. if (!_view.length()) {
  128. return false;
  129. }
  130. const auto delim = std::find(_view.begin(), _view.end(), _delim);
  131. if (delim != _view.end()) {
  132. _current = StringView(_view.begin(), delim);
  133. _view = StringView(delim + 1, _view.end());
  134. } else {
  135. _current = _view;
  136. _view = StringView(_view.end(), _view.end());
  137. }
  138. return true;
  139. }
  140. } // namespace espurna