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

/*
Part of the SYSTEM MODULE
Copyright (C) 2019-2021 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
*/
#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