From 99932d792c91ad72d70da7e8fc8a61de7cda724c Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Wed, 6 Oct 2021 12:29:06 +0300
Subject: [PATCH] added new macros for generate command

---
 Heart/AbstractSpace/abstractnode.cpp          | 24 +----
 Heart/AbstractSpace/abstractnode.h            | 34 ++------
 Heart/AbstractSpace/header.cpp                |  2 +-
 Heart/AbstractSpace/package.cpp               | 22 ++---
 Heart/AbstractSpace/package.h                 |  6 ++
 Heart/AbstractSpace/packages/abstractdata.cpp | 56 +++---------
 Heart/AbstractSpace/packages/abstractdata.h   | 87 +++++++++++--------
 Heart/AbstractSpace/packages/badrequest.h     |  5 +-
 Heart/AbstractSpace/packages/bigdatabase.h    |  2 +
 .../AbstractSpace/packages/bigdataheader.cpp  | 12 +--
 Heart/AbstractSpace/packages/bigdataheader.h  |  4 +-
 Heart/AbstractSpace/packages/bigdatapart.h    |  2 +
 Heart/AbstractSpace/packages/bigdatarequest.h |  3 +
 .../AbstractSpace/packages/closeconnection.h  |  2 +
 Heart/AbstractSpace/packages/ping.h           |  4 +-
 Heart/DataBaseSpace/databasenode.cpp          | 25 +-----
 Heart/DataBaseSpace/databasenode.h            | 15 ----
 .../packages/abstractnetworkmember.h          |  2 +
 Heart/DataBaseSpace/packages/authrequest.h    |  3 +-
 .../packages/cacheddbobjectsrequest.h         |  1 +
 Heart/DataBaseSpace/packages/dbobject.cpp     |  2 -
 Heart/DataBaseSpace/packages/dbobject.h       |  2 +
 Heart/DataBaseSpace/packages/dbobjectset.h    |  2 +
 .../DataBaseSpace/packages/defaultpermision.h |  2 +
 Heart/DataBaseSpace/packages/deleteobject.h   |  2 +
 .../DataBaseSpace/packages/getmaxintegerid.h  |  2 +
 Heart/DataBaseSpace/packages/getsinglevalue.h |  2 +
 .../packages/memberpermisionobject.cpp        | 10 +--
 .../packages/memberpermisionobject.h          |  3 +-
 Heart/DataBaseSpace/packages/networkmember.h  |  2 +
 Heart/DataBaseSpace/packages/setsinglevalue.h |  2 +
 Heart/DataBaseSpace/packages/usermember.h     |  2 +
 Heart/DataBaseSpace/packages/websocket.h      |  2 +
 .../packages/websocketsubscriptions.h         |  2 +
 Heart/DataBaseSpace/singleclient.cpp          | 14 ++-
 Heart/DataBaseSpace/singleclient.h            | 29 ++++++-
 Heart/DataBaseSpace/singleserver.cpp          |  4 +-
 Heart/heart.h                                 |  2 +-
 HeartTests/AbstractSpace/abstractnodetest.cpp |  1 -
 HeartTests/AbstractSpace/bigdatatest.cpp      |  8 +-
 .../DataBaseSpace/databasenodetesttemplate.h  |  2 -
 README.md                                     |  2 +-
 42 files changed, 192 insertions(+), 218 deletions(-)

diff --git a/Heart/AbstractSpace/abstractnode.cpp b/Heart/AbstractSpace/abstractnode.cpp
index 5209cab..52bbab4 100644
--- a/Heart/AbstractSpace/abstractnode.cpp
+++ b/Heart/AbstractSpace/abstractnode.cpp
@@ -544,7 +544,7 @@ ParserResult AbstractNode::parsePackage(const QSharedPointer<AbstractData> &pkg,
 
     incomingData(pkg.data(), sender);
 
-    if (H_16<Ping>() == pkg->cmd()) {
+    if (Ping::command() == pkg->cmd()) {
         auto cmd = static_cast<Ping *>(pkg.data());
         if (!cmd->ansver()) {
             cmd->setAnsver(true);
@@ -552,14 +552,14 @@ ParserResult AbstractNode::parsePackage(const QSharedPointer<AbstractData> &pkg,
         }
 
         return ParserResult::Processed;
-    } else if (H_16<BadRequest>() == pkg->cmd()) {
+    } else if (BadRequest::command() == pkg->cmd()) {
         auto cmd = static_cast<BadRequest *>(pkg.data());
 
         emit requestError(cmd->errCode(), cmd->err());
 
         return ParserResult::Processed;
 
-    } else if (H_16<CloseConnection>() == pkg->cmd()) {
+    } else if (CloseConnection::command() == pkg->cmd()) {
 
         if (sender->isLocal()) {
             removeNode(sender->networkAddress());
@@ -611,30 +611,12 @@ bool AbstractNode::sendPackage(const Package &pkg, QAbstractSocket *target) cons
     return _dataSender->sendData(pkg.toBytes(), target, true);
 }
 
-unsigned int AbstractNode::sendData(AbstractData *resp,
-                                    const HostAddress &addere,
-                                    const Header *req) {
-
-    return sendData(resp, getInfoPtr(addere), req);
-}
-
 unsigned int AbstractNode::sendData(const AbstractData *resp,
                                     const HostAddress &addere,
                                     const Header *req) {
     return sendData(resp, getInfoPtr(addere), req);
 }
 
-unsigned int AbstractNode::sendData(PKG::AbstractData *resp,
-                                    const AbstractNodeInfo *node,
-                                    const Header *req) {
-
-    if (!resp || !resp->prepareToSend()) {
-        return false;
-    }
-
-    return sendData(const_cast<const AbstractData*>(resp), node, req);
-}
-
 unsigned int AbstractNode::sendData(const PKG::AbstractData *resp,
                                     const AbstractNodeInfo *node,
                                     const Header *req) {
diff --git a/Heart/AbstractSpace/abstractnode.h b/Heart/AbstractSpace/abstractnode.h
index 93ff62c..b758c41 100644
--- a/Heart/AbstractSpace/abstractnode.h
+++ b/Heart/AbstractSpace/abstractnode.h
@@ -321,7 +321,7 @@ protected:
             }
 
             // you can use parsing without the commandHandler method
-            if (H_16<MyCommand>() == pkg->cmd()) {
+            if (MyCommand::command() == pkg->cmd()) {
 
                 BaseId requesterId = getSender(sender, &obj);
 
@@ -371,44 +371,24 @@ protected:
     virtual bool sendPackage(const Package &pkg, QAbstractSocket *target) const;
 
     /**
-     * @brief sendData This pakcage send data package to address and prepare object to sending.
-     * @param resp This is pointer to sendet object.
-     * @param address This is target addres for sending.
-     * @param req This is header of request.
-     * @return hash of the sendet package. If function is failed then return 0.
-     */
-    virtual unsigned int sendData(PKG::AbstractData *resp,  const HostAddress& address,
-                          const Header *req = nullptr);
-
-    /**
-     * @brief sendData this is some as a sendData(AbstractData *resp ...) exept this method not prepare object for sending.
+     * @brief sendData This method send data  object another to node
      * @param resp This is pointer to sendet object.
      * @param address This is target addres for sending.
      * @param req This is header of request.
      * @return hash of the sendet package. If function is failed then return 0.
      */
     virtual unsigned int sendData(const PKG::AbstractData *resp,  const HostAddress& address,
-                          const Header *req = nullptr);
+                                  const Header *req = nullptr);
 
     /**
-     * @brief sendData This pakcage send data package to node object and prepare object to sending.
-     * @param resp This is pointer to sendet object.
-     * @param address This is target addres for sending.
-     * @param req This is header of request.
-     * @return hash of the sendet package. If function is failed then return 0.
-     */
-    virtual unsigned int sendData(PKG::AbstractData *resp,  const AbstractNodeInfo *node,
-                          const Header *req = nullptr);
-
-    /**
-     * @brief sendData this is some as a sendData(AbstractData *resp ...) exept this method not prepare object for sending.
+     * @brief sendData This method send data  object another to node
      * @param resp This is pointer to sendet object.
      * @param address This is target addres for sending.
      * @param req This is header of request.
      * @return hash of the sendet package. If function is failed then return 0.
      */
     virtual unsigned int sendData(const PKG::AbstractData *resp, const AbstractNodeInfo *node,
-                          const Header *req = nullptr);
+                                  const Header *req = nullptr);
 
     /**
      * @brief badRequest This method is send data about error of request.
@@ -556,7 +536,7 @@ protected:
      * This is need to prepare pacakge for parsing in the parsePackage method.
      */
     void registerPackageType() {
-        _registeredTypes[H_16<T>()] = [](){
+        _registeredTypes[T::command()] = [](){
             return new T();
         };
     };
@@ -628,7 +608,7 @@ protected:
                                        const QH::AbstractNodeInfo *sender,
                                        const QH::Header &pkgHeader) {
 
-        if (H_16<PackageClass>() == pkg->cmd()) {
+        if (PackageClass::command() == pkg->cmd()) {
             auto data = pkg.staticCast<PackageClass>();
 
             if (!data->isValid()) {
diff --git a/Heart/AbstractSpace/header.cpp b/Heart/AbstractSpace/header.cpp
index 3d473da..3d170d0 100644
--- a/Heart/AbstractSpace/header.cpp
+++ b/Heart/AbstractSpace/header.cpp
@@ -15,7 +15,7 @@ Header::Header() {
 }
 
 bool Header::isValid() const {
-    return command && size && hash;
+    return command && hash;
 }
 
 void Header::reset() {
diff --git a/Heart/AbstractSpace/package.cpp b/Heart/AbstractSpace/package.cpp
index c2ee73b..7b2a13a 100644
--- a/Heart/AbstractSpace/package.cpp
+++ b/Heart/AbstractSpace/package.cpp
@@ -25,19 +25,7 @@ bool Package::isValid() const {
         return false;
     }
 
-    auto rawint = data.mid(0, sizeof (decltype (hdr.command)));
-    decltype (hdr.command) cmd;
-    memcpy(&cmd, rawint.data(), sizeof (cmd));
-
-    if (data.size() && hdr.command != cmd) {
-        std::reverse(rawint.begin(), rawint.end());
-        memcpy(&cmd, rawint.data(), sizeof (cmd));
-
-        if (hdr.command != cmd)
-            return false;
-    }
-
-    return static_cast<uint>(qHash(data)) == hdr.hash;
+    return calcHash() == hdr.hash;
 }
 
 void Package::reset() {
@@ -51,6 +39,14 @@ QString Package::toString() const {
             arg(hdr.toString()).arg(data.size()).arg(QString(data.toHex().toUpper()));
 }
 
+unsigned int Package::calcHash() const{
+    QByteArray hashArray(data);
+    hashArray.push_back(QByteArray::fromRawData(reinterpret_cast<const char*>(&hdr.command),
+                                                sizeof (hdr.command)));
+
+    return qHash(hashArray);
+}
+
 QDataStream &Package::fromStream(QDataStream &stream) {
     reset();
     stream.readRawData(reinterpret_cast<char*>(&hdr), sizeof(Header));
diff --git a/Heart/AbstractSpace/package.h b/Heart/AbstractSpace/package.h
index 1db874a..3e25a10 100644
--- a/Heart/AbstractSpace/package.h
+++ b/Heart/AbstractSpace/package.h
@@ -54,6 +54,12 @@ public:
      */
     QString toString() const;
 
+    /**
+     * @brief calcHash This method recalc hash sum for this pacakge.
+     * @return int32 hash of pacakge.
+     */
+    unsigned int calcHash() const;
+
     // StreamBase interface
 protected:
     QDataStream &fromStream(QDataStream &stream) override;
diff --git a/Heart/AbstractSpace/packages/abstractdata.cpp b/Heart/AbstractSpace/packages/abstractdata.cpp
index 11a8e95..f016dbc 100644
--- a/Heart/AbstractSpace/packages/abstractdata.cpp
+++ b/Heart/AbstractSpace/packages/abstractdata.cpp
@@ -16,41 +16,19 @@
 
 namespace QH {
 namespace PKG {
-unsigned short AbstractData::cmd() const {
-    if (_cmd)
-        return _cmd;
-
-    return generateCmd();
-}
-
-void AbstractData::setCmd(unsigned short cmd) {
-    _cmd = cmd;
-}
-
-bool AbstractData::init() {
-    if (typeid (*this).hash_code() == typeid(AbstractData).hash_code())
-        return false;
-
-    initCmd();
-
-    return true;
-}
-
-unsigned short AbstractData::generateCmd() const {
-    return H_16(*this);
-}
-
-void AbstractData::initCmd() {
-    setCmd(generateCmd());
-}
 
 AbstractData::AbstractData() {
-    setCmd(0);
 }
 
 bool AbstractData::toPackage(Package &package,
                              unsigned int triggerHash) const {
 
+    if (!checkCmd()) {
+        QuasarAppUtils::Params::log("You try send pacakge without QH_PACKAGE macross. Please add QH_PACKAGE macros to this class.",
+                                    QuasarAppUtils::Error);
+        return false;
+    }
+
     if (!isValid()) {
         return false;
     }
@@ -61,44 +39,38 @@ bool AbstractData::toPackage(Package &package,
     package.hdr.triggerHash = triggerHash;
     int realDataSize = package.data.size();
     package.hdr.size = static_cast<unsigned short>(realDataSize);
-    package.hdr.hash = qHash(package.data);
+    package.hdr.hash = package.calcHash();
 
     return package.isValid();
 }
 
 QDataStream &AbstractData::fromStream(QDataStream &stream) {
-    stream >> _cmd;
     return stream;
 }
 
 QDataStream &AbstractData::toStream(QDataStream &stream) const {
-    stream << cmd();
     return stream;
 }
 
+bool AbstractData::checkCmd() const {
+    unsigned int code = typeid (*this).hash_code();
+    return code == localCode(); \
+}
+
 bool AbstractData::isValid() const {
-    return cmd();
+    return true;
 }
 
 bool AbstractData::copyFrom(const AbstractData *other) {
-
     return other;
 }
 
 QString AbstractData::toString() const {
     return QString("Object: type:%0, command:%1").
-            arg(typeid(*this).name()).
+            arg(cmdString()).
             arg(cmd());
 }
 
-bool AbstractData::prepareToSend() {
-    if (isValid()) {
-        return true;
-    }
-
-    return init();
-}
-
 void AbstractData::fromPakcage(const Package &pkg) {
     fromBytes(pkg.data);
 }
diff --git a/Heart/AbstractSpace/packages/abstractdata.h b/Heart/AbstractSpace/packages/abstractdata.h
index f76eb25..eb7bc37 100644
--- a/Heart/AbstractSpace/packages/abstractdata.h
+++ b/Heart/AbstractSpace/packages/abstractdata.h
@@ -11,6 +11,22 @@
 #include <streambase.h>
 #include <global.h>
 
+
+/**
+ * @brief QH_PACKAGE This macross prepare data to send and create a global id for package. For get global id use the cmd method.
+ * For get quick access for global command use the ClassName::command() method. This method is static.
+*/
+#define QH_PACKAGE(X, S) \
+   public: \
+    static unsigned short command(){return qHash(QString(S)) % 0xFFFF;} \
+    static QString commandText(){return S;} \
+    unsigned short cmd() const override {return X::command();} \
+    QString cmdString() const override {return X::commandText();} \
+   protected: \
+    unsigned int localCode() const override {return typeid(X).hash_code();} \
+    \
+   private:
+
 namespace QH {
 namespace PKG {
 
@@ -49,6 +65,7 @@ protected:
  * \code {cpp}
  * class MyPackage: public QH::AbstractData
 {
+    QH_PACKAGE(MyPackage, "MyPackage")
     ...
     bool copyFrom(const AbstractData *other) {
         if (!AbstractData::copyFrom(other))
@@ -110,10 +127,20 @@ public:
     virtual ~AbstractData() override;
 
     /**
-     * @brief cmd - This is command of this object, (for generate cmd use macross H16<ClassName>)
-     * @return Command of package.
+     * @brief cmd - This is command of this object, (for generate cmd use macross QH_PACKAGE)
+     * @note Use the QH_PACKAGE macross for implement this method.
+     * @return global command of package.
+     * @see QH_PACKAGE
      */
-    unsigned short cmd() const;
+    virtual unsigned short cmd() const = 0;
+
+    /**
+     * @brief cmd - This is command string of this object, (for generate cmd use macross QH_PACKAGE)
+     * @note Use the QH_PACKAGE macross for implement this method.
+     * @return global command of package.
+     * @see QH_PACKAGE
+     */
+    virtual QString cmdString() const = 0;
 
     /**
      * @brief toPackage This method convert this class object to the package.
@@ -157,12 +184,6 @@ public:
      */
     virtual QString toString() const;
 
-    /**
-     * @brief prepareToSend - This method check object to valid and if an object is invalid invoke method init.
-     * @return Return true if the object prepared for sending.
-     */
-    bool prepareToSend();
-
     /**
      * @brief create - This is factory method for create a new object.
      * @param args - List of arguments for create object.
@@ -171,7 +192,6 @@ public:
     template<class C, class... Args>
     C* create(Args&&... args) const {
         C* object = new C(std::forward<Args>(args)...);
-        object->generateCmd();
         return object;
     }
 
@@ -181,49 +201,42 @@ public:
      */
     void fromPakcage(const Package& pkg);
 
+    /**
+     * @brief command This static method that return glaball code of this object.
+     * @note This method generated automaticaly in the QH_PACKAGE macross.
+     * @return global code
+     * @see QH_PACKAGE
+     */
+    static unsigned int command(){return 0;};
+
+    /**
+     * @brief commandText This method return text of package command
+     * @return text of pacakge command
+     */
+    static QString commandText(){return "NULL";};
+
 protected:
     /**
      * @brief AbstractData - Base constructor of this object.
      */
     explicit AbstractData();
 
-
     /**
-     * @brief setCmd - Set the new value command of object.
-     * @param cmd - New value.
+     * @brief localCode This method return local code
+     * @return local command of this class. used for check QH_PACKAGE macro before send pacakge.
      */
-    void setCmd(unsigned short cmd);
-
-    /**
-     * @brief Init This method need to invoke after create object for initialize all component of objects.
-     * @note Do not invade this method on constructor of object, because object will be initialized not correctly.
-     *  By default implementation of object init command.
-     * @return True if object initialized correctly.
-     */
-    virtual bool init();
+    virtual unsigned int localCode() const = 0;
 
     QDataStream& fromStream(QDataStream& stream) override;
     QDataStream& toStream(QDataStream& stream) const override;
 
 private:
     /**
-     * @brief generateCmd Generate command from name of this class object.
-     * @note Call this method only after create objects. Do not call in constructor of class.
-     * @return Command of object.
+     * @brief checkCmd This method check QH_PACKAGE macross.
+     * @return true if the QH_PACKAGE macross is enabled else fal.
      */
-    unsigned short generateCmd() const;
+    bool checkCmd() const;;
 
-
-    /**
-     * @brief initCmd Set cmd from class name.
-     * @note Call this method only after create objects. Do not call in constructor of class.
-     */
-    void initCmd();
-
-    /**
-     * @brief cmd - Unique id of class using in Header of package for identification.
-     */
-    unsigned short _cmd = 0;
 };
 
 
diff --git a/Heart/AbstractSpace/packages/badrequest.h b/Heart/AbstractSpace/packages/badrequest.h
index dbd05ee..2d16ae9 100644
--- a/Heart/AbstractSpace/packages/badrequest.h
+++ b/Heart/AbstractSpace/packages/badrequest.h
@@ -33,6 +33,7 @@ struct ErrorData {
  */
 class HEARTSHARED_EXPORT BadRequest : public AbstractData
 {
+    QH_PACKAGE(BadRequest, "BadRequest")
 public:
 
     /**
@@ -62,8 +63,8 @@ public:
     void setErr(const QString &err);
 
     // StreamBase interface
-    QDataStream &fromStream(QDataStream &stream);
-    QDataStream &toStream(QDataStream &stream) const;
+    QDataStream &fromStream(QDataStream &stream) override;
+    QDataStream &toStream(QDataStream &stream) const override;
 
     /**
      * @brief errCode This method return code of error.
diff --git a/Heart/AbstractSpace/packages/bigdatabase.h b/Heart/AbstractSpace/packages/bigdatabase.h
index 5ba6d59..b1485af 100644
--- a/Heart/AbstractSpace/packages/bigdatabase.h
+++ b/Heart/AbstractSpace/packages/bigdatabase.h
@@ -19,6 +19,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT BigDataBase: public AbstractData
 {
+    QH_PACKAGE(BigDataBase, "BigDataBase")
+
 public:
     BigDataBase();
 
diff --git a/Heart/AbstractSpace/packages/bigdataheader.cpp b/Heart/AbstractSpace/packages/bigdataheader.cpp
index 1ec3af3..79bb404 100644
--- a/Heart/AbstractSpace/packages/bigdataheader.cpp
+++ b/Heart/AbstractSpace/packages/bigdataheader.cpp
@@ -15,7 +15,7 @@ BigDataHeader::BigDataHeader() {
 }
 
 bool BigDataHeader::isValid() const {
-    return BigDataBase::isValid() && packagesCount >= 2 && command;
+    return BigDataBase::isValid() && packagesCount >= 2 && _command;
 }
 
 QString BigDataHeader::toString() const {
@@ -23,7 +23,7 @@ QString BigDataHeader::toString() const {
             " Packages count: " +
             QString::number(packagesCount) +
             " Packages command: " +
-            QString::number(command);
+            QString::number(_command);
 }
 
 int BigDataHeader::getPackagesCount() const {
@@ -38,7 +38,7 @@ QDataStream &BigDataHeader::fromStream(QDataStream &stream) {
     BigDataBase::fromStream(stream);
 
     stream >> packagesCount;
-    stream >> command;
+    stream >> _command;
 
     return stream;
 }
@@ -47,17 +47,17 @@ QDataStream &BigDataHeader::toStream(QDataStream &stream) const {
     BigDataBase::toStream(stream);
 
     stream << packagesCount;
-    stream << command;
+    stream << _command;
 
     return stream;
 }
 
 unsigned short BigDataHeader::getCommand() const {
-    return command;
+    return _command;
 }
 
 void BigDataHeader::setCommand(unsigned short newCommand) {
-    command = newCommand;
+    _command = newCommand;
 }
 
 }
diff --git a/Heart/AbstractSpace/packages/bigdataheader.h b/Heart/AbstractSpace/packages/bigdataheader.h
index 433e483..3650a42 100644
--- a/Heart/AbstractSpace/packages/bigdataheader.h
+++ b/Heart/AbstractSpace/packages/bigdataheader.h
@@ -27,6 +27,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT BigDataHeader : public BigDataBase
 {
+    QH_PACKAGE(BigDataHeader, "BigDataHeader")
+
 public:
     BigDataHeader();
 
@@ -64,7 +66,7 @@ protected:
 
 private:
     int packagesCount;
-    unsigned short command;
+    unsigned short _command;
 };
 }
 }
diff --git a/Heart/AbstractSpace/packages/bigdatapart.h b/Heart/AbstractSpace/packages/bigdatapart.h
index 34d3ef3..12de0c8 100644
--- a/Heart/AbstractSpace/packages/bigdatapart.h
+++ b/Heart/AbstractSpace/packages/bigdatapart.h
@@ -20,6 +20,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT BigDataPart : public BigDataBase
 {
+    QH_PACKAGE(BigDataPart, "BigDataPart")
+
 public:
     BigDataPart();
 
diff --git a/Heart/AbstractSpace/packages/bigdatarequest.h b/Heart/AbstractSpace/packages/bigdatarequest.h
index 0e2c3f1..97d32fd 100644
--- a/Heart/AbstractSpace/packages/bigdatarequest.h
+++ b/Heart/AbstractSpace/packages/bigdatarequest.h
@@ -19,6 +19,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT BigDataRequest: public BigDataBase
 {
+    QH_PACKAGE(BigDataRequest, "BigDataRequest")
+
 public:
     BigDataRequest();
 
@@ -43,6 +45,7 @@ protected:
 private:
     int _currentPart = 0;
 
+
 };
 
 }
diff --git a/Heart/AbstractSpace/packages/closeconnection.h b/Heart/AbstractSpace/packages/closeconnection.h
index b428a87..f3e271b 100644
--- a/Heart/AbstractSpace/packages/closeconnection.h
+++ b/Heart/AbstractSpace/packages/closeconnection.h
@@ -27,6 +27,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT CloseConnection: public AbstractData
 {
+    QH_PACKAGE(CloseConnection, "CloseConnection")
+
 public:
     CloseConnection();
 };
diff --git a/Heart/AbstractSpace/packages/ping.h b/Heart/AbstractSpace/packages/ping.h
index e2e4881..935ce38 100644
--- a/Heart/AbstractSpace/packages/ping.h
+++ b/Heart/AbstractSpace/packages/ping.h
@@ -20,6 +20,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT Ping: public AbstractData
 {
+    QH_PACKAGE(Ping, "Ping")
+
 public:
     Ping();
     Ping(const Package& from);
@@ -29,7 +31,7 @@ public:
      * @brief isValid - Check this package if valid.
      * @return True if package is valid.
      */
-    bool isValid() const;
+    bool isValid() const override;
 
     /**
      * @brief answer This is bool value for check this object that it is answer or request.
diff --git a/Heart/DataBaseSpace/databasenode.cpp b/Heart/DataBaseSpace/databasenode.cpp
index c7dc01f..c4d383f 100644
--- a/Heart/DataBaseSpace/databasenode.cpp
+++ b/Heart/DataBaseSpace/databasenode.cpp
@@ -256,18 +256,6 @@ bool DataBaseNode::changeTrust(const QVariant &id, int diff) {
     return _db->changeObjects(NetworkMember{id}, action);
 }
 
-unsigned int DataBaseNode::sendData(AbstractData *resp,
-                            const QVariant &nodeId,
-                            const Header *req) {
-
-
-    if (!resp || !resp->prepareToSend()) {
-        return 0;
-    }
-
-    return sendData(const_cast<const AbstractData*>(resp), nodeId, req);
-}
-
 unsigned int DataBaseNode::sendData(const AbstractData *resp,
                             const QVariant &nodeId,
                             const Header *req) {
@@ -290,23 +278,12 @@ unsigned int DataBaseNode::sendData(const AbstractData *resp, const HostAddress
 
 }
 
-unsigned int DataBaseNode::sendData(AbstractData *resp, const HostAddress &nodeId,
-                            const Header *req) {
-    return AbstractNode::sendData(resp, nodeId, req);
-}
-
 unsigned int DataBaseNode::sendData(const PKG::AbstractData *resp,
                                     const AbstractNodeInfo *node,
                                     const Header *req) {
     return AbstractNode::sendData(resp, node, req);
 }
 
-unsigned int DataBaseNode::sendData(PKG::AbstractData *resp,
-                                    const AbstractNodeInfo *node,
-                                    const Header *req) {
-    return AbstractNode::sendData(resp, node, req);
-}
-
 ParserResult DataBaseNode::parsePackage(const QSharedPointer<AbstractData> &pkg,
                                         const Header &pkgHeader,
                                         const AbstractNodeInfo *sender) {
@@ -315,7 +292,7 @@ ParserResult DataBaseNode::parsePackage(const QSharedPointer<AbstractData> &pkg,
         return parentResult;
     }
 
-    if (H_16<WebSocket>() == pkg->cmd()) {
+    if (WebSocket::command() == pkg->cmd()) {
         WebSocket *obj = static_cast<WebSocket*>(pkg.data());
 
         QVariant requesterId = getSender(sender, obj);
diff --git a/Heart/DataBaseSpace/databasenode.h b/Heart/DataBaseSpace/databasenode.h
index b0a7f8c..270ec64 100644
--- a/Heart/DataBaseSpace/databasenode.h
+++ b/Heart/DataBaseSpace/databasenode.h
@@ -211,17 +211,6 @@ protected:
      */
     virtual bool changeTrust(const QVariant &id, int diff);
 
-    /**
-     * @brief sendData This method is some as AbstractNode::sendData but it try send data to the id.
-     *  This implementation prepare object to sending.
-     * @param resp This is sending object to the nodeId.
-     * @param nodeId This is id of target node.
-     * @param req This is header of request.
-     * @return true if a data send successful.
-     */
-    virtual unsigned int sendData(PKG::AbstractData *resp, const QVariant &nodeId,
-                          const Header *req = nullptr);
-
     /**
      * @brief sendData This method is some as AbstractNode::sendData but it try send data to the id.
      *  This implementation do not prepare object to sending.
@@ -235,13 +224,9 @@ protected:
 
     unsigned int sendData(const PKG::AbstractData *resp, const HostAddress &nodeId,
                   const Header *req = nullptr) override;
-    unsigned int sendData(PKG::AbstractData *resp, const HostAddress &nodeId,
-                  const Header *req = nullptr) override;
 
     unsigned int sendData(const PKG::AbstractData *resp, const AbstractNodeInfo *node,
                   const Header *req = nullptr) override;
-    unsigned int sendData(PKG::AbstractData *resp, const AbstractNodeInfo *node,
-                  const Header *req = nullptr) override;
 
     /**
      * @brief hashgenerator This method generate a hash from any value.
diff --git a/Heart/DataBaseSpace/packages/abstractnetworkmember.h b/Heart/DataBaseSpace/packages/abstractnetworkmember.h
index a6d3439..806a6b3 100644
--- a/Heart/DataBaseSpace/packages/abstractnetworkmember.h
+++ b/Heart/DataBaseSpace/packages/abstractnetworkmember.h
@@ -21,6 +21,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT AbstractNetworkMember: public DBObject
 {
+    QH_PACKAGE(AbstractNetworkMember, "AbstractNetworkMember")
+
 public:
     AbstractNetworkMember();
     AbstractNetworkMember(const Package& pkg);
diff --git a/Heart/DataBaseSpace/packages/authrequest.h b/Heart/DataBaseSpace/packages/authrequest.h
index 233f42a..68bb323 100644
--- a/Heart/DataBaseSpace/packages/authrequest.h
+++ b/Heart/DataBaseSpace/packages/authrequest.h
@@ -12,7 +12,6 @@
 
 #include <request.h>
 
-
 namespace QH {
 
 
@@ -36,6 +35,8 @@ enum class UserRequestType: unsigned char {
  */
 class HEARTSHARED_EXPORT AuthRequest: public UserMember, public Request
 {
+    QH_PACKAGE(AuthRequest, "AuthRequest")
+
 public:
     AuthRequest();
     AuthRequest(const Package& pkg);
diff --git a/Heart/DataBaseSpace/packages/cacheddbobjectsrequest.h b/Heart/DataBaseSpace/packages/cacheddbobjectsrequest.h
index fb9662e..0554821 100644
--- a/Heart/DataBaseSpace/packages/cacheddbobjectsrequest.h
+++ b/Heart/DataBaseSpace/packages/cacheddbobjectsrequest.h
@@ -36,6 +36,7 @@ template <class BASE>
  */
 class CachedDbObjectsRequest : public BASE
 {
+
 public:
     CachedDbObjectsRequest(const QString& condition) {
         _condition = condition;
diff --git a/Heart/DataBaseSpace/packages/dbobject.cpp b/Heart/DataBaseSpace/packages/dbobject.cpp
index 02c45a3..dea9f40 100644
--- a/Heart/DataBaseSpace/packages/dbobject.cpp
+++ b/Heart/DataBaseSpace/packages/dbobject.cpp
@@ -287,8 +287,6 @@ DBObject *DBObject::cloneRaw() const {
         return nullptr;
     }
 
-    cloneObject->init();
-
     return cloneObject;
 }
 
diff --git a/Heart/DataBaseSpace/packages/dbobject.h b/Heart/DataBaseSpace/packages/dbobject.h
index 4742e98..01599a1 100644
--- a/Heart/DataBaseSpace/packages/dbobject.h
+++ b/Heart/DataBaseSpace/packages/dbobject.h
@@ -92,6 +92,8 @@ typedef QMap<QString, DBVariant> DBVariantMap;
  */
 class HEARTSHARED_EXPORT DBObject : public AbstractData, public ISubscribableData
 {
+    QH_PACKAGE(DBObject, "DBObject")
+
 public:
 
     /**
diff --git a/Heart/DataBaseSpace/packages/dbobjectset.h b/Heart/DataBaseSpace/packages/dbobjectset.h
index e87fca5..c414a42 100644
--- a/Heart/DataBaseSpace/packages/dbobjectset.h
+++ b/Heart/DataBaseSpace/packages/dbobjectset.h
@@ -22,6 +22,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT DBObjectSet: public DBObject
 {
+    QH_PACKAGE(DBObjectSet, "DBObjectSet")
+
 public:
     DBObjectSet(const QString table);
 
diff --git a/Heart/DataBaseSpace/packages/defaultpermision.h b/Heart/DataBaseSpace/packages/defaultpermision.h
index d808bb9..76cfb69 100644
--- a/Heart/DataBaseSpace/packages/defaultpermision.h
+++ b/Heart/DataBaseSpace/packages/defaultpermision.h
@@ -21,6 +21,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT DefaultPermision: public MemberPermisionObject
 {
+    QH_PACKAGE(DefaultPermision, "DefaultPermision")
+
 public:
     DefaultPermision();
     DefaultPermision(const PermisionData& permision);
diff --git a/Heart/DataBaseSpace/packages/deleteobject.h b/Heart/DataBaseSpace/packages/deleteobject.h
index 32b68a1..651342b 100644
--- a/Heart/DataBaseSpace/packages/deleteobject.h
+++ b/Heart/DataBaseSpace/packages/deleteobject.h
@@ -19,6 +19,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT DeleteObject: public DBObject, public IToken
 {
+    QH_PACKAGE(DeleteObject, "DeleteObject")
+
 public:
     DeleteObject();
     DeleteObject(const Package& pkg);
diff --git a/Heart/DataBaseSpace/packages/getmaxintegerid.h b/Heart/DataBaseSpace/packages/getmaxintegerid.h
index 3023fb2..26dd83d 100644
--- a/Heart/DataBaseSpace/packages/getmaxintegerid.h
+++ b/Heart/DataBaseSpace/packages/getmaxintegerid.h
@@ -19,6 +19,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT GetMaxIntegerId: public DBObject
 {
+    QH_PACKAGE(GetMaxIntegerId, "GetMaxIntegerId")
+
 public:
     /**
      * @brief GetMaxIntegerId This is default constructor of the GetMaxIntegerId class.
diff --git a/Heart/DataBaseSpace/packages/getsinglevalue.h b/Heart/DataBaseSpace/packages/getsinglevalue.h
index fa9da58..9e121c8 100644
--- a/Heart/DataBaseSpace/packages/getsinglevalue.h
+++ b/Heart/DataBaseSpace/packages/getsinglevalue.h
@@ -22,6 +22,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT GetSingleValue final: public DBObject
 {
+    QH_PACKAGE(GetSingleValue, "GetSingleValue")
+
 public:
     /**
      * @brief GetSingleValue This is default constructor of the GetMaxIntegerId class.
diff --git a/Heart/DataBaseSpace/packages/memberpermisionobject.cpp b/Heart/DataBaseSpace/packages/memberpermisionobject.cpp
index 752d2ba..2c1fe8c 100644
--- a/Heart/DataBaseSpace/packages/memberpermisionobject.cpp
+++ b/Heart/DataBaseSpace/packages/memberpermisionobject.cpp
@@ -117,21 +117,13 @@ QString MemberPermisionObject::primaryKey() const {
     return "";
 }
 
-bool MemberPermisionObject::init() {
-    if (!DBObject::init())
-        return false;
-
-    setId(_key.hash());
-
-    return true;
-}
-
 PermisionData MemberPermisionObject::key() const {
     return _key;
 }
 
 void MemberPermisionObject::setKey(const PermisionData &key) {
     _key = key;
+    setId(_key.hash());
 }
 
 Permission MemberPermisionObject::permisions() const {
diff --git a/Heart/DataBaseSpace/packages/memberpermisionobject.h b/Heart/DataBaseSpace/packages/memberpermisionobject.h
index 9038067..89f5766 100644
--- a/Heart/DataBaseSpace/packages/memberpermisionobject.h
+++ b/Heart/DataBaseSpace/packages/memberpermisionobject.h
@@ -22,6 +22,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT MemberPermisionObject: public DBObject
 {
+    QH_PACKAGE(MemberPermisionObject, "MemberPermisionObject")
+
 public:
     MemberPermisionObject();
     MemberPermisionObject(const Package& pkg);
@@ -75,7 +77,6 @@ protected:
     QDataStream &toStream(QDataStream &stream) const override;
     QString condition() const override;
     QString primaryKey() const override;
-    bool init() override;
 
 private:
     Permission _permision;
diff --git a/Heart/DataBaseSpace/packages/networkmember.h b/Heart/DataBaseSpace/packages/networkmember.h
index 6cd4480..4c05735 100644
--- a/Heart/DataBaseSpace/packages/networkmember.h
+++ b/Heart/DataBaseSpace/packages/networkmember.h
@@ -20,6 +20,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT NetworkMember: public AbstractNetworkMember
 {
+    QH_PACKAGE(NetworkMember, "NetworkMember")
+
 public:
     NetworkMember();
     NetworkMember(const QVariant& id);
diff --git a/Heart/DataBaseSpace/packages/setsinglevalue.h b/Heart/DataBaseSpace/packages/setsinglevalue.h
index 7bf503d..023b98d 100644
--- a/Heart/DataBaseSpace/packages/setsinglevalue.h
+++ b/Heart/DataBaseSpace/packages/setsinglevalue.h
@@ -30,6 +30,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT SetSingleValue final: public DBObject
 {
+    QH_PACKAGE(SetSingleValue, "SetSingleValue")
+
 public:
     /**
      * @brief SetSingleValue This is default constructor of the update query generator.
diff --git a/Heart/DataBaseSpace/packages/usermember.h b/Heart/DataBaseSpace/packages/usermember.h
index e1ba2d3..07224ce 100644
--- a/Heart/DataBaseSpace/packages/usermember.h
+++ b/Heart/DataBaseSpace/packages/usermember.h
@@ -21,6 +21,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT UserMember: public AbstractNetworkMember
 {
+    QH_PACKAGE(UserMember, "UserMember")
+
 public:
     UserMember();
     UserMember(const Package &pkg);
diff --git a/Heart/DataBaseSpace/packages/websocket.h b/Heart/DataBaseSpace/packages/websocket.h
index 9774cac..9e8ac63 100644
--- a/Heart/DataBaseSpace/packages/websocket.h
+++ b/Heart/DataBaseSpace/packages/websocket.h
@@ -37,6 +37,8 @@ enum class WebSocketRequest {
 class HEARTSHARED_EXPORT WebSocket:
         public AbstractData, public Request
 {
+    QH_PACKAGE(WebSocket, "WebSocket")
+
 public:
     WebSocket();
     WebSocket(const Package& package);
diff --git a/Heart/DataBaseSpace/packages/websocketsubscriptions.h b/Heart/DataBaseSpace/packages/websocketsubscriptions.h
index 141eafd..3095b49 100644
--- a/Heart/DataBaseSpace/packages/websocketsubscriptions.h
+++ b/Heart/DataBaseSpace/packages/websocketsubscriptions.h
@@ -23,6 +23,8 @@ namespace PKG {
  */
 class HEARTSHARED_EXPORT WebSocketSubscriptions: public AbstractData
 {
+    QH_PACKAGE(WebSocketSubscriptions, "WebSocketSubscriptions")
+
 public:
     WebSocketSubscriptions();
     WebSocketSubscriptions(const Package& package);
diff --git a/Heart/DataBaseSpace/singleclient.cpp b/Heart/DataBaseSpace/singleclient.cpp
index 2e96e34..48c29c4 100644
--- a/Heart/DataBaseSpace/singleclient.cpp
+++ b/Heart/DataBaseSpace/singleclient.cpp
@@ -37,7 +37,7 @@ ParserResult SingleClient::parsePackage(const QSharedPointer<PKG::AbstractData>
         return parentResult;
     }
 
-    if (H_16<QH::PKG::UserMember>() == pkg->cmd()) {
+    if (QH::PKG::UserMember::command() == pkg->cmd()) {
         QH::PKG::UserMember *obj = static_cast<QH::PKG::UserMember*>(pkg.data());
 
         if (!(obj->isValid() && obj->getSignToken().isValid())) {
@@ -51,7 +51,7 @@ ParserResult SingleClient::parsePackage(const QSharedPointer<PKG::AbstractData>
 
         return QH::ParserResult::Processed;
 
-    } else if (H_16<PKG::WebSocketSubscriptions>() == pkg->cmd()) {
+    } else if (PKG::WebSocketSubscriptions::command() == pkg->cmd()) {
         PKG::WebSocketSubscriptions *obj = static_cast<PKG::WebSocketSubscriptions*>(pkg.data());
         if (!obj->isValid()) {
             return ParserResult::Error;
@@ -338,6 +338,16 @@ unsigned int SingleClient::sendData(PKG::AbstractData *resp,
     return DataBaseNode::sendData(resp, address, req);
 }
 
+unsigned int SingleClient::sendData(PKG::AbstractData *resp,
+                                    const AbstractNode *node,
+                                    const Header *req) {
+    if (!signPackageWithToken(resp)) {
+        return 0;
+    }
+
+    return DataBaseNode::sendData(resp, node, req);
+}
+
 unsigned int SingleClient::sendData(PKG::AbstractData *resp,
                                     const QVariant &nodeId,
                                     const Header *req) {
diff --git a/Heart/DataBaseSpace/singleclient.h b/Heart/DataBaseSpace/singleclient.h
index 2acd50f..ce92ad2 100644
--- a/Heart/DataBaseSpace/singleclient.h
+++ b/Heart/DataBaseSpace/singleclient.h
@@ -275,13 +275,38 @@ protected:
     void nodeConnected(AbstractNodeInfo *node) override;
     void nodeDisconnected(AbstractNodeInfo *node) override;
 
+    /**
+     * @brief sendData This method is wraper of default sendData method but add sign to sendet pacakge.
+     * @param resp This is pointer to sendet object.
+     * @param address This is target addres for sending.
+     * @param req This is header of request.
+     * @return hash of the sendet package. If function is failed then return 0.
+     */
     unsigned int sendData(PKG::AbstractData *resp,
                           const HostAddress &address,
-                          const Header *req = nullptr) override;
+                          const Header *req = nullptr);
 
+    /**
+     * @brief sendData This method is wraper of default sendData method but add sign to sendet pacakge.
+     * @param resp This is pointer to sendet object.
+     * @param address This is target addres for sending.
+     * @param req This is header of request.
+     * @return hash of the sendet package. If function is failed then return 0.
+     */
+    unsigned int sendData(PKG::AbstractData *resp,
+                          const AbstractNode *node,
+                          const Header *req = nullptr);
+
+    /**
+     * @brief sendData This method is wraper of default sendData method but add sign to sendet pacakge.
+     * @param resp This is sending object to the nodeId.
+     * @param nodeId This is id of target node.
+     * @param req This is header of request.
+     * @return true if a data send successful.
+     */
     unsigned int sendData(PKG::AbstractData *resp,
                           const QVariant &nodeId,
-                          const Header *req = nullptr) override;
+                          const Header *req = nullptr);
 
     /**
      * @brief realServerAddress This method return the real server address that connected with this node.
diff --git a/Heart/DataBaseSpace/singleserver.cpp b/Heart/DataBaseSpace/singleserver.cpp
index 7e53f44..b142060 100644
--- a/Heart/DataBaseSpace/singleserver.cpp
+++ b/Heart/DataBaseSpace/singleserver.cpp
@@ -160,7 +160,7 @@ ParserResult SingleServer::parsePackage(const QSharedPointer<PKG::AbstractData>
         return parentResult;
     }
 
-    if (H_16<QH::PKG::AuthRequest>() == pkg->cmd()) {
+    if (QH::PKG::AuthRequest::command() == pkg->cmd()) {
         auto obj = pkg.staticCast<QH::PKG::AuthRequest>();
 
         if (!obj->isValid()) {
@@ -193,7 +193,7 @@ ParserResult SingleServer::parsePackage(const QSharedPointer<PKG::AbstractData>
     };
 
 
-    if (H_16<PKG::DeleteObject>() == pkg->cmd()) {
+    if (PKG::DeleteObject::command() == pkg->cmd()) {
         auto obj = pkg.staticCast<PKG::DeleteObject>();
 
         auto requesterId = getSender(sender, obj.data());
diff --git a/Heart/heart.h b/Heart/heart.h
index 9edc82f..94e3376 100644
--- a/Heart/heart.h
+++ b/Heart/heart.h
@@ -130,7 +130,7 @@ protected:
             return parentResult;
         }
 
-        if (H_16<MyPackage>() == pkg.hdr.command) {
+        if (MyPackage::command() == pkg.hdr.command) {
             MyPackage obj(pkg);
 
             // print responce of server
diff --git a/HeartTests/AbstractSpace/abstractnodetest.cpp b/HeartTests/AbstractSpace/abstractnodetest.cpp
index 1b1fa05..3a33499 100644
--- a/HeartTests/AbstractSpace/abstractnodetest.cpp
+++ b/HeartTests/AbstractSpace/abstractnodetest.cpp
@@ -17,7 +17,6 @@
 
 class TestingClient: public QH::AbstractNode {
 
-
     // AbstractNode interface
 public:
     const QH::PKG::Ping& getPing() const {
diff --git a/HeartTests/AbstractSpace/bigdatatest.cpp b/HeartTests/AbstractSpace/bigdatatest.cpp
index 2104be1..11309fb 100644
--- a/HeartTests/AbstractSpace/bigdatatest.cpp
+++ b/HeartTests/AbstractSpace/bigdatatest.cpp
@@ -12,7 +12,7 @@
 #define LOCAL_TEST_PORT TEST_PORT + 4
 
 class BigPackage: public QH::PKG::AbstractData {
-
+    QH_PACKAGE(BigPackage, "BigPackage")
 public:
     BigPackage(){
         data = {};
@@ -21,7 +21,7 @@ public:
 
     // StreamBase interface
 protected:
-    QDataStream &fromStream(QDataStream &stream) {
+    QDataStream &fromStream(QDataStream &stream) override{
         AbstractData::fromStream(stream);
 
         stream >> data;
@@ -29,7 +29,7 @@ protected:
         return stream;
     };
 
-    QDataStream &toStream(QDataStream &stream) const {
+    QDataStream &toStream(QDataStream &stream) const override{
         AbstractData::toStream(stream);
 
         stream << data;
@@ -64,7 +64,7 @@ protected:
     void incomingData(const QH::PKG::AbstractData *pkg, const QH::AbstractNodeInfo *sender) override {
         Q_UNUSED(sender);
 
-        if (pkg->cmd() == H_16<BigPackage>()) {
+        if (pkg->cmd() == BigPackage::command()) {
 
             data->copy<BigPackage>(*pkg);
             sendData(data, sender);
diff --git a/HeartTests/DataBaseSpace/databasenodetesttemplate.h b/HeartTests/DataBaseSpace/databasenodetesttemplate.h
index 0a069a4..3ab96a1 100644
--- a/HeartTests/DataBaseSpace/databasenodetesttemplate.h
+++ b/HeartTests/DataBaseSpace/databasenodetesttemplate.h
@@ -24,8 +24,6 @@ protected:
         res->setTrust(0);
         res->setId(QString(this->randomArray(5).toHex()));
 
-        res->prepareToSend();
-
         return res;
 
     };
diff --git a/README.md b/README.md
index ac8f57e..5e852b2 100644
--- a/README.md
+++ b/README.md
@@ -150,7 +150,7 @@ protected:
             return parentResult;
         }
     
-        if (H_16<MyPackage>() == pkg.hdr.command) {
+        if (MyPackage::command() == pkg.hdr.command) {
             MyPackage obj(pkg);
    
             // print responce of server