zeus/jus/Buffer.cpp

333 lines
8.6 KiB
C++

/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <jus/Buffer.h>
#include <jus/debug.h>
jus::Buffer::Buffer() {
clear();
}
void jus::Buffer::clear() {
m_data.clear();
m_paramOffset.clear();
m_header.clear();
}
std::string jus::Buffer::generateHumanString() {
return "jus::Buffer ...";
}
uint16_t jus::Buffer::getProtocalVersion() {
return m_header.versionProtocol;
}
void jus::Buffer::setProtocolVersion(uint16_t _value) {
m_header.versionProtocol = _value;
}
uint32_t jus::Buffer::getTransactionId() {
return m_header.transactionID;
}
void jus::Buffer::setTransactionId(uint32_t _value) {
m_header.transactionID = _value;
}
uint32_t jus::Buffer::getClientId() {
return m_header.clientID;
}
void jus::Buffer::setClientId(uint32_t _value) {
m_header.clientID = _value;
}
// note limited 15 bits
uint16_t jus::Buffer::getPartId() {
return uint16_t(m_header.partID & 0x7FFF);
}
void jus::Buffer::setPartId(uint16_t _value) {
m_header.partID = (m_header.partID&0x8000) | (_value & 0x7FFF);
}
bool jus::Buffer::getPartFinish() {
return m_header.versionProtocol<0;
}
void jus::Buffer::setPartFinish(bool _value) {
if (_value == true) {
m_header.versionProtocol = (m_header.versionProtocol & 0x7FFF) | 0x8000;
} else {
m_header.versionProtocol = m_header.versionProtocol & 0x7FFF;
}
}
enum jus::Buffer::typeMessage jus::Buffer::getType() {
return (enum jus::Buffer::typeMessage)m_header.typeMessage;
}
void jus::Buffer::setType(enum typeMessage _value) {
m_header.typeMessage = uint16_t(_value);
}
uint16_t jus::Buffer::getNumberParameter() {
return m_paramOffset.size()-1;
}
template<>
void jus::Buffer::addParameter<std::string>(const std::string& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('s');
m_data.push_back('t');
m_data.push_back('r');
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('g');
m_data.push_back('\0');
m_data.resize(m_data.size()+_value.size()+1);
memcpy(&m_data[currentOffset], &_value[0], m_data.size());
}
template<>
void jus::Buffer::addParameter<int8_t>(const int8_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('8');
m_data.push_back('\0');
m_data.push_back(uint8_t(_value));
}
template<>
void jus::Buffer::addParameter<uint8_t>(const uint8_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('u');
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('8');
m_data.push_back('\0');
m_data.push_back(_value);
}
template<>
void jus::Buffer::addParameter<int16_t>(const int16_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('1');
m_data.push_back('6');
m_data.push_back('\0');
m_data.resize(m_data.size()+2);
memcpy(&m_data[currentOffset], &_value, 2);
}
template<>
void jus::Buffer::addParameter<uint16_t>(const uint16_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('u');
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('1');
m_data.push_back('6');
m_data.push_back('\0');
m_data.resize(m_data.size()+2);
memcpy(&m_data[currentOffset], &_value, 2);
}
template<>
void jus::Buffer::addParameter<int32_t>(const int32_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('3');
m_data.push_back('2');
m_data.push_back('\0');
m_data.resize(m_data.size()+4);
memcpy(&m_data[currentOffset], &_value, 4);
}
template<>
void jus::Buffer::addParameter<uint32_t>(const uint32_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('u');
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('3');
m_data.push_back('2');
m_data.push_back('\0');
m_data.resize(m_data.size()+4);
memcpy(&m_data[currentOffset], &_value, 4);
}
template<>
void jus::Buffer::addParameter<int64_t>(const int64_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('3');
m_data.push_back('2');
m_data.push_back('\0');
m_data.resize(m_data.size()+8);
memcpy(&m_data[currentOffset], &_value, 8);
}
template<>
void jus::Buffer::addParameter<uint64_t>(const uint64_t& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('u');
m_data.push_back('i');
m_data.push_back('n');
m_data.push_back('t');
m_data.push_back('6');
m_data.push_back('4');
m_data.push_back('\0');
m_data.resize(m_data.size()+8);
memcpy(&m_data[currentOffset], &_value, 8);
}
template<>
void jus::Buffer::addParameter<float>(const float& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('f');
m_data.push_back('l');
m_data.push_back('o');
m_data.push_back('a');
m_data.push_back('t');
m_data.push_back('\0');
m_data.resize(m_data.size()+4);
memcpy(&m_data[currentOffset], &_value, 4);
}
template<>
void jus::Buffer::addParameter<double>(const double& _value) {
int32_t currentOffset = m_data.size();
m_paramOffset.push_back(currentOffset);
m_data.push_back('d');
m_data.push_back('o');
m_data.push_back('u');
m_data.push_back('b');
m_data.push_back('l');
m_data.push_back('e');
m_data.push_back('\0');
m_data.resize(m_data.size()+8);
memcpy(&m_data[currentOffset], &_value, 8);
}
template<>
std::string jus::Buffer::internalGetParameter<std::string>(int32_t _id) {
std::string out;
if (m_paramOffset.size() <= _id) {
JUS_ERROR("out of range Id for parameter ... " << _id << " have " << m_paramOffset.size());
return out;
}
int32_t startPos = m_paramOffset[_id];
int32_t endPos = m_data.size();
if (m_paramOffset.size() > _id+1) {
endPos = m_paramOffset[_id+1];
}
// First get type:
char* type = reinterpret_cast<char*>(&m_data[startPos]); // Will be stop with \0 ...
if (strcmp(type, "string") == 0) {
// OK
// move in the buffer pos
startPos += strlen(type) + 1;
// get real data size
int32_t dataSize = endPos - startPos;
if (dataSize < 0) {
JUS_ERROR("Get size < 0 : " << dataSize);
} else if (dataSize < 0) {
// nothing to do ...
} else {
// Allocate data
out.resize(dataSize, ' ');
memcpy(&out[0], &m_data[startPos], dataSize);
}
} else {
//wrong type ...
JUS_ERROR("Can not convert '" << type << "' into 'string'");
}
return out;
}
template<>
int8_t jus::Buffer::internalGetParameter<int8_t>(int32_t _id) {
int8_t out;
if (m_paramOffset.size() <= _id) {
JUS_ERROR("out of range Id for parameter ... " << _id << " have " << m_paramOffset.size());
return out;
}
int32_t startPos = m_paramOffset[_id];
int32_t endPos = m_data.size();
if (m_paramOffset.size() > _id+1) {
endPos = m_paramOffset[_id+1];
}
// First get type:
char* type = reinterpret_cast<char*>(&m_data[startPos]); // Will be stop with \0 ...
if (strcmp(type, "int8") == 0) {
// OK
// move in the buffer pos
startPos += strlen(type) + 1;
// get real data size
int32_t dataSize = endPos - startPos;
if (dataSize < 0) {
JUS_ERROR("Get size < 0 : " << dataSize);
} else if (dataSize < 0) {
// nothing to do ...
} else {
if (dataSize != 1) {
JUS_ERROR("Get size > 1 : " << dataSize << " ==> limit 1");
dataSize = 1;
}
// Allocate data
memcpy(&out, &m_data[startPos], dataSize);
}
} else {
//wrong type ...
JUS_ERROR("Can not convert '" << type << "' into 'string'");
}
return out;
}
std::string jus::Buffer::getCall() {
std::string out;
switch(getType()) {
case jus::Buffer::typeMessage::call:
return internalGetParameter<std::string>(0);
break;
case jus::Buffer::typeMessage::answer:
JUS_WARNING("get 'call' with an input type: 'answer'");
break;
case jus::Buffer::typeMessage::event:
JUS_WARNING("get 'call' with an input type: 'event'");
break;
default:
JUS_ERROR("unknow type: " << uint16_t(getType()));
break;
}
return "";
}
void jus::Buffer::setCall(std::string _value) {
if (m_paramOffset.size() != 0) {
JUS_ERROR("Clear Buffer of parameter ==> set the call type in first ...");
m_paramOffset.clear();
m_data.clear();
}
addParameter(_value);
}