move toStdFunction() to pibase.h refactor PIParseHelper, now it much more abstract and useful fix PIIODevice::createFromFullPath() when whitespaces at start or end are presence PIStreamPacker add events for start and end packet receive PIClientServer::ClientBase add virtual methods for start and end packet receive. also one can enable diagnostics with enableDiagnostics() method PICout now call flush() on each end of output add PIString::entries(const PIString & str)
142 lines
4.1 KiB
C++
142 lines
4.1 KiB
C++
/*! \file piparsehelper.h
|
|
* \ingroup IO
|
|
* \~\brief
|
|
* \~english Helper class to automate structs receive
|
|
* \~russian Класс для автоматизации приема структур
|
|
*/
|
|
/*
|
|
PIP - Platform Independent Primitives
|
|
Helper class to automate structs receive
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef PIPARSEHELPER_H
|
|
#define PIPARSEHELPER_H
|
|
|
|
#include "piobject.h"
|
|
#include "pip_io_utils_export.h"
|
|
|
|
|
|
/** \class PIParseHelper
|
|
* \brief Helper class to automate structs receive
|
|
*
|
|
*
|
|
* \section PIParseHelper_synopsis Synopsis
|
|
* This class helps to deserialize and invoke neccessarily methods.
|
|
*
|
|
* Data packets with header and various data types can be automated by this class.
|
|
* Every key value mapped to object member function, lambda-function or functor.
|
|
*
|
|
* This class can remove \b switch-case with deserialization code and
|
|
* replace it with several \a assign() calls, binded to ready-to-use event handlers.
|
|
* Moreover data type automatic takes from event handler or lambda argument. One should
|
|
* only make \"PIByteArray & operator <<()\" with used types, deserialization will be
|
|
* performed by %PIParseHelper.
|
|
*
|
|
*
|
|
* \section PIParseHelper_usage Usage
|
|
*
|
|
* Create instance of %PIParseHelper, or subclass.
|
|
*
|
|
* In \a assign() methods you can use object member function, lambda-function
|
|
* or functor with 0 or 1 arguments,
|
|
*
|
|
*
|
|
* \section PIParseHelper_lambda Lambda-functions
|
|
* \code assign(1, [this](const SomeStruct & s){}) \endcode
|
|
*
|
|
*
|
|
* \section PIParseHelper_examples Examples
|
|
* First example describes subclass variant. As one can see, it`s a single place to change
|
|
* type of received data - event handler argument.
|
|
* \snippet piparsehelper.cpp 0
|
|
*
|
|
* Second example show separate variant:
|
|
* \snippet piparsehelper.cpp 1
|
|
*
|
|
**/
|
|
|
|
template<typename Key>
|
|
class PIParseHelper {
|
|
public:
|
|
//! \brief Construct %PIParseHelper
|
|
PIParseHelper() {}
|
|
|
|
|
|
//! \brief Assign key \"key\" to lambda-function \"func\" without arguments
|
|
void assign(Key key, std::function<void()> func) {
|
|
auto lf = [func](PIByteArray) { func(); };
|
|
functions[key] << lf;
|
|
}
|
|
|
|
|
|
//! \brief Assign key \"key\" to lambda-function \"func\" with 1 argument
|
|
template<typename T>
|
|
void assign(Key key, std::function<void(const T &)> func) {
|
|
auto lf = [func](PIByteArray data) {
|
|
if (!data.isEmpty()) {
|
|
T v;
|
|
data >> v;
|
|
func(v);
|
|
}
|
|
};
|
|
functions[key] << lf;
|
|
}
|
|
|
|
|
|
//! \brief Assign key \"key\" to member function of object \"obj\" without arguments
|
|
template<typename O>
|
|
void assign(Key key, O * obj, void (O::*member_func)()) {
|
|
auto lf = [member_func, obj](PIByteArray) { (obj->*member_func)(); };
|
|
functions[key] << lf;
|
|
}
|
|
|
|
|
|
//! \brief Assign key \"key\" to member function of object \"obj\" with 1 argument
|
|
template<typename T, typename O>
|
|
void assign(Key key, O * obj, void (O::*member_func)(const T &)) {
|
|
auto lf = [member_func, obj](PIByteArray data) {
|
|
if (!data.isEmpty()) {
|
|
T v;
|
|
data >> v;
|
|
(obj->*member_func)(v);
|
|
}
|
|
};
|
|
functions[key] << lf;
|
|
}
|
|
|
|
|
|
//! \brief Assign key \"key\" to functor \"func\" with 0 or 1 argument
|
|
template<typename L>
|
|
void assign(Key key, L func) {
|
|
return assign(key, toStdFunction(func));
|
|
}
|
|
|
|
|
|
//! \brief Deserialize data and invoke assigned to \"key\" methods
|
|
void parse(Key key, PIByteArray ba) {
|
|
auto fl = functions.value(key);
|
|
for (auto f: fl)
|
|
f(ba);
|
|
}
|
|
|
|
private:
|
|
PIMap<Key, PIVector<std::function<void(PIByteArray)>>> functions;
|
|
};
|
|
|
|
|
|
#endif // PIPARSEHELPER_H
|