1334 lines
43 KiB
C++
1334 lines
43 KiB
C++
|
|
#include "spit_message.hpp"
|
|
|
|
#include "esp_log.h"
|
|
#include <cstring>
|
|
|
|
const char *TAG = "SpitMsg";
|
|
|
|
namespace spit {
|
|
|
|
//---------- Receive ---------
|
|
Message::Message(std::vector<char> message) {
|
|
if (message.empty()) {
|
|
ESP_LOGE(TAG, "message is emtpy, nothing to parse");
|
|
return;
|
|
}
|
|
if (!parse(message)) {
|
|
ESP_LOGE(TAG, "Failed ot parse message");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Receive
|
|
|
|
bool Message::parse(std::vector<char> message) {
|
|
// parse Header
|
|
auto header = make_unique<Header>();
|
|
if (!header->parse(message)) {
|
|
return false;
|
|
}
|
|
|
|
// parse OP
|
|
switch (header->getType()) {
|
|
case Message::Connect::OPFLAG: { // Connection
|
|
oPPart = make_unique<Connect>(move(header));
|
|
} break;
|
|
case Message::ConnectAnswer::OPFLAG: {
|
|
oPPart = make_unique<ConnectAnswer>(move(header));
|
|
} break;
|
|
case Disconnect::OPFLAG: {
|
|
oPPart = make_unique<Disconnect>(move(header));
|
|
} break;
|
|
case Watchdog::OPFLAG: {
|
|
oPPart = make_unique<Watchdog>(move(header));
|
|
} break;
|
|
case WatchdogAnswer::OPFLAG: {
|
|
oPPart = make_unique<WatchdogAnswer>(move(header));
|
|
} break;
|
|
case ReportProject::OPFLAG: { // SpitProject
|
|
oPPart = make_unique<ReportProject>(move(header));
|
|
} break;
|
|
case CloseProject::OPFLAG: {
|
|
oPPart = make_unique<CloseProject>(move(header));
|
|
} break;
|
|
case RequestProjectTransfer::OPFLAG: {
|
|
oPPart = make_unique<RequestProjectTransfer>(move(header));
|
|
} break;
|
|
case StartProjectTransfer::OPFLAG: {
|
|
oPPart = make_unique<StartProjectTransfer>(move(header));
|
|
} break;
|
|
case EndProjectTransfer::OPFLAG: {
|
|
oPPart = make_unique<EndProjectTransfer>(move(header));
|
|
} break;
|
|
case ReportType::OPFLAG: { // SpitType
|
|
oPPart = make_unique<ReportType>(move(header));
|
|
} break;
|
|
case RemoveType::OPFLAG: {
|
|
oPPart = make_unique<RemoveType>(move(header));
|
|
} break;
|
|
case ReportObject::OPFLAG: { // SpitObject
|
|
oPPart = make_unique<ReportObject>(move(header));
|
|
} break;
|
|
case RemoveObject::OPFLAG: {
|
|
oPPart = make_unique<RemoveObject>(move(header));
|
|
} break;
|
|
case PlayStart::OPFLAG: { // PlaySpitObjects
|
|
oPPart = make_unique<PlayStart>(move(header));
|
|
} break;
|
|
case PlayObject::OPFLAG: {
|
|
oPPart = make_unique<PlayObject>(move(header));
|
|
} break;
|
|
case PlayEnd::OPFLAG: {
|
|
oPPart = make_unique<PlayEnd>(move(header));
|
|
} break;
|
|
case ReportPlayStatus::OPFLAG: {
|
|
oPPart = make_unique<ReportPlayStatus>(move(header));
|
|
} break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return oPPart->parse(message);
|
|
}
|
|
|
|
//---------- Send ----------
|
|
std::vector<char> Message::createMessage(OPPart &oPPart) {
|
|
if (!oPPart.getHeader()) {
|
|
return {};
|
|
}
|
|
|
|
try {
|
|
int totalSize = Header::BYTESLENGTH + oPPart.getBytesCount();
|
|
std::vector<char> msgByts(totalSize);
|
|
oPPart.fillBytes(msgByts);
|
|
return msgByts;
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "Failed to allocate memory");
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//----------- Header -----------
|
|
Message::Header::Header(const Header &orig) {
|
|
mID = &SPITID[0];
|
|
mMessageNumber = orig.getMessageNumber();
|
|
mServerId = orig.getServerID();
|
|
mClientId = orig.getClientID();
|
|
}
|
|
|
|
Message::Header::Header() {
|
|
mID = &SPITID[0];
|
|
}
|
|
|
|
bool Message::Header::parse(const std::vector<char> &message) {
|
|
try {
|
|
mParseOffset = 0;
|
|
auto strID = getString(message, mParseOffset, 7).value();
|
|
if (strID != SPITID) {
|
|
return false;
|
|
}
|
|
auto iVer = getInt(message, mParseOffset).value();
|
|
if (iVer < 0) {
|
|
return false;
|
|
}
|
|
mMessageNumber = getByte(message, mParseOffset).value();
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
if (mBytesCount < 0) {
|
|
return false;
|
|
}
|
|
mServerId = getString(message, mParseOffset, 41).value();
|
|
mClientId = getString(message, mParseOffset, 41).value();
|
|
mOpFlag = message[mParseOffset++] & 0xFF;
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse Header");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::Header::Header(int p_SPITVersion, int p_OPFlag) {
|
|
mID = &SPITID[0];
|
|
mVersion = p_SPITVersion;
|
|
mOpFlag = p_OPFlag;
|
|
}
|
|
|
|
bool Message::Header::fillBytes(std::vector<char> &message) {
|
|
try {
|
|
mParseOffset = 0;
|
|
mParseOffset += setString(mID, message, mParseOffset, 7);
|
|
mParseOffset += setInt(SPITVERSION, message, mParseOffset);
|
|
mParseOffset += setByte(mMessageNumber, message, mParseOffset);
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mServerId, message, mParseOffset, 41);
|
|
mParseOffset += setString(mClientId, message, mParseOffset, 41);
|
|
mParseOffset += setByte(mOpFlag, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create Header");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- OPPart -----------
|
|
|
|
Message::OPPart::~OPPart() {
|
|
}
|
|
|
|
// Receive
|
|
Message::OPPart::OPPart(unique_ptr<Header> p_Header, int p_OPFlag, int size)
|
|
: mHeader(move(p_Header)),
|
|
mBytesCount(size) {
|
|
if (!mHeader) {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mHeader->setOPFlag(p_OPFlag);
|
|
}
|
|
}
|
|
void Message::OPPart::setHeader(int opFlag) {
|
|
mHeader = make_unique<Header>(SPITVERSION, opFlag);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
// Send
|
|
Message::OPPart::OPPart(int size)
|
|
: mBytesCount(size) {}
|
|
|
|
//--------------------------- Connection --------------------------------
|
|
//----------- Connect -----------
|
|
// Receive
|
|
Message::Connect::Connect(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
|
|
bool Message::Connect::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mClientComputerName = getString(message, mParseOffset, 64).value();
|
|
mClientName = getString(message, mParseOffset, 64).value();
|
|
mLoginName = getString(message, mParseOffset, 64).value();
|
|
mLoginPassword = getString(message, mParseOffset, 64).value();
|
|
mServerIp = getString(message, mParseOffset, 40).value();
|
|
mServerPort = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse Connect message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::Connect::Connect(string pComputerName, string pClientName)
|
|
: OPPart(BYTESLENGTH),
|
|
mClientComputerName(pComputerName),
|
|
mClientName(pClientName) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
void Message::Connect::setServerPort(int p_ServerPort) {
|
|
if (p_ServerPort < 0 || p_ServerPort > 65535)
|
|
p_ServerPort = 0;
|
|
mServerPort = p_ServerPort;
|
|
}
|
|
bool Message::Connect::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mClientComputerName, message, mParseOffset, 64);
|
|
mParseOffset += setString(mClientName, message, mParseOffset, 64);
|
|
mParseOffset += setString(mLoginName, message, mParseOffset, 64);
|
|
mParseOffset += setString(mLoginPassword, message, mParseOffset, 64);
|
|
mParseOffset += setString(mServerIp, message, mParseOffset, 40);
|
|
mParseOffset += setInt(mServerPort, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create Connect message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- ConnectAnswer -----------
|
|
|
|
// Receive
|
|
Message::ConnectAnswer::ConnectAnswer(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {}
|
|
bool Message::ConnectAnswer::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mServerComputerName = getString(message, mParseOffset, 64).value();
|
|
mServerName = getString(message, mParseOffset, 64).value();
|
|
mStepTime = getInt(message, mParseOffset).value();
|
|
mConnected = getBoolean(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse ConnectAnswer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::ConnectAnswer::ConnectAnswer()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
void Message::ConnectAnswer::setStepTime(int p_StepTime_ms) {
|
|
if (p_StepTime_ms < 0)
|
|
p_StepTime_ms = 1;
|
|
mStepTime = p_StepTime_ms;
|
|
}
|
|
bool Message::ConnectAnswer::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mServerComputerName, message, mParseOffset, 64);
|
|
mParseOffset += setString(mServerName, message, mParseOffset, 64);
|
|
mParseOffset += setInt(mStepTime, message, mParseOffset);
|
|
mParseOffset += setBoolean(mConnected, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create ConnectAnswer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- Disconnect -----------
|
|
|
|
// Receive
|
|
Message::Disconnect::Disconnect(unique_ptr<Header> p_Header) : OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::Disconnect::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse Disconnect message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::Disconnect::Disconnect()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
}
|
|
|
|
bool Message::Disconnect::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create Disconnect message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- Watchdog -----------
|
|
// Receive
|
|
Message::Watchdog::Watchdog(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::Watchdog::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse Watchdog message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::Watchdog::Watchdog() : OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
bool Message::Watchdog::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create Watchdog message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- WatchdogAnswer -----------
|
|
|
|
// Receive
|
|
Message::WatchdogAnswer::WatchdogAnswer(unique_ptr<Header> p_Header) : OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::WatchdogAnswer::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse WatchdogAnswer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::WatchdogAnswer::WatchdogAnswer() : OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
bool Message::WatchdogAnswer::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create WatchdogAnswer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//--------------------------- SPITProject --------------------------------
|
|
|
|
//----------- ReportProject -----------
|
|
// Receive
|
|
Message::ReportProject::ReportProject(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::ReportProject::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mProjectID = getString(message, mParseOffset, 41).value();
|
|
mProjectName = getString(message, mParseOffset, 64).value();
|
|
mFramesPerSecond = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse ReportProject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::ReportProject::ReportProject(string p_ProjectID, string p_ProjectName)
|
|
: OPPart(BYTESLENGTH),
|
|
mProjectID(p_ProjectID),
|
|
mProjectName(p_ProjectName) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::ReportProject::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mProjectID, message, mParseOffset, 41);
|
|
mParseOffset += setString(mProjectName, message, mParseOffset, 64);
|
|
mParseOffset += setInt(mFramesPerSecond, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create ReportProject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- StartProjectTransfer -----------
|
|
|
|
// Receive
|
|
Message::CloseProject::CloseProject(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::CloseProject::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mProjectID = getString(message, mParseOffset, 41).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse CloseProject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::CloseProject::CloseProject(string projectID)
|
|
: OPPart(BYTESLENGTH),
|
|
mProjectID(projectID) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::CloseProject::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mProjectID, message, mParseOffset, 41);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create CloseProject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- RequestProjectTransfer -----------
|
|
|
|
// Receive
|
|
Message::RequestProjectTransfer::RequestProjectTransfer(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::RequestProjectTransfer::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse RequestProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::RequestProjectTransfer::RequestProjectTransfer()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
bool Message::RequestProjectTransfer::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create RequestProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- StartProjectTransfer -----------
|
|
|
|
// Receive
|
|
Message::StartProjectTransfer::StartProjectTransfer(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::StartProjectTransfer::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse StartProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::StartProjectTransfer::StartProjectTransfer()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::StartProjectTransfer::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create StartProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- ENdProjectTransfer -----------
|
|
|
|
// Receive
|
|
Message::EndProjectTransfer::EndProjectTransfer(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::EndProjectTransfer::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse EndProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::EndProjectTransfer::EndProjectTransfer()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
bool Message::EndProjectTransfer::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create EndProjectTransfer message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//--------------------------- SPITType ---------------------------------
|
|
|
|
//----------- ReportType -----------
|
|
|
|
// Receive
|
|
Message::ReportType::ReportType(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::ReportType::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mConfirmed = getBoolean(message, mParseOffset).value();
|
|
mSPITTypeID = getString(message, mParseOffset, 41).value();
|
|
mFixed = getBoolean(message, mParseOffset).value();
|
|
mServerRemote = getBoolean(message, mParseOffset).value();
|
|
mServerProjectIndepended = getBoolean(message, mParseOffset).value();
|
|
mTypeGroupName = getString(message, mParseOffset, 39).value();
|
|
mSPITTypeName = getString(message, mParseOffset, 64).value();
|
|
mDelay = getLong(message, mParseOffset).value();
|
|
mDuration = getLong(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse ReportType message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::ReportType::ReportType()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::ReportType::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = mHeader->BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setBoolean(mConfirmed, message, mParseOffset);
|
|
mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
|
|
mParseOffset += setBoolean(mFixed, message, mParseOffset);
|
|
mParseOffset += setBoolean(mServerRemote, message, mParseOffset);
|
|
mParseOffset += setBoolean(mServerProjectIndepended, message, mParseOffset);
|
|
mParseOffset += setString(mTypeGroupName, message, mParseOffset, 39);
|
|
mParseOffset += setString(mSPITTypeName, message, mParseOffset, 64);
|
|
mParseOffset += setLong(mDelay, message, mParseOffset);
|
|
mParseOffset += setLong(mDuration, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create ReportType message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- ReportType -----------
|
|
|
|
// Receive
|
|
Message::RemoveType::RemoveType(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::RemoveType::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mSPITTypeID = getString(message, mParseOffset, 41).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse RemoveType message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::RemoveType::RemoveType()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::RemoveType::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create RemoveType message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//---------------------------- SPITObjects ----------------------------------
|
|
|
|
//----------- ReportObject -----------
|
|
// Receive
|
|
Message::ReportObject::ReportObject(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::ReportObject::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mConfirmed = getBoolean(message, mParseOffset).value();
|
|
mSPITObjectID = getString(message, mParseOffset, 41).value();
|
|
mFixed = getBoolean(message, mParseOffset).value();
|
|
mServerRemote = getBoolean(message, mParseOffset).value();
|
|
mSPITObjectName = getString(message, mParseOffset, 64).value();
|
|
mSPITTypeID = getString(message, mParseOffset, 41).value();
|
|
mServerParams = getString(message, mParseOffset, 64).value();
|
|
mFrameStart = getLong(message, mParseOffset).value();
|
|
mFrameLength = getLong(message, mParseOffset).value();
|
|
mFrameFadeInLength = getLong(message, mParseOffset).value();
|
|
mFrameFadeOutLength = getLong(message, mParseOffset).value();
|
|
mValueFactor = getInt(message, mParseOffset).value();
|
|
mValueUse = getByte(message, mParseOffset).value();
|
|
mTrack = getInt(message, mParseOffset).value();
|
|
mRemark = getString(message, mParseOffset, 64).value();
|
|
mDelay = getLong(message, mParseOffset).value();
|
|
mDuration = getLong(message, mParseOffset).value();
|
|
mActionAssigned = getBoolean(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse ReportObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::ReportObject::ReportObject() : OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
void Message::ReportObject::setDelay(uint64_t p_Delay) {
|
|
if (p_Delay < 0)
|
|
p_Delay = 0;
|
|
mDelay = p_Delay;
|
|
}
|
|
void Message::ReportObject::setDuration(uint64_t p_Duration) {
|
|
if (p_Duration < 0)
|
|
p_Duration = 0;
|
|
mDuration = p_Duration;
|
|
}
|
|
|
|
bool Message::ReportObject::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setBoolean(mConfirmed, message, mParseOffset);
|
|
mParseOffset += setString(mSPITObjectID, message, mParseOffset, 41);
|
|
mParseOffset += setBoolean(mFixed, message, mParseOffset);
|
|
mParseOffset += setBoolean(mServerRemote, message, mParseOffset);
|
|
mParseOffset += setString(mSPITObjectName, message, mParseOffset, 64);
|
|
mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
|
|
mParseOffset += setString(mServerParams, message, mParseOffset, 64);
|
|
mParseOffset += setLong(mFrameStart, message, mParseOffset);
|
|
mParseOffset += setLong(mFrameLength, message, mParseOffset);
|
|
mParseOffset += setLong(mFrameFadeInLength, message, mParseOffset);
|
|
mParseOffset += setLong(mFrameFadeOutLength, message, mParseOffset);
|
|
mParseOffset += setInt(mValueFactor, message, mParseOffset);
|
|
mParseOffset += setByte(mValueUse, message, mParseOffset);
|
|
mParseOffset += setInt(mTrack, message, mParseOffset);
|
|
mParseOffset += setString(mRemark, message, mParseOffset, 64);
|
|
mParseOffset += setLong(mDelay, message, mParseOffset);
|
|
mParseOffset += setLong(mDuration, message, mParseOffset);
|
|
mParseOffset += setBoolean(mActionAssigned, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create ReportObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- RemoveObject -----------
|
|
// Receive
|
|
Message::RemoveObject::RemoveObject(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::RemoveObject::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mSPITObjectID = getString(message, mParseOffset, 41).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse RemoveObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::RemoveObject::RemoveObject() : OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::RemoveObject::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mSPITObjectID, message, mParseOffset, 41);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create RemoveObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//---------------------------- SPITPlayer ----------------------------------
|
|
|
|
//----------- PlayStart -----------
|
|
// Receive
|
|
Message::PlayStart::PlayStart(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::PlayStart::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mPlayerID = getString(message, mParseOffset, 41).value();
|
|
mPlayerName = getString(message, mParseOffset, 64).value();
|
|
mPlayerType = getByte(message, mParseOffset).value();
|
|
mPlayerIsRunning = getBoolean(message, mParseOffset).value();
|
|
mTime = getLong(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse PlayStart message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Send
|
|
Message::PlayStart::PlayStart(string p_PlayerID, string p_PlayerName, char p_PlayerType)
|
|
: OPPart(BYTESLENGTH),
|
|
mPlayerID(p_PlayerID),
|
|
mPlayerName(p_PlayerName),
|
|
mPlayerType(p_PlayerType) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::PlayStart::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mPlayerID, message, mParseOffset, 41);
|
|
mParseOffset += setString(mPlayerName, message, mParseOffset, 64);
|
|
mParseOffset += setByte(mPlayerType, message, mParseOffset);
|
|
mParseOffset += setBoolean(mPlayerIsRunning, message, mParseOffset);
|
|
mParseOffset += setLong(mTime, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create PlayStart message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- PlayObject -----------
|
|
|
|
// Receive
|
|
Message::PlayObject::PlayObject(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::PlayObject::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mPlayerID = getString(message, mParseOffset, 41).value();
|
|
mSPITObjectID = getString(message, mParseOffset, 41).value();
|
|
mFrameInsideObject = getLong(message, mParseOffset).value();
|
|
mPlayPrePosition = getBoolean(message, mParseOffset).value();
|
|
mValue = getInt(message, mParseOffset).value();
|
|
mValueFlag = getByte(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse PlayObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::PlayObject::PlayObject()
|
|
: OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
bool Message::PlayObject::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mPlayerID, message, mParseOffset, 41);
|
|
mParseOffset += setString(mSPITObjectID, message, mParseOffset, 41);
|
|
mParseOffset += setLong(mFrameInsideObject, message, mParseOffset);
|
|
mParseOffset += setBoolean(mPlayPrePosition, message, mParseOffset);
|
|
mParseOffset += setInt(mValue, message, mParseOffset);
|
|
mParseOffset += setByte(mValueFlag, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create PlayObject message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- PlayEnd -----------
|
|
|
|
// Receive
|
|
Message::PlayEnd::PlayEnd(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::PlayEnd::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mPlayerID = getString(message, mParseOffset, 41).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse PlayEnd message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::PlayEnd::PlayEnd(string p_PlayerID)
|
|
: OPPart(BYTESLENGTH),
|
|
mPlayerID(p_PlayerID) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
bool Message::PlayEnd::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mPlayerID, message, mParseOffset, 41);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create PlayEnd message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------- ReportPlayStatus -----------
|
|
|
|
// Receive
|
|
Message::ReportPlayStatus::ReportPlayStatus(unique_ptr<Header> p_Header)
|
|
: OPPart(move(p_Header), OPFLAG, BYTESLENGTH) {
|
|
}
|
|
bool Message::ReportPlayStatus::parse(const std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
int intOPFlag = mHeader->getType();
|
|
if (intOPFlag != OPFLAG)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mBytesCount = getInt(message, mParseOffset).value();
|
|
mSPITObjectID = getString(message, mParseOffset, 41).value();
|
|
mFrameInsideObject = getLong(message, mParseOffset).value();
|
|
mValue = getInt(message, mParseOffset).value();
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to parse ReportPlayStatus message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Send
|
|
Message::ReportPlayStatus::ReportPlayStatus() : OPPart(BYTESLENGTH) {
|
|
setHeader(OPFLAG);
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
}
|
|
|
|
void Message::ReportPlayStatus::setID(string p_ID) {
|
|
mSPITObjectID = p_ID;
|
|
}
|
|
void Message::ReportPlayStatus::setFrameInsideObject(uint64_t p_TimeInside) {
|
|
mFrameInsideObject = p_TimeInside;
|
|
}
|
|
void Message::ReportPlayStatus::setValue(int p_Value) {
|
|
mValue = p_Value;
|
|
}
|
|
bool Message::ReportPlayStatus::fillBytes(std::vector<char> &message) {
|
|
if (!mHeader) {
|
|
return false;
|
|
}
|
|
if (mHeader->fillBytes(message) == false)
|
|
return false;
|
|
try {
|
|
mParseOffset = Header::BYTESLENGTH;
|
|
mParseOffset += setInt(mBytesCount, message, mParseOffset);
|
|
mParseOffset += setString(mSPITObjectID, message, mParseOffset, 41);
|
|
mParseOffset += setLong(mFrameInsideObject, message, mParseOffset);
|
|
mParseOffset += setInt(mValue, message, mParseOffset);
|
|
} catch (...) {
|
|
ESP_LOGE(TAG, "failed to create ReportPlayStatus message");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//---------------------------- static helper functions -----------------------
|
|
bool Message::isSystemLittleEndian() {
|
|
// todo replace with #include <bit> then if constexpr (std::endian::native == std::endian::big)
|
|
int intOne = 1;
|
|
char *firstByte;
|
|
firstByte = (char *)&intOne;
|
|
if (*firstByte > 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
optional<int> Message::getInt(const std::vector<char> &message, int &offset) {
|
|
if (offset < 0 || offset + 4 > message.size())
|
|
return std::nullopt;
|
|
// low byte first
|
|
int intValue = 0;
|
|
if (isSystemLittleEndian() == false) {
|
|
intValue += ((message[offset + 0] & 0x000000ff));
|
|
intValue += ((message[offset + 1] & 0x000000ff) << 8);
|
|
intValue += ((message[offset + 2] & 0x000000ff) << 16);
|
|
intValue += ((message[offset + 3] & 0x000000ff) << 24);
|
|
} else {
|
|
intValue += ((message[offset + 3] & 0x000000ff));
|
|
intValue += ((message[offset + 2] & 0x000000ff) << 8);
|
|
intValue += ((message[offset + 1] & 0x000000ff) << 16);
|
|
intValue += ((message[offset + 0] & 0x000000ff) << 24);
|
|
}
|
|
offset += 4;
|
|
return intValue;
|
|
}
|
|
|
|
int Message::setInt(int p_Value, std::vector<char> &message, int p_Offset) {
|
|
if ((p_Offset < 0) || (message.size() < p_Offset + 4))
|
|
throw "ParseError_send";
|
|
|
|
// low byte first
|
|
if (isSystemLittleEndian() == false) {
|
|
message[p_Offset + 0] = (char)(p_Value & 0x000000ff);
|
|
message[p_Offset + 1] = (char)((p_Value & 0x0000ff00) >> 8);
|
|
message[p_Offset + 2] = (char)((p_Value & 0x00ff0000) >> 16);
|
|
message[p_Offset + 3] = (char)((p_Value & 0xff000000) >> 24);
|
|
} else {
|
|
message[p_Offset + 3] = (char)(p_Value & 0x000000ff);
|
|
message[p_Offset + 2] = (char)((p_Value & 0x0000ff00) >> 8);
|
|
message[p_Offset + 1] = (char)((p_Value & 0x00ff0000) >> 16);
|
|
message[p_Offset + 0] = (char)((p_Value & 0xff000000) >> 24);
|
|
}
|
|
return 4;
|
|
}
|
|
|
|
optional<uint64_t> Message::getLong(const std::vector<char> &message, int &offset) {
|
|
if (offset < 0 || offset + 8 > message.size())
|
|
return std::nullopt;
|
|
|
|
// low byte first
|
|
uint64_t intValue = 0;
|
|
if (isSystemLittleEndian() == false) {
|
|
intValue += ((uint64_t)(message[offset] & 0x000000ff));
|
|
intValue += ((uint64_t)(message[offset + 1] & 0x000000ff) << 8);
|
|
intValue += ((uint64_t)(message[offset + 2] & 0x000000ff) << 16);
|
|
intValue += ((uint64_t)(message[offset + 3] & 0x000000ff) << 24);
|
|
intValue += ((uint64_t)(message[offset + 4] & 0x000000ff) << 32);
|
|
intValue += ((uint64_t)(message[offset + 5] & 0x000000ff) << 40);
|
|
intValue += ((uint64_t)(message[offset + 6] & 0x000000ff) << 48);
|
|
intValue += ((uint64_t)(message[offset + 7] & 0x000000ff) << 56);
|
|
} else {
|
|
intValue += ((uint64_t)(message[offset + 7] & 0x000000ff));
|
|
intValue += ((uint64_t)(message[offset + 6] & 0x000000ff) << 8);
|
|
intValue += ((uint64_t)(message[offset + 5] & 0x000000ff) << 16);
|
|
intValue += ((uint64_t)(message[offset + 4] & 0x000000ff) << 24);
|
|
intValue += ((uint64_t)(message[offset + 3] & 0x000000ff) << 32);
|
|
intValue += ((uint64_t)(message[offset + 2] & 0x000000ff) << 40);
|
|
intValue += ((uint64_t)(message[offset + 1] & 0x000000ff) << 48);
|
|
intValue += ((uint64_t)(message[offset + 0] & 0x000000ff) << 56);
|
|
}
|
|
offset += 8;
|
|
return intValue;
|
|
}
|
|
|
|
int Message::setLong(uint64_t p_Value, std::vector<char> &message, int p_Offset) {
|
|
if ((p_Offset < 0) || (message.size() < p_Offset + 8))
|
|
throw "ParseError_send";
|
|
// low byte first
|
|
if (isSystemLittleEndian() == false) {
|
|
message[p_Offset + 0] = (char)((p_Value & 0x00000000000000ff));
|
|
message[p_Offset + 1] = (char)((p_Value & 0x000000000000ff00) >> 8);
|
|
message[p_Offset + 2] = (char)((p_Value & 0x0000000000ff0000) >> 16);
|
|
message[p_Offset + 3] = (char)((p_Value & 0x00000000ff000000) >> 24);
|
|
message[p_Offset + 4] = (char)((p_Value & 0x000000ff00000000) >> 32);
|
|
message[p_Offset + 5] = (char)((p_Value & 0x0000ff0000000000) >> 40);
|
|
message[p_Offset + 6] = (char)((p_Value & 0x00ff000000000000) >> 48);
|
|
message[p_Offset + 7] = (char)((p_Value & 0xff00000000000000) >> 56);
|
|
} else {
|
|
message[p_Offset + 7] = (char)((p_Value & 0x00000000000000ff));
|
|
message[p_Offset + 6] = (char)((p_Value & 0x000000000000ff00) >> 8);
|
|
message[p_Offset + 5] = (char)((p_Value & 0x0000000000ff0000) >> 16);
|
|
message[p_Offset + 4] = (char)((p_Value & 0x00000000ff000000) >> 24);
|
|
message[p_Offset + 3] = (char)((p_Value & 0x000000ff00000000) >> 32);
|
|
message[p_Offset + 2] = (char)((p_Value & 0x0000ff0000000000) >> 40);
|
|
message[p_Offset + 1] = (char)((p_Value & 0x00ff000000000000) >> 48);
|
|
message[p_Offset + 0] = (char)((p_Value & 0xff00000000000000) >> 56);
|
|
}
|
|
return 8;
|
|
}
|
|
|
|
optional<bool> Message::getBoolean(const std::vector<char> &message, int &offset) {
|
|
if (offset < 0 || offset + 1 > message.size())
|
|
return std::nullopt;
|
|
return {message[offset++] > 0x00};
|
|
}
|
|
|
|
int Message::setBoolean(bool p_Value, std::vector<char> &message, int p_Offset) {
|
|
if ((p_Offset < 0) || (message.size() < p_Offset + 1))
|
|
throw "ParseError_send";
|
|
|
|
if (p_Value == false) {
|
|
message[p_Offset] = 0x00;
|
|
} else {
|
|
message[p_Offset] = 0x01;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
optional<char> Message::getByte(const std::vector<char> &message, int &offset) {
|
|
if (offset < 0 || offset + 1 > message.size())
|
|
return std::nullopt;
|
|
|
|
return {message[offset++]};
|
|
}
|
|
|
|
int Message::setByte(int p_Value, std::vector<char> &message, int p_Offset) {
|
|
if ((p_Offset < 0) || (message.size() < p_Offset + 1))
|
|
throw "ParseError_send";
|
|
|
|
message[p_Offset] = (char)(p_Value & 0xff);
|
|
return 1;
|
|
}
|
|
|
|
optional<string> Message::getString(const std::vector<char> &message, int &offset, int maxLength) {
|
|
if (offset < 0 || offset + maxLength > message.size())
|
|
return std::nullopt;
|
|
|
|
size_t len = strnlen(&message[offset], maxLength);
|
|
if (len >= maxLength)
|
|
return std::nullopt;
|
|
|
|
string str(&message[offset], len);
|
|
offset += maxLength;
|
|
return str;
|
|
}
|
|
|
|
int Message::setString(string p_String, std::vector<char> &message, int offset, int maxLength) {
|
|
if ((offset < 0) || (maxLength < 1) || (message.size() < offset + maxLength))
|
|
throw "ParseError_send";
|
|
|
|
int intLength;
|
|
if (p_String.length() + 1 > maxLength) {
|
|
intLength = maxLength;
|
|
} else {
|
|
intLength = p_String.length() + 1;
|
|
}
|
|
int intChar = 0;
|
|
bool boolNullChar = false;
|
|
while (intChar < intLength) {
|
|
message[offset + intChar] = p_String.data()[intChar];
|
|
if (p_String[intChar] == '\0') {
|
|
boolNullChar = true;
|
|
break;
|
|
}
|
|
intChar++;
|
|
}
|
|
if (boolNullChar == false) {
|
|
message[offset + intLength - 1] = '\0';
|
|
}
|
|
return maxLength;
|
|
}
|
|
} |