refactoring message

This commit is contained in:
2025-11-10 10:43:13 +01:00
parent 598f1262d7
commit f064794499
13 changed files with 1968 additions and 1626 deletions
+729
View File
@@ -0,0 +1,729 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: Message.h
* Author: Hagi
*
* Created on 3. April 2019, 08:51
*/
#pragma once
#include <cstdlib>
#include <memory>
#include <optional>
#include <string>
#include <vector>
using namespace std;
static const string SPITID = "#spit#";
namespace spit {
class Message {
//----------- Header -----------
public:
class Header {
public:
static constexpr int BYTESLENGTH = 99;
Header(const Header &orig);
Header();
private:
string mID;
int mVersion{SPITVERSION};
unsigned char mMessageNumber{};
int mBytesCount{BYTESLENGTH};
string mServerID{};
string mClientID{};
int mOpFlag{-1};
int mParseOffset{};
public:
string getSPITID() const { return mID; }
int getSPITVersion() const { return mVersion; }
unsigned char getMessageNumber() const { return mMessageNumber; }
int getBytesCount() const { return mBytesCount; }
string getServerID() const { return mServerID; }
string getClientID() const { return mClientID; }
int getType() const { return mOpFlag; }
// Receive
bool parse(const std::vector<char> &message);
// Send
Header(int p_SPITVersion, int pOpFlag);
void setMessageNumber(unsigned char p_MessageNumber) { mMessageNumber = p_MessageNumber; }
void setServerID(string p_ID) { mServerID = p_ID; }
void setClientID(string p_ID) { mClientID = p_ID; }
void setOPFlag(int pOpFlag) { mOpFlag = pOpFlag; }
bool fillBytes(std::vector<char> &message);
};
//----------- OPPart -----------
public:
class OPPart {
// Members
protected:
unique_ptr<Header> mHeader{};
int mParseOffset{};
int mBytesCount;
public:
virtual ~OPPart();
Header *getHeader() const { return mHeader.get(); }
int getBytesCount() const { return mBytesCount; }
void setServerInfoInHeader(string clientId, string serverId) {
if (!mHeader) {
return;
}
mHeader->setClientID(clientId);
mHeader->setServerID(serverId);
}
void setMessageNumber(uint8_t no) {
if (!mHeader) {
return;
}
mHeader->setMessageNumber(no);
}
const string getServerID() const {
if (!mHeader) {
return "";
}
return mHeader->getServerID();
}
const string getClientID() const {
if (!mHeader) {
return "";
}
return mHeader->getClientID();
}
int getType() const {
if (!mHeader) {
return -1;
}
return mHeader->getType();
}
// Receive
OPPart(unique_ptr<Header> p_Header, int pOpFlag, int size);
void setHeader(int opFlag);
virtual bool parse(const std::vector<char> &message) = 0;
// Send
OPPart(int size);
virtual bool fillBytes(std::vector<char> &message) = 0;
};
//----------- Message -----------
public:
static constexpr int SPITVERSION = 1;
// SPIT_Object value usage
static constexpr char VALUEUSE_DISCARD = 0x00; // value of SPITObejct is not used
static constexpr char VALUEUSE_INRANGE = 0x01; // value of SPITOBject in range 0 - 1000000ppm
static constexpr char VALUEUSE_OVERRIDE = 0x02; // value can be overridden
// SPIT Player type
static constexpr char PLAYERTYPE_MAIN = 0x02;
static constexpr char PLAYERTYPE_CONTINIOUS = 0x01;
static constexpr char PLAYERTYPE_DISCRETE = 0x00;
// PlayObject value usage
static constexpr char VALUEFLAG_DIRECT = 0x00; // use the vlue direct
static constexpr char VALUEFLAG_INCREASE = 0x01; // increase the value
static constexpr char VALUEFLAG_DECREASE = 0x02; // decrease the value
Message() = default;
// Members
private:
unique_ptr<OPPart> m_OPPart{};
// Receive
public:
Message(std::vector<char> message);
const Header *getHeader() const { return m_OPPart->getHeader(); }
int getType() const {
if (!m_OPPart || !m_OPPart->getHeader()) {
return -1;
}
return m_OPPart->getHeader()->getType();
}
const OPPart *getOPPart() const { return m_OPPart.get(); }
template<typename T>
T &getAs() const { return *reinterpret_cast<T *>(m_OPPart.get()); }
private:
bool parse(std::vector<char> message);
// Send
public:
static std::vector<char> createMessage(OPPart & p_OPPart);
//------------------------------ Connection ----------------------------------
//----------- Connect -----------
public:
class Connect : public OPPart {
public:
static constexpr int OPFLAG = 1;
static constexpr int BYTESLENGTH = 304;
private:
string m_ClientComputerName{};
string m_ClientName{};
string m_LoginName{};
string m_LoginPassword{};
string m_ServerIP{};
int m_ServerPort{};
public:
// Receive
Connect(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
string getClientComputerName() const { return m_ClientComputerName; }
string getClientName() const { return m_ClientName; }
string getLoginName() const { return m_LoginName; }
string getLoginPassword() const { return m_LoginPassword; }
string getServerIP() const { return m_ServerIP; }
int getServerPort() const { return m_ServerPort; }
// Send
Connect(string p_ComputerName, string p_ClientName);
void setLoginName(string p_LoginName) { m_LoginName = p_LoginName; }
void setLoginPassword(string p_LoginPassword) { m_LoginPassword = p_LoginPassword; }
void setServerIP(string p_ServerIP) { m_ServerIP = p_ServerIP; }
void setServerPort(int p_ServerPort);
bool fillBytes(std::vector<char> &message);
};
//----------- ConnectAnswer -----------
class ConnectAnswer : public OPPart {
public:
static constexpr int OPFLAG = 2;
static constexpr int BYTESLENGTH = 137;
private:
string m_ServerComputerName{};
string m_ServerName{};
bool m_Connected{};
int m_StepTime{40}; // ms step size the Server will send play sequences
public:
ConnectAnswer(const ConnectAnswer &orig);
// Receive
ConnectAnswer(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getServerComputerName() const { return m_ServerComputerName; }
const string getServerName() const { return m_ServerName; }
bool getConnected() const { return m_Connected; }
int getStepTime() const { return m_StepTime; }
// Send
ConnectAnswer();
void setServerComputerName(string p_ServerComputerName) { m_ServerComputerName = p_ServerComputerName; }
void setServerName(string p_ServerName) { m_ServerName = p_ServerName; }
void setConnected(bool p_Connected) { m_Connected = p_Connected; }
void setStepTime(int p_StepTime_ms);
bool fillBytes(std::vector<char> &message);
};
//----------- Disconnect -----------
class Disconnect : public OPPart {
public:
static constexpr int OPFLAG = 3;
static constexpr int BYTESLENGTH = 4;
Disconnect(const Disconnect &orig);
// Receive
Disconnect(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
Disconnect();
bool fillBytes(std::vector<char> &message);
};
//----------- Watchdog -----------
class Watchdog : public OPPart {
public:
static constexpr int OPFLAG = 8;
static constexpr int BYTESLENGTH = 4;
Watchdog(const Watchdog &orig);
// Receive
Watchdog(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
Watchdog();
bool fillBytes(std::vector<char> &message);
};
//----------- WatchdogAnswer -----------
class WatchdogAnswer : public OPPart {
public:
static constexpr int OPFLAG = 9;
static constexpr int BYTESLENGTH = 4;
// Receive
WatchdogAnswer(const WatchdogAnswer &orig);
WatchdogAnswer(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
WatchdogAnswer();
bool fillBytes(std::vector<char> &message);
};
//------------------------------ SPITProject ----------------------------------
//----------- ReportProject -----------
class ReportProject : public OPPart {
public:
static constexpr int OPFLAG = 11;
static constexpr int BYTESLENGTH = 113;
private:
string m_ProjectID{};
string m_ProjectName{};
int m_FramesPerSecond{1000}; // Frames per second
// Receive
public:
ReportProject(const ReportProject &orig);
ReportProject(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getProjectID() const { return m_ProjectID; }
const string getProjectName() const { return m_ProjectName; }
int getFramesPerSecond() const { return m_FramesPerSecond; }
// Send
ReportProject(string p_ProjectID, string p_ProjectName);
void setFramesPerSecond(const int p_FramesPerSecond) { m_FramesPerSecond = p_FramesPerSecond; }
bool fillBytes(std::vector<char> &message);
};
//----------- CloseProject -----------
class CloseProject : public OPPart {
public:
static constexpr int OPFLAG = 13;
static constexpr int BYTESLENGTH = 45;
private:
string m_ProjectID{};
public:
CloseProject(const CloseProject &orig);
// Receive
CloseProject(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getProjectID() const {
return m_ProjectID;
}
// Send
CloseProject(string projectID);
bool fillBytes(std::vector<char> &message);
};
//----------- StartProjectTransfer -----------
class RequestProjectTransfer : public OPPart {
public:
static constexpr int OPFLAG = 15;
static constexpr int BYTESLENGTH = 4;
RequestProjectTransfer(const RequestProjectTransfer &orig);
// Receive
RequestProjectTransfer(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
RequestProjectTransfer();
bool fillBytes(std::vector<char> &message);
};
//----------- StartProjectTransfer -----------
class StartProjectTransfer : public OPPart {
public:
static constexpr int OPFLAG = 16;
static constexpr int BYTESLENGTH = 4;
StartProjectTransfer(const StartProjectTransfer &orig);
// Receive
StartProjectTransfer(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
StartProjectTransfer();
bool fillBytes(std::vector<char> &message);
};
//----------- EndProjectTransfer -----------
class EndProjectTransfer : public OPPart {
public:
static constexpr int OPFLAG = 17;
static constexpr int BYTESLENGTH = 4;
EndProjectTransfer(const EndProjectTransfer &orig);
// Receive
EndProjectTransfer(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
// Send
EndProjectTransfer();
bool fillBytes(std::vector<char> &message);
};
//---------------------------- SPIT_Types ----------------------------------
//----------- ReportType -----------
class ReportType : public OPPart {
public:
static constexpr int OPFLAG = 21;
static constexpr int BYTESLENGTH = 168;
private:
bool m_Confirmed{};
string m_SPITTypeID{};
bool m_Fixed{};
bool m_ServerRemote{};
bool m_ServerProjectIndepended{};
string m_SPITTypeGroupName{};
string m_SPITTypeName{};
uint64_t m_Delay{};
uint64_t m_Duration{};
public:
ReportType(const ReportType &orig);
// Receive
ReportType(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
bool getConfirmed() const { return m_Confirmed; }
const string getID() const { return m_SPITTypeID; }
bool getFixed() const { return m_Fixed; }
bool getServerRemote() const { return m_ServerRemote; }
bool getServerProjectIndepended() const { return m_ServerProjectIndepended; }
const string getGroupName() const { return m_SPITTypeGroupName; }
const string getName() const { return m_SPITTypeName; }
uint64_t getDelay() const { return m_Delay; }
uint64_t getDuration() const { return m_Duration; }
// Send
ReportType();
void setConfirmed(bool p_Confirmed) { m_Confirmed = p_Confirmed; }
void setID(string p_ID) { m_SPITTypeID = p_ID; }
void setFixed(bool p_Fixed) { m_Fixed = p_Fixed; }
void setServerRemote(bool p_IsServerRemote) { m_ServerRemote = p_IsServerRemote; }
void setServerProjectIndepended(bool p_ProjectIndpended) { m_ServerProjectIndepended = p_ProjectIndpended; }
void setGroupName(string p_GroupName) { m_SPITTypeGroupName = p_GroupName; }
void setName(string p_Name) { m_SPITTypeName = p_Name; }
void setDelay(uint64_t p_Delay) { m_Delay = p_Delay; }
void setDuration(uint64_t p_Duration) { m_Duration = p_Duration; }
bool fillBytes(std::vector<char> &message);
};
//----------- RemoveType -----------
class RemoveType : public OPPart {
public:
static constexpr int OPFLAG = 23;
static constexpr int BYTESLENGTH = 45;
private:
string m_SPITTypeID{};
public:
RemoveType(const RemoveType &orig);
// Receive
RemoveType(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getID() const { return m_SPITTypeID; }
// Send
RemoveType();
void setID(string p_ID) { m_SPITTypeID = p_ID; }
bool fillBytes(std::vector<char> &message);
};
//---------------------------- SPITObjects ----------------------------------
//----------- ReportObject -----------
class ReportObject : public OPPart {
public:
static constexpr int OPFLAG = 31;
static constexpr int BYTESLENGTH = 339;
private:
bool m_Confirmed{};
string m_SPITObjectID{};
bool m_Fixed{};
bool m_ServerRemote{};
string m_SPITObjectName{};
string m_SPITTypeID{};
string m_ServerParams{};
uint64_t m_FrameStart{};
uint64_t m_FrameLength{};
uint64_t m_FrameFadeInLength{};
uint64_t m_FrameFadeOutLength{};
int m_ValueFactor{};
char m_ValueUse{VALUEUSE_DISCARD};
int m_Track{};
string m_Remark{};
uint64_t m_Delay{};
uint64_t m_Duration{};
bool m_ActionAssigned{};
public:
ReportObject(const ReportObject &orig);
// Receive
ReportObject(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
bool getConfirmed() const { return m_Confirmed; }
const string getID() const { return m_SPITObjectID; }
bool getFixed() const { return m_Fixed; }
bool getServerRemote() const { return m_ServerRemote; }
const string getName() const { return m_SPITObjectName; }
const string getSPITTypeID() const { return m_SPITTypeID; }
const string getServerParams() const { return m_ServerParams; }
uint64_t getFrameStart() const { return m_FrameStart; }
uint64_t getFrameLength() const { return m_FrameLength; }
uint64_t getFrameFadeInLength() const { return m_FrameFadeInLength; }
uint64_t getFrameFadeOutLength() const { return m_FrameFadeOutLength; }
int getValueFactor() const { return m_ValueFactor; }
char getValueUse() const { return m_ValueUse; }
int getTrack() const { return m_Track; }
const string getRemark() const { return m_Remark; }
uint64_t getDelay() const { return m_Delay; }
uint64_t getDuration() const { return m_Duration; }
bool getActionAssigned() const { return m_ActionAssigned; }
// Send
public:
ReportObject();
void setConfirmed(bool p_Confirmed) { m_Confirmed = p_Confirmed; };
void setID(string p_ID) { m_SPITObjectID = p_ID; };
void setFixed(bool p_Fixed) { m_Fixed = p_Fixed; };
void setServerRemote(bool p_IsRemote) { m_ServerRemote = p_IsRemote; };
void setName(string p_Name) { m_SPITObjectName = p_Name; };
void setSPITTypeID(string p_ID) { m_SPITTypeID = p_ID; };
void setServerParams(string p_Parameters) { m_ServerParams = p_Parameters; };
void setFrameStart(uint64_t p_StartTime) { m_FrameStart = p_StartTime; };
void setFrameLength(uint64_t p_Length) { m_FrameLength = p_Length; };
void setFrameFadeInLength(uint64_t p_FadeInTime) { m_FrameFadeInLength = p_FadeInTime; };
void setFrameFadeOutLength(uint64_t p_FadeOutTime) { m_FrameFadeOutLength = p_FadeOutTime; };
void setValueFactor(int p_Volume) { m_ValueFactor = p_Volume; };
void setValueUse(char p_ValueUse) { m_ValueUse = p_ValueUse; };
void setTrack(int p_Track) { m_Track = p_Track; };
void setRemark(string p_Description) { m_Remark = p_Description; };
void setDelay(uint64_t p_Delay);
void setDuration(uint64_t p_Duration);
void setActionAssigned(bool p_ActionAssigned) { m_ActionAssigned = p_ActionAssigned; }
bool fillBytes(std::vector<char> &message);
};
//----------- RemoveObject -----------
class RemoveObject : public OPPart {
public:
static constexpr int OPFLAG = 33;
static constexpr int BYTESLENGTH = 45;
private:
string m_SPITObjectID{};
public:
RemoveObject(const RemoveObject &orig);
// Receive
RemoveObject(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getID() const { return m_SPITObjectID; }
// Send
public:
RemoveObject();
void setID(string p_ID) { m_SPITObjectID = p_ID; }
bool fillBytes(std::vector<char> &message);
};
//---------------------------- SPITPlayer ----------------------------------
//----------- PlayStart -----------
class PlayStart : public OPPart {
public:
static constexpr int OPFLAG = 37;
static constexpr int BYTESLENGTH = 119;
private:
string m_PlayerID{};
string m_PlayerName{};
char m_PlayerType{};
bool m_PlayerIsRunning{};
uint64_t m_Time; // Frames
public:
PlayStart(const PlayStart &orig);
// Receive
PlayStart(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getPlayerID() const { return m_PlayerID; }
const string getPlayerName() const { return m_PlayerName; }
char getPlayerType() const { return m_PlayerType; }
bool getPlayerIsRunning() const { return m_PlayerIsRunning; }
uint64_t getTime() const { return m_Time; }
// Send
PlayStart(string p_PlayerID, string p_PlayerName, char p_PlayerType);
void setPlayerIsRunning(bool p_IsPlaying) { m_PlayerIsRunning = p_IsPlaying; }
void setTime(uint64_t p_Time) { m_Time = p_Time; }
bool fillBytes(std::vector<char> &message);
};
//----------- PlayObject -----------
class PlayObject : public OPPart {
public:
static constexpr int OPFLAG = 38;
static constexpr int BYTESLENGTH = 100;
private:
string m_PlayerID{};
string m_SPITObjectID{};
uint64_t m_FrameInsideObject{}; // Frames
bool m_PlayPrePosition{};
int m_Value{};
char m_ValueFlag{VALUEFLAG_DIRECT};
public:
PlayObject(const PlayObject &orig);
// Receive
PlayObject(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getPlayerID() const { return m_PlayerID; }
const string getSPITObjectID() const { return m_SPITObjectID; }
uint64_t getFrameInsideObject() const { return m_FrameInsideObject; }
bool getPlayPrePosition() const { return m_PlayPrePosition; }
int getValue() const { return m_Value; }
char getValueFlag() const { return m_ValueFlag; }
// Send
PlayObject();
void setPlayerID(string p_PlayerID) { m_PlayerID = p_PlayerID; }
void setID(string p_ID) { m_SPITObjectID = p_ID; }
void setFrameInsideObject(uint64_t p_TimeInside) { m_FrameInsideObject = p_TimeInside; }
void setPlayPrePosition(bool p_PlayOldPosition) { m_PlayPrePosition = p_PlayOldPosition; }
void setValue(int p_Value) { m_Value = p_Value; }
void setValueFlag(char p_ValueFlag) { m_ValueFlag = p_ValueFlag; }
bool fillBytes(std::vector<char> &message);
};
//----------- PlayEnd -----------
class PlayEnd : public OPPart {
public:
static constexpr int OPFLAG = 39;
static constexpr int BYTESLENGTH = 45;
private:
string m_PlayerID{};
public:
PlayEnd(const PlayEnd &orig);
// Receive
PlayEnd(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getPlayerID() const { return m_PlayerID; }
// Send
PlayEnd(string p_PlayerID);
bool fillBytes(std::vector<char> &message);
};
//----------- ReportPlayStatus -----------
class ReportPlayStatus : public OPPart {
public:
static constexpr int OPFLAG = 40;
static constexpr int BYTESLENGTH = 57;
private:
string m_SPITObjectID{};
uint64_t m_FrameInsideObject{};
int m_Value{};
public:
ReportPlayStatus(const ReportPlayStatus &orig);
// Receive
ReportPlayStatus(unique_ptr<Header> p_Header);
bool parse(const std::vector<char> &message);
const string getID() const { return m_SPITObjectID; }
uint64_t getFrameInsideObject() const { return m_FrameInsideObject; }
int getValue() const { return m_Value; }
// Send
ReportPlayStatus();
void setID(string p_ID);
void setFrameInsideObject(uint64_t p_TimeInside);
void setValue(int p_Value);
bool fillBytes(std::vector<char> &message);
};
//----------------------- static helper functions ----------------------------
public:
static bool isSystemLittleEndian();
static optional<int> getInt(const std::vector<char> &message, int &offset);
static optional<uint64_t> getLong(const std::vector<char> &message, int &offset);
static optional<bool> getBoolean(const std::vector<char> &message, int &offset);
static optional<char> getByte(const std::vector<char> &message, int &offset);
static int setInt(int value, std::vector<char> &message, int offset);
static int setLong(uint64_t value, std::vector<char> &message, int offset);
static int setBoolean(bool value, std::vector<char> &message, int offset);
static int setByte(int value, std::vector<char> &message, int offset);
/**
* Returns the string char* of the part of the byte sequence (0x00 null terminated).
* @param p_Bytes the byte array
* @param offset the startposition of strings bytes
* @param p_Length the length of the string included the null terminate byte (0x00).
* The length of the string will be p_Length -1.
*/
static optional<string> getString(const std::vector<char> &message, int &offset, int maxLength);
/**
* Fill the p_String in the byte array.
* If p_String length is greater than p_Length -1, the p_String will be truncated.
* CAUTION the return value should be freed after use.
* @param p_String the string
* @param p_Length the maximal length of the string included the null character.
* @throws Exception if p_String == nullptr, p_Bytes == nullptr
* p_Offset less than 0
* p_ByteCount less than p_Offset + p_Length
* @return p_Length
*/
static int setString(string p_String, std::vector<char> &message, int p_Offset, int p_Length);
};
}