/* Part of the SYSTEM MODULE Copyright (C) 2019-2021 by Maxim Prokhorov */ #include "types.h" namespace espurna { void Callback::swap(Callback& other) noexcept { if (_type == other._type) { switch (_type) { case StorageType::Empty: break; case StorageType::Simple: std::swap(_storage.simple, other._storage.simple); break; case StorageType::Wrapper: std::swap(_storage.wrapper, other._storage.wrapper); break; } return; } auto moved = std::move(*this); *this = std::move(other); other = std::move(moved); } void Callback::operator()() const { switch (_type) { case StorageType::Empty: break; case StorageType::Simple: (*_storage.simple)(); break; case StorageType::Wrapper: _storage.wrapper(); break; } } void Callback::copy(const Callback& other) { _type = other._type; switch (other._type) { case StorageType::Empty: break; case StorageType::Simple: _storage.simple = other._storage.simple; break; case StorageType::Wrapper: new (&_storage.wrapper) WrapperType( other._storage.wrapper); break; } } void Callback::move(Callback& other) noexcept { _type = other._type; switch (other._type) { case StorageType::Empty: break; case StorageType::Simple: _storage.simple = other._storage.simple; break; case StorageType::Wrapper: new (&_storage.wrapper) WrapperType( std::move(other._storage.wrapper)); break; } other._storage.simple = nullptr; other._type = StorageType::Empty; } void Callback::reset() { switch (_type) { case StorageType::Empty: case StorageType::Simple: break; case StorageType::Wrapper: _storage.wrapper.~WrapperType(); break; } _storage.simple = nullptr; _type = StorageType::Empty; } Callback& Callback::operator=(Callback&& other) noexcept { reset(); move(other); return *this; } bool StringView::equals(StringView other) const { if (other._len == _len) { if (inFlash(_ptr) && inFlash(other._ptr)) { return _ptr == other._ptr; } else if (inFlash(_ptr)) { return memcmp_P(other._ptr, _ptr, _len) == 0; } else if (inFlash(other._ptr)) { return memcmp_P(_ptr, other._ptr, _len) == 0; } return __builtin_memcmp(_ptr, other._ptr, _len) == 0; } return false; } bool StringView::equalsIgnoreCase(StringView other) const { if (other._len == _len) { if (inFlash(_ptr) && inFlash(other._ptr) && (_ptr == other._ptr)) { return true; } else if (inFlash(_ptr) || inFlash(other._ptr)) { String copy; const char* ptr = _ptr; if (inFlash(_ptr)) { copy = toString(); ptr = copy.begin(); } return strncasecmp_P(ptr, other._ptr, _len) == 0; } return __builtin_strncasecmp(_ptr, other._ptr, _len) == 0; } return false; } bool StringView::startsWith(StringView other) const { if (other._len <= _len) { return StringView(begin(), begin() + other._len).equals(other); } return false; } bool StringView::endsWith(StringView other) const { if (other._len <= _len) { return StringView(end() - other._len, end()).equals(other); } return false; } bool SplitStringView::next() { if (!_view.length()) { return false; } const auto delim = std::find(_view.begin(), _view.end(), _delim); if (delim != _view.end()) { _current = StringView(_view.begin(), delim); _view = StringView(delim + 1, _view.end()); } else { _current = _view; _view = StringView(_view.end(), _view.end()); } return true; } } // namespace espurna