1
0
forked from fsfw/fsfw

renormalized line endings

This commit is contained in:
2020-08-28 18:33:29 +02:00
parent 9abd796e6f
commit 1b9c8446b7
381 changed files with 38723 additions and 38723 deletions

View File

@ -1,230 +1,230 @@
#include "../globalfunctions/AsciiConverter.h"
#include <limits>
#include <cmath>
template<typename T>
ReturnValue_t AsciiConverter::scanAsciiDecimalNumber(const uint8_t** dataPtr,
uint8_t len, T* value) {
if (len > std::numeric_limits<T>().digits10) {
return TOO_LONG_FOR_TARGET_TYPE;
}
double temp;
ReturnValue_t result = scanAsciiDecimalNumber_(dataPtr, len, &temp);
*value = temp;
return result;
}
ReturnValue_t AsciiConverter::scanAsciiHexByte(const uint8_t** dataPtr,
uint8_t* value) {
int8_t tmp;
tmp = convertHexChar(*dataPtr);
(*dataPtr)++;
if (tmp == -1) {
return INVALID_CHARACTERS;
}
if (tmp == -2) {
tmp = 0;
}
*value = tmp << 4;
tmp = convertHexChar(*dataPtr);
(*dataPtr)++;
if (tmp == -1) {
return INVALID_CHARACTERS;
}
if (tmp != -2) {
*value += tmp;
} else {
*value = *value >> 4;
}
return RETURN_OK;
}
ReturnValue_t AsciiConverter::scanAsciiDecimalNumber_(uint8_t const ** dataPtr,
uint8_t len, double* value) {
uint8_t const *ptr = *dataPtr;
int8_t sign = 1;
float decimal = 0;
bool abort = false;
*value = 0;
//ignore leading space
ptr = clearSpace(ptr, len);
while ((ptr - *dataPtr < len) && !abort) {
switch (*ptr) {
case '+':
sign = 1;
break;
case '-':
sign = -1;
break;
case '.':
decimal = 1;
break;
case ' ':
case 0x0d:
case 0x0a:
//ignore trailing space
ptr = clearSpace(ptr, len - (ptr - *dataPtr)) - 1; //before aborting the loop, ptr will be incremented
abort = true;
break;
default:
if ((*ptr < 0x30) || (*ptr > 0x39)) {
return INVALID_CHARACTERS;
}
*value = *value * 10 + (*ptr - 0x30);
if (decimal > 0) {
decimal *= 10;
}
break;
}
ptr++;
}
if (decimal == 0) {
decimal = 1;
}
*value = *value / (decimal) * sign;
*dataPtr = ptr;
return RETURN_OK;
}
ReturnValue_t AsciiConverter::printFloat(uint8_t* buffer, uint32_t bufferLength,
float value, uint8_t decimalPlaces, uint32_t *printedSize) {
*printedSize = 0;
uint32_t streamposition = 0, integerSize;
bool negative = (value < 0);
int32_t digits = bufferLength - decimalPlaces - 1;
if (digits <= 0) {
return BUFFER_TOO_SMALL;
}
if (negative) {
digits -= 1;
buffer[streamposition++] = '-';
value = -value;
}
float maximumNumber = pow(10, digits);
if (value >= maximumNumber) {
return BUFFER_TOO_SMALL;
}
//print the numbers before the decimal point;
ReturnValue_t result = printInteger(buffer + streamposition,
bufferLength - streamposition - decimalPlaces - 1, value,
&integerSize);
if (result != RETURN_OK) {
return result;
}
streamposition += integerSize;
//The decimal Point
buffer[streamposition++] = '.';
//Print the decimals
uint32_t integerValue = value;
value -= integerValue;
value = value * pow(10, decimalPlaces);
result = printInteger(buffer + streamposition, decimalPlaces, round(value),
&integerSize, true);
*printedSize = integerSize + streamposition;
return result;
}
ReturnValue_t AsciiConverter::printInteger(uint8_t* buffer,
uint32_t bufferLength, uint32_t value, uint32_t *printedSize,
bool leadingZeros) {
*printedSize = 0;
if (bufferLength == 0) {
return BUFFER_TOO_SMALL;
}
uint32_t maximumNumber = -1;
if (bufferLength < 10) {
maximumNumber = pow(10, bufferLength);
if (value >= maximumNumber) {
return BUFFER_TOO_SMALL;
}
maximumNumber /= 10;
} else {
if (!(value <= maximumNumber)) {
return BUFFER_TOO_SMALL;
}
maximumNumber = 1000000000;
}
if (!leadingZeros && (value == 0)) {
buffer[(*printedSize)++] = '0';
return RETURN_OK;
}
while (maximumNumber >= 1) {
uint8_t number = value / maximumNumber;
value = value - (number * maximumNumber);
if (!leadingZeros && number == 0) {
maximumNumber /= 10;
} else {
leadingZeros = true;
buffer[(*printedSize)++] = '0' + number;
maximumNumber /= 10;
}
}
return RETURN_OK;
}
ReturnValue_t AsciiConverter::printSignedInteger(uint8_t* buffer,
uint32_t bufferLength, int32_t value, uint32_t *printedSize) {
bool negative = false;
if ((bufferLength > 0) && (value < 0)) {
*buffer++ = '-';
bufferLength--;
value = -value;
negative = true;
}
ReturnValue_t result = printInteger(buffer, bufferLength, value,
printedSize);
if (negative) {
(*printedSize)++;
}
return result;
}
int8_t AsciiConverter::convertHexChar(const uint8_t* character) {
if ((*character > 0x60) && (*character < 0x67)) {
return *character - 0x61 + 10;
} else if ((*character > 0x40) && (*character < 0x47)) {
return *character - 0x41 + 10;
} else if ((*character > 0x2F) && (*character < 0x3A)) {
return *character - 0x30;
} else if (*character == ' ') {
return -2;
}
return -1;
}
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<float>(
const uint8_t** dataPtr, uint8_t len, float* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<uint8_t>(
const uint8_t** dataPtr, uint8_t len, uint8_t* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<uint16_t>(
const uint8_t** dataPtr, uint8_t len, uint16_t* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<double>(
const uint8_t** dataPtr, uint8_t len, double* value);
const uint8_t* AsciiConverter::clearSpace(const uint8_t* data, uint8_t len) {
while (len > 0) {
if ((*data != ' ') && (*data != 0x0a) && (*data != 0x0d)) {
return data;
}
data++;
len--;
}
return data;
}
#include "../globalfunctions/AsciiConverter.h"
#include <limits>
#include <cmath>
template<typename T>
ReturnValue_t AsciiConverter::scanAsciiDecimalNumber(const uint8_t** dataPtr,
uint8_t len, T* value) {
if (len > std::numeric_limits<T>().digits10) {
return TOO_LONG_FOR_TARGET_TYPE;
}
double temp;
ReturnValue_t result = scanAsciiDecimalNumber_(dataPtr, len, &temp);
*value = temp;
return result;
}
ReturnValue_t AsciiConverter::scanAsciiHexByte(const uint8_t** dataPtr,
uint8_t* value) {
int8_t tmp;
tmp = convertHexChar(*dataPtr);
(*dataPtr)++;
if (tmp == -1) {
return INVALID_CHARACTERS;
}
if (tmp == -2) {
tmp = 0;
}
*value = tmp << 4;
tmp = convertHexChar(*dataPtr);
(*dataPtr)++;
if (tmp == -1) {
return INVALID_CHARACTERS;
}
if (tmp != -2) {
*value += tmp;
} else {
*value = *value >> 4;
}
return RETURN_OK;
}
ReturnValue_t AsciiConverter::scanAsciiDecimalNumber_(uint8_t const ** dataPtr,
uint8_t len, double* value) {
uint8_t const *ptr = *dataPtr;
int8_t sign = 1;
float decimal = 0;
bool abort = false;
*value = 0;
//ignore leading space
ptr = clearSpace(ptr, len);
while ((ptr - *dataPtr < len) && !abort) {
switch (*ptr) {
case '+':
sign = 1;
break;
case '-':
sign = -1;
break;
case '.':
decimal = 1;
break;
case ' ':
case 0x0d:
case 0x0a:
//ignore trailing space
ptr = clearSpace(ptr, len - (ptr - *dataPtr)) - 1; //before aborting the loop, ptr will be incremented
abort = true;
break;
default:
if ((*ptr < 0x30) || (*ptr > 0x39)) {
return INVALID_CHARACTERS;
}
*value = *value * 10 + (*ptr - 0x30);
if (decimal > 0) {
decimal *= 10;
}
break;
}
ptr++;
}
if (decimal == 0) {
decimal = 1;
}
*value = *value / (decimal) * sign;
*dataPtr = ptr;
return RETURN_OK;
}
ReturnValue_t AsciiConverter::printFloat(uint8_t* buffer, uint32_t bufferLength,
float value, uint8_t decimalPlaces, uint32_t *printedSize) {
*printedSize = 0;
uint32_t streamposition = 0, integerSize;
bool negative = (value < 0);
int32_t digits = bufferLength - decimalPlaces - 1;
if (digits <= 0) {
return BUFFER_TOO_SMALL;
}
if (negative) {
digits -= 1;
buffer[streamposition++] = '-';
value = -value;
}
float maximumNumber = pow(10, digits);
if (value >= maximumNumber) {
return BUFFER_TOO_SMALL;
}
//print the numbers before the decimal point;
ReturnValue_t result = printInteger(buffer + streamposition,
bufferLength - streamposition - decimalPlaces - 1, value,
&integerSize);
if (result != RETURN_OK) {
return result;
}
streamposition += integerSize;
//The decimal Point
buffer[streamposition++] = '.';
//Print the decimals
uint32_t integerValue = value;
value -= integerValue;
value = value * pow(10, decimalPlaces);
result = printInteger(buffer + streamposition, decimalPlaces, round(value),
&integerSize, true);
*printedSize = integerSize + streamposition;
return result;
}
ReturnValue_t AsciiConverter::printInteger(uint8_t* buffer,
uint32_t bufferLength, uint32_t value, uint32_t *printedSize,
bool leadingZeros) {
*printedSize = 0;
if (bufferLength == 0) {
return BUFFER_TOO_SMALL;
}
uint32_t maximumNumber = -1;
if (bufferLength < 10) {
maximumNumber = pow(10, bufferLength);
if (value >= maximumNumber) {
return BUFFER_TOO_SMALL;
}
maximumNumber /= 10;
} else {
if (!(value <= maximumNumber)) {
return BUFFER_TOO_SMALL;
}
maximumNumber = 1000000000;
}
if (!leadingZeros && (value == 0)) {
buffer[(*printedSize)++] = '0';
return RETURN_OK;
}
while (maximumNumber >= 1) {
uint8_t number = value / maximumNumber;
value = value - (number * maximumNumber);
if (!leadingZeros && number == 0) {
maximumNumber /= 10;
} else {
leadingZeros = true;
buffer[(*printedSize)++] = '0' + number;
maximumNumber /= 10;
}
}
return RETURN_OK;
}
ReturnValue_t AsciiConverter::printSignedInteger(uint8_t* buffer,
uint32_t bufferLength, int32_t value, uint32_t *printedSize) {
bool negative = false;
if ((bufferLength > 0) && (value < 0)) {
*buffer++ = '-';
bufferLength--;
value = -value;
negative = true;
}
ReturnValue_t result = printInteger(buffer, bufferLength, value,
printedSize);
if (negative) {
(*printedSize)++;
}
return result;
}
int8_t AsciiConverter::convertHexChar(const uint8_t* character) {
if ((*character > 0x60) && (*character < 0x67)) {
return *character - 0x61 + 10;
} else if ((*character > 0x40) && (*character < 0x47)) {
return *character - 0x41 + 10;
} else if ((*character > 0x2F) && (*character < 0x3A)) {
return *character - 0x30;
} else if (*character == ' ') {
return -2;
}
return -1;
}
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<float>(
const uint8_t** dataPtr, uint8_t len, float* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<uint8_t>(
const uint8_t** dataPtr, uint8_t len, uint8_t* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<uint16_t>(
const uint8_t** dataPtr, uint8_t len, uint16_t* value);
template ReturnValue_t AsciiConverter::scanAsciiDecimalNumber<double>(
const uint8_t** dataPtr, uint8_t len, double* value);
const uint8_t* AsciiConverter::clearSpace(const uint8_t* data, uint8_t len) {
while (len > 0) {
if ((*data != ' ') && (*data != 0x0a) && (*data != 0x0d)) {
return data;
}
data++;
len--;
}
return data;
}

View File

@ -1,39 +1,39 @@
#ifndef ASCIICONVERTER_H_
#define ASCIICONVERTER_H_
#include "../returnvalues/HasReturnvaluesIF.h"
class AsciiConverter: public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::ASCII_CONVERTER;
static const ReturnValue_t TOO_LONG_FOR_TARGET_TYPE = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_CHARACTERS = MAKE_RETURN_CODE(2);
static const ReturnValue_t BUFFER_TOO_SMALL = MAKE_RETURN_CODE(0x3);
template<typename T>
static ReturnValue_t scanAsciiDecimalNumber(const uint8_t **dataPtr,
uint8_t len, T *value);
static ReturnValue_t scanAsciiHexByte(const uint8_t **dataPtr,
uint8_t *value);
static ReturnValue_t printFloat(uint8_t *buffer, uint32_t bufferLength,
float value, uint8_t decimalPlaces, uint32_t *printedSize);
static ReturnValue_t printInteger(uint8_t *buffer, uint32_t bufferLength,
uint32_t value, uint32_t *printedSize, bool leadingZeros = false);
static ReturnValue_t printSignedInteger(uint8_t *buffer,
uint32_t bufferLength, int32_t value, uint32_t *printedSize);
private:
AsciiConverter();
static ReturnValue_t scanAsciiDecimalNumber_(const uint8_t **dataPtr,
uint8_t len, double *value);
static int8_t convertHexChar(const uint8_t *character);
static const uint8_t *clearSpace(const uint8_t *data, uint8_t len);
};
#endif /* ASCIICONVERTER_H_ */
#ifndef ASCIICONVERTER_H_
#define ASCIICONVERTER_H_
#include "../returnvalues/HasReturnvaluesIF.h"
class AsciiConverter: public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::ASCII_CONVERTER;
static const ReturnValue_t TOO_LONG_FOR_TARGET_TYPE = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_CHARACTERS = MAKE_RETURN_CODE(2);
static const ReturnValue_t BUFFER_TOO_SMALL = MAKE_RETURN_CODE(0x3);
template<typename T>
static ReturnValue_t scanAsciiDecimalNumber(const uint8_t **dataPtr,
uint8_t len, T *value);
static ReturnValue_t scanAsciiHexByte(const uint8_t **dataPtr,
uint8_t *value);
static ReturnValue_t printFloat(uint8_t *buffer, uint32_t bufferLength,
float value, uint8_t decimalPlaces, uint32_t *printedSize);
static ReturnValue_t printInteger(uint8_t *buffer, uint32_t bufferLength,
uint32_t value, uint32_t *printedSize, bool leadingZeros = false);
static ReturnValue_t printSignedInteger(uint8_t *buffer,
uint32_t bufferLength, int32_t value, uint32_t *printedSize);
private:
AsciiConverter();
static ReturnValue_t scanAsciiDecimalNumber_(const uint8_t **dataPtr,
uint8_t len, double *value);
static int8_t convertHexChar(const uint8_t *character);
static const uint8_t *clearSpace(const uint8_t *data, uint8_t len);
};
#endif /* ASCIICONVERTER_H_ */

View File

@ -1,139 +1,139 @@
#include "../globalfunctions/CRC.h"
#include <math.h>
const uint16_t CRC::crc16ccitt_table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
// CRC implementation
uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t startingCrc)
{
uint8_t *data = (uint8_t *)input;
unsigned int tbl_idx;
while (length--) {
tbl_idx = ((startingCrc >> 8) ^ *data) & 0xff;
startingCrc = (crc16ccitt_table[tbl_idx] ^ (startingCrc << 8)) & 0xffff;
data++;
}
return startingCrc & 0xffff;
//The part below is not used!
// bool temr[16];
// bool xor_out[16];
// bool r[16];
// bool d[8];
// uint16_t crc_value = 0;
//
//
// for (int i=0; i<16 ;i++) {
// temr[i] = false;
// xor_out[i] = false;
// }
//
//
// for (int i=0; i<16 ;i++)
// r[i] = true; // initialize with 0xFFFF
//
//
//
// for (int j=0; j<length ;j++)
// {
//
// for (int i=0; i<8 ;i++)
// if ((input[j] & 1<<i) == 1<<i)
// d[7-i]=true; // reverse input data
// else
// d[7-i]=false; // reverse input data
//
//
//
// temr[0] = d[4] ^ d[0];
// temr[1] = d[5] ^ d[1];
// temr[2] = d[6] ^ d[2];
// temr[3] = d[7] ^ d[3];
// temr[4] = r[12] ^ r[8];
// temr[5] = r[13] ^ r[9];
// temr[6] = r[14] ^ r[10];
// temr[7] = r[15] ^ r[11];
// temr[8] = d[4] ^ r[12];
// temr[9] = d[5] ^ r[13];
// temr[10] = d[6] ^ r[14];
// temr[11] = d[7] ^ r[15];
// temr[12] = temr[0] ^ temr[4];
// temr[13] = temr[1] ^ temr[5];
// temr[14] = temr[2] ^ temr[6];
// temr[15] = temr[3] ^ temr[7];
//
//
// xor_out[0] = temr[12];
// xor_out[1] = temr[13];
// xor_out[2] = temr[14];
// xor_out[3] = temr[15];
// xor_out[4] = temr[8];
// xor_out[5] = temr[9] ^ temr[12];
// xor_out[6] = temr[10] ^ temr[13];
// xor_out[7] = temr[11] ^ temr[14];
// xor_out[8] = temr[15] ^ r[0];
// xor_out[9] = temr[8] ^ r[1];
// xor_out[10] = temr[9] ^ r[2];
// xor_out[11] = temr[10] ^ r[3];
// xor_out[12] = temr[11] ^ temr[12] ^ r[4];
// xor_out[13] = temr[13] ^ r[5];
// xor_out[14] = temr[14] ^ r[6];
// xor_out[15] = temr[15] ^ r[7];
//
// for (int i=0; i<16 ;i++)
// {
// r[i]= xor_out[i] ;
// }
//
// }
//
//
//
// for (int i=0; i<16 ;i++)
// {
// if (xor_out[i] == true)
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before Final XOR
// }
//
// crc_value = 0;// for debug mode
// return (crc_value);
} /* Calculate_CRC() */
#include "../globalfunctions/CRC.h"
#include <math.h>
const uint16_t CRC::crc16ccitt_table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
// CRC implementation
uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t startingCrc)
{
uint8_t *data = (uint8_t *)input;
unsigned int tbl_idx;
while (length--) {
tbl_idx = ((startingCrc >> 8) ^ *data) & 0xff;
startingCrc = (crc16ccitt_table[tbl_idx] ^ (startingCrc << 8)) & 0xffff;
data++;
}
return startingCrc & 0xffff;
//The part below is not used!
// bool temr[16];
// bool xor_out[16];
// bool r[16];
// bool d[8];
// uint16_t crc_value = 0;
//
//
// for (int i=0; i<16 ;i++) {
// temr[i] = false;
// xor_out[i] = false;
// }
//
//
// for (int i=0; i<16 ;i++)
// r[i] = true; // initialize with 0xFFFF
//
//
//
// for (int j=0; j<length ;j++)
// {
//
// for (int i=0; i<8 ;i++)
// if ((input[j] & 1<<i) == 1<<i)
// d[7-i]=true; // reverse input data
// else
// d[7-i]=false; // reverse input data
//
//
//
// temr[0] = d[4] ^ d[0];
// temr[1] = d[5] ^ d[1];
// temr[2] = d[6] ^ d[2];
// temr[3] = d[7] ^ d[3];
// temr[4] = r[12] ^ r[8];
// temr[5] = r[13] ^ r[9];
// temr[6] = r[14] ^ r[10];
// temr[7] = r[15] ^ r[11];
// temr[8] = d[4] ^ r[12];
// temr[9] = d[5] ^ r[13];
// temr[10] = d[6] ^ r[14];
// temr[11] = d[7] ^ r[15];
// temr[12] = temr[0] ^ temr[4];
// temr[13] = temr[1] ^ temr[5];
// temr[14] = temr[2] ^ temr[6];
// temr[15] = temr[3] ^ temr[7];
//
//
// xor_out[0] = temr[12];
// xor_out[1] = temr[13];
// xor_out[2] = temr[14];
// xor_out[3] = temr[15];
// xor_out[4] = temr[8];
// xor_out[5] = temr[9] ^ temr[12];
// xor_out[6] = temr[10] ^ temr[13];
// xor_out[7] = temr[11] ^ temr[14];
// xor_out[8] = temr[15] ^ r[0];
// xor_out[9] = temr[8] ^ r[1];
// xor_out[10] = temr[9] ^ r[2];
// xor_out[11] = temr[10] ^ r[3];
// xor_out[12] = temr[11] ^ temr[12] ^ r[4];
// xor_out[13] = temr[13] ^ r[5];
// xor_out[14] = temr[14] ^ r[6];
// xor_out[15] = temr[15] ^ r[7];
//
// for (int i=0; i<16 ;i++)
// {
// r[i]= xor_out[i] ;
// }
//
// }
//
//
//
// for (int i=0; i<16 ;i++)
// {
// if (xor_out[i] == true)
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before Final XOR
// }
//
// crc_value = 0;// for debug mode
// return (crc_value);
} /* Calculate_CRC() */

View File

@ -1,124 +1,124 @@
#include "../globalfunctions/DleEncoder.h"
DleEncoder::DleEncoder() {}
DleEncoder::~DleEncoder() {}
ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream,
size_t sourceLen, uint8_t* destStream, size_t maxDestLen,
size_t* encodedLen, bool addStxEtx) {
if (maxDestLen < 2) {
return STREAM_TOO_SHORT;
}
size_t encodedIndex = 0, sourceIndex = 0;
uint8_t nextByte;
if (addStxEtx) {
destStream[0] = STX_CHAR;
++encodedIndex;
}
while (encodedIndex < maxDestLen and sourceIndex < sourceLen)
{
nextByte = sourceStream[sourceIndex];
// STX, ETX and CR characters in the stream need to be escaped with DLE
if (nextByte == STX_CHAR or nextByte == ETX_CHAR or nextByte == CARRIAGE_RETURN) {
if (encodedIndex + 1 >= maxDestLen) {
return STREAM_TOO_SHORT;
}
else {
destStream[encodedIndex] = DLE_CHAR;
++encodedIndex;
/* Escaped byte will be actual byte + 0x40. This prevents
* STX, ETX, and carriage return characters from appearing
* in the encoded data stream at all, so when polling an
* encoded stream, the transmission can be stopped at ETX.
* 0x40 was chosen at random with special requirements:
* - Prevent going from one control char to another
* - Prevent overflow for common characters */
destStream[encodedIndex] = nextByte + 0x40;
}
}
// DLE characters are simply escaped with DLE.
else if (nextByte == DLE_CHAR) {
if (encodedIndex + 1 >= maxDestLen) {
return STREAM_TOO_SHORT;
}
else {
destStream[encodedIndex] = DLE_CHAR;
++encodedIndex;
destStream[encodedIndex] = DLE_CHAR;
}
}
else {
destStream[encodedIndex] = nextByte;
}
++encodedIndex;
++sourceIndex;
}
if (sourceIndex == sourceLen and encodedIndex < maxDestLen) {
if (addStxEtx) {
destStream[encodedIndex] = ETX_CHAR;
++encodedIndex;
}
*encodedLen = encodedIndex;
return RETURN_OK;
}
else {
return STREAM_TOO_SHORT;
}
}
ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream,
size_t sourceStreamLen, size_t *readLen, uint8_t *destStream,
size_t maxDestStreamlen, size_t *decodedLen) {
size_t encodedIndex = 0, decodedIndex = 0;
uint8_t nextByte;
if (*sourceStream != STX_CHAR) {
return DECODING_ERROR;
}
++encodedIndex;
while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)
&& (sourceStream[encodedIndex] != ETX_CHAR)
&& (sourceStream[encodedIndex] != STX_CHAR)) {
if (sourceStream[encodedIndex] == DLE_CHAR) {
nextByte = sourceStream[encodedIndex + 1];
// The next byte is a DLE character that was escaped by another
// DLE character, so we can write it to the destination stream.
if (nextByte == DLE_CHAR) {
destStream[decodedIndex] = nextByte;
}
else {
/* The next byte is a STX, DTX or 0x0D character which
* was escaped by a DLE character. The actual byte was
* also encoded by adding + 0x40 to preven having control chars,
* in the stream at all, so we convert it back. */
if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) {
destStream[decodedIndex] = nextByte - 0x40;
}
else {
return DECODING_ERROR;
}
}
++encodedIndex;
}
else {
destStream[decodedIndex] = sourceStream[encodedIndex];
}
++encodedIndex;
++decodedIndex;
}
if (sourceStream[encodedIndex] != ETX_CHAR) {
*readLen = ++encodedIndex;
return DECODING_ERROR;
}
else {
*readLen = ++encodedIndex;
*decodedLen = decodedIndex;
return RETURN_OK;
}
}
#include "../globalfunctions/DleEncoder.h"
DleEncoder::DleEncoder() {}
DleEncoder::~DleEncoder() {}
ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream,
size_t sourceLen, uint8_t* destStream, size_t maxDestLen,
size_t* encodedLen, bool addStxEtx) {
if (maxDestLen < 2) {
return STREAM_TOO_SHORT;
}
size_t encodedIndex = 0, sourceIndex = 0;
uint8_t nextByte;
if (addStxEtx) {
destStream[0] = STX_CHAR;
++encodedIndex;
}
while (encodedIndex < maxDestLen and sourceIndex < sourceLen)
{
nextByte = sourceStream[sourceIndex];
// STX, ETX and CR characters in the stream need to be escaped with DLE
if (nextByte == STX_CHAR or nextByte == ETX_CHAR or nextByte == CARRIAGE_RETURN) {
if (encodedIndex + 1 >= maxDestLen) {
return STREAM_TOO_SHORT;
}
else {
destStream[encodedIndex] = DLE_CHAR;
++encodedIndex;
/* Escaped byte will be actual byte + 0x40. This prevents
* STX, ETX, and carriage return characters from appearing
* in the encoded data stream at all, so when polling an
* encoded stream, the transmission can be stopped at ETX.
* 0x40 was chosen at random with special requirements:
* - Prevent going from one control char to another
* - Prevent overflow for common characters */
destStream[encodedIndex] = nextByte + 0x40;
}
}
// DLE characters are simply escaped with DLE.
else if (nextByte == DLE_CHAR) {
if (encodedIndex + 1 >= maxDestLen) {
return STREAM_TOO_SHORT;
}
else {
destStream[encodedIndex] = DLE_CHAR;
++encodedIndex;
destStream[encodedIndex] = DLE_CHAR;
}
}
else {
destStream[encodedIndex] = nextByte;
}
++encodedIndex;
++sourceIndex;
}
if (sourceIndex == sourceLen and encodedIndex < maxDestLen) {
if (addStxEtx) {
destStream[encodedIndex] = ETX_CHAR;
++encodedIndex;
}
*encodedLen = encodedIndex;
return RETURN_OK;
}
else {
return STREAM_TOO_SHORT;
}
}
ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream,
size_t sourceStreamLen, size_t *readLen, uint8_t *destStream,
size_t maxDestStreamlen, size_t *decodedLen) {
size_t encodedIndex = 0, decodedIndex = 0;
uint8_t nextByte;
if (*sourceStream != STX_CHAR) {
return DECODING_ERROR;
}
++encodedIndex;
while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)
&& (sourceStream[encodedIndex] != ETX_CHAR)
&& (sourceStream[encodedIndex] != STX_CHAR)) {
if (sourceStream[encodedIndex] == DLE_CHAR) {
nextByte = sourceStream[encodedIndex + 1];
// The next byte is a DLE character that was escaped by another
// DLE character, so we can write it to the destination stream.
if (nextByte == DLE_CHAR) {
destStream[decodedIndex] = nextByte;
}
else {
/* The next byte is a STX, DTX or 0x0D character which
* was escaped by a DLE character. The actual byte was
* also encoded by adding + 0x40 to preven having control chars,
* in the stream at all, so we convert it back. */
if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) {
destStream[decodedIndex] = nextByte - 0x40;
}
else {
return DECODING_ERROR;
}
}
++encodedIndex;
}
else {
destStream[decodedIndex] = sourceStream[encodedIndex];
}
++encodedIndex;
++decodedIndex;
}
if (sourceStream[encodedIndex] != ETX_CHAR) {
*readLen = ++encodedIndex;
return DECODING_ERROR;
}
else {
*readLen = ++encodedIndex;
*decodedLen = decodedIndex;
return RETURN_OK;
}
}

View File

@ -1,79 +1,79 @@
#ifndef FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_
#define FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include <cstddef>
/**
* @brief This DLE Encoder (Data Link Encoder) can be used to encode and
* decode arbitrary data with ASCII control characters
* @details
* List of control codes:
* https://en.wikipedia.org/wiki/C0_and_C1_control_codes
*
* This encoder can be used to achieve a basic transport layer when using
* char based transmission systems.
* The passed source strean is converted into a encoded stream by adding
* a STX marker at the start of the stream and an ETX marker at the end of
* the stream. Any STX, ETX, DLE and CR occurences in the source stream are
* escaped by a DLE character. The encoder also replaces escaped control chars
* by another char, so STX, ETX and CR should not appear anywhere in the actual
* encoded data stream.
*
* When using a strictly char based reception of packets enoded with DLE,
* STX can be used to notify a reader that actual data will start to arrive
* while ETX can be used to notify the reader that the data has ended.
*/
class DleEncoder: public HasReturnvaluesIF {
private:
DleEncoder();
virtual ~DleEncoder();
public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER;
static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02);
//! Start Of Text character. First character is encoded stream
static constexpr uint8_t STX_CHAR = 0x02;
//! End Of Text character. Last character in encoded stream
static constexpr uint8_t ETX_CHAR = 0x03;
//! Data Link Escape character. Used to escape STX, ETX and DLE occurences
//! in the source stream.
static constexpr uint8_t DLE_CHAR = 0x10;
static constexpr uint8_t CARRIAGE_RETURN = 0x0D;
/**
* Encodes the give data stream by preceding it with the STX marker
* and ending it with an ETX marker. STX, ETX and DLE characters inside
* the stream are escaped by DLE characters and also replaced by adding
* 0x40 (which is reverted in the decoing process).
* @param sourceStream
* @param sourceLen
* @param destStream
* @param maxDestLen
* @param encodedLen
* @param addStxEtx
* Adding STX and ETX can be omitted, if they are added manually.
* @return
*/
static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen,
uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
bool addStxEtx = true);
/**
* Converts an encoded stream back.
* @param sourceStream
* @param sourceStreamLen
* @param readLen
* @param destStream
* @param maxDestStreamlen
* @param decodedLen
* @return
*/
static ReturnValue_t decode(const uint8_t *sourceStream,
size_t sourceStreamLen, size_t *readLen, uint8_t *destStream,
size_t maxDestStreamlen, size_t *decodedLen);
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */
#ifndef FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_
#define FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include <cstddef>
/**
* @brief This DLE Encoder (Data Link Encoder) can be used to encode and
* decode arbitrary data with ASCII control characters
* @details
* List of control codes:
* https://en.wikipedia.org/wiki/C0_and_C1_control_codes
*
* This encoder can be used to achieve a basic transport layer when using
* char based transmission systems.
* The passed source strean is converted into a encoded stream by adding
* a STX marker at the start of the stream and an ETX marker at the end of
* the stream. Any STX, ETX, DLE and CR occurences in the source stream are
* escaped by a DLE character. The encoder also replaces escaped control chars
* by another char, so STX, ETX and CR should not appear anywhere in the actual
* encoded data stream.
*
* When using a strictly char based reception of packets enoded with DLE,
* STX can be used to notify a reader that actual data will start to arrive
* while ETX can be used to notify the reader that the data has ended.
*/
class DleEncoder: public HasReturnvaluesIF {
private:
DleEncoder();
virtual ~DleEncoder();
public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER;
static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02);
//! Start Of Text character. First character is encoded stream
static constexpr uint8_t STX_CHAR = 0x02;
//! End Of Text character. Last character in encoded stream
static constexpr uint8_t ETX_CHAR = 0x03;
//! Data Link Escape character. Used to escape STX, ETX and DLE occurences
//! in the source stream.
static constexpr uint8_t DLE_CHAR = 0x10;
static constexpr uint8_t CARRIAGE_RETURN = 0x0D;
/**
* Encodes the give data stream by preceding it with the STX marker
* and ending it with an ETX marker. STX, ETX and DLE characters inside
* the stream are escaped by DLE characters and also replaced by adding
* 0x40 (which is reverted in the decoing process).
* @param sourceStream
* @param sourceLen
* @param destStream
* @param maxDestLen
* @param encodedLen
* @param addStxEtx
* Adding STX and ETX can be omitted, if they are added manually.
* @return
*/
static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen,
uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
bool addStxEtx = true);
/**
* Converts an encoded stream back.
* @param sourceStream
* @param sourceStreamLen
* @param readLen
* @param destStream
* @param maxDestStreamlen
* @param decodedLen
* @return
*/
static ReturnValue_t decode(const uint8_t *sourceStream,
size_t sourceStreamLen, size_t *readLen, uint8_t *destStream,
size_t maxDestStreamlen, size_t *decodedLen);
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */

View File

@ -1,181 +1,181 @@
#include "../globalfunctions/Type.h"
#include "../serialize/SerializeAdapter.h"
Type::Type() :
actualType(UNKNOWN_TYPE) {
}
Type::Type(ActualType_t actualType) :
actualType(actualType) {
}
Type::Type(const Type& type) :
actualType(type.actualType) {
}
Type& Type::operator =(Type rhs) {
this->actualType = rhs.actualType;
return *this;
}
Type& Type::operator =(ActualType_t actualType) {
this->actualType = actualType;
return *this;
}
Type::operator Type::ActualType_t() const {
return actualType;
}
bool Type::operator ==(const Type& rhs) {
return this->actualType == rhs.actualType;
}
bool Type::operator !=(const Type& rhs) {
return !operator==(rhs);
}
uint8_t Type::getSize() const {
switch (actualType) {
case UINT8_T:
return sizeof(uint8_t);
case INT8_T:
return sizeof(int8_t);
case UINT16_T:
return sizeof(uint16_t);
case INT16_T:
return sizeof(int16_t);
case UINT32_T:
return sizeof(uint32_t);
case INT32_T:
return sizeof(int32_t);
case FLOAT:
return sizeof(float);
case DOUBLE:
return sizeof(double);
default:
return 0;
}
}
ReturnValue_t Type::serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
uint8_t ptc;
uint8_t pfc;
ReturnValue_t result = getPtcPfc(&ptc, &pfc);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&ptc, buffer, size, maxSize,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&pfc, buffer, size, maxSize,
streamEndianness);
return result;
}
size_t Type::getSerializedSize() const {
uint8_t dontcare = 0;
return 2 * SerializeAdapter::getSerializedSize(&dontcare);
}
ReturnValue_t Type::deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
uint8_t ptc;
uint8_t pfc;
ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer,
size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&pfc, buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
actualType = getActualType(ptc, pfc);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Type::getPtcPfc(uint8_t* ptc, uint8_t* pfc) const {
switch (actualType) {
case UINT8_T:
*ptc = 3;
*pfc = 4;
break;
case INT8_T:
*ptc = 4;
*pfc = 4;
break;
case UINT16_T:
*ptc = 3;
*pfc = 12;
break;
case INT16_T:
*ptc = 4;
*pfc = 12;
break;
case UINT32_T:
*ptc = 3;
*pfc = 14;
break;
case INT32_T:
*ptc = 4;
*pfc = 14;
break;
case FLOAT:
*ptc = 5;
*pfc = 1;
break;
case DOUBLE:
*ptc = 5;
*pfc = 2;
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
Type::ActualType_t Type::getActualType(uint8_t ptc, uint8_t pfc) {
switch (ptc) {
case 3:
switch (pfc) {
case 4:
return UINT8_T;
case 12:
return UINT16_T;
case 14:
return UINT32_T;
}
break;
case 4:
switch (pfc) {
case 4:
return INT8_T;
case 12:
return INT16_T;
case 14:
return INT32_T;
}
break;
case 5:
switch (pfc) {
case 1:
return FLOAT;
case 2:
return DOUBLE;
}
break;
}
return UNKNOWN_TYPE;
}
#include "../globalfunctions/Type.h"
#include "../serialize/SerializeAdapter.h"
Type::Type() :
actualType(UNKNOWN_TYPE) {
}
Type::Type(ActualType_t actualType) :
actualType(actualType) {
}
Type::Type(const Type& type) :
actualType(type.actualType) {
}
Type& Type::operator =(Type rhs) {
this->actualType = rhs.actualType;
return *this;
}
Type& Type::operator =(ActualType_t actualType) {
this->actualType = actualType;
return *this;
}
Type::operator Type::ActualType_t() const {
return actualType;
}
bool Type::operator ==(const Type& rhs) {
return this->actualType == rhs.actualType;
}
bool Type::operator !=(const Type& rhs) {
return !operator==(rhs);
}
uint8_t Type::getSize() const {
switch (actualType) {
case UINT8_T:
return sizeof(uint8_t);
case INT8_T:
return sizeof(int8_t);
case UINT16_T:
return sizeof(uint16_t);
case INT16_T:
return sizeof(int16_t);
case UINT32_T:
return sizeof(uint32_t);
case INT32_T:
return sizeof(int32_t);
case FLOAT:
return sizeof(float);
case DOUBLE:
return sizeof(double);
default:
return 0;
}
}
ReturnValue_t Type::serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
uint8_t ptc;
uint8_t pfc;
ReturnValue_t result = getPtcPfc(&ptc, &pfc);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&ptc, buffer, size, maxSize,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&pfc, buffer, size, maxSize,
streamEndianness);
return result;
}
size_t Type::getSerializedSize() const {
uint8_t dontcare = 0;
return 2 * SerializeAdapter::getSerializedSize(&dontcare);
}
ReturnValue_t Type::deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
uint8_t ptc;
uint8_t pfc;
ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer,
size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&pfc, buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
actualType = getActualType(ptc, pfc);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Type::getPtcPfc(uint8_t* ptc, uint8_t* pfc) const {
switch (actualType) {
case UINT8_T:
*ptc = 3;
*pfc = 4;
break;
case INT8_T:
*ptc = 4;
*pfc = 4;
break;
case UINT16_T:
*ptc = 3;
*pfc = 12;
break;
case INT16_T:
*ptc = 4;
*pfc = 12;
break;
case UINT32_T:
*ptc = 3;
*pfc = 14;
break;
case INT32_T:
*ptc = 4;
*pfc = 14;
break;
case FLOAT:
*ptc = 5;
*pfc = 1;
break;
case DOUBLE:
*ptc = 5;
*pfc = 2;
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
Type::ActualType_t Type::getActualType(uint8_t ptc, uint8_t pfc) {
switch (ptc) {
case 3:
switch (pfc) {
case 4:
return UINT8_T;
case 12:
return UINT16_T;
case 14:
return UINT32_T;
}
break;
case 4:
switch (pfc) {
case 4:
return INT8_T;
case 12:
return INT16_T;
case 14:
return INT32_T;
}
break;
case 5:
switch (pfc) {
case 1:
return FLOAT;
case 2:
return DOUBLE;
}
break;
}
return UNKNOWN_TYPE;
}

View File

@ -1,94 +1,94 @@
#ifndef TYPE_H_
#define TYPE_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../serialize/SerializeIF.h"
/**
* @brief Type definition for CCSDS or ECSS.
*/
class Type: public SerializeIF {
public:
enum ActualType_t {
UINT8_T,
INT8_T,
UINT16_T,
INT16_T,
UINT32_T,
INT32_T,
FLOAT,
DOUBLE,
UNKNOWN_TYPE
};
Type();
Type(ActualType_t actualType);
Type(const Type &type);
Type& operator=(Type rhs);
Type& operator=(ActualType_t actualType);
operator ActualType_t() const;
bool operator==(const Type &rhs);
bool operator!=(const Type &rhs);
uint8_t getSize() const;
ReturnValue_t getPtcPfc(uint8_t *ptc, uint8_t *pfc) const;
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
size_t maxSize, Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
private:
ActualType_t actualType;
};
template<typename T>
struct PodTypeConversion {
static const Type::ActualType_t type = Type::UNKNOWN_TYPE;
};
template<>
struct PodTypeConversion<uint8_t> {
static const Type::ActualType_t type = Type::UINT8_T;
};
template<>
struct PodTypeConversion<uint16_t> {
static const Type::ActualType_t type = Type::UINT16_T;
};
template<>
struct PodTypeConversion<uint32_t> {
static const Type::ActualType_t type = Type::UINT32_T;
};
template<>
struct PodTypeConversion<int8_t> {
static const Type::ActualType_t type = Type::INT8_T;
};
template<>
struct PodTypeConversion<int16_t> {
static const Type::ActualType_t type = Type::INT16_T;
};
template<>
struct PodTypeConversion<int32_t> {
static const Type::ActualType_t type = Type::INT32_T;
};
template<>
struct PodTypeConversion<float> {
static const Type::ActualType_t type = Type::FLOAT;
};
template<>
struct PodTypeConversion<double> {
static const Type::ActualType_t type = Type::DOUBLE;
};
#endif /* TYPE_H_ */
#ifndef TYPE_H_
#define TYPE_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../serialize/SerializeIF.h"
/**
* @brief Type definition for CCSDS or ECSS.
*/
class Type: public SerializeIF {
public:
enum ActualType_t {
UINT8_T,
INT8_T,
UINT16_T,
INT16_T,
UINT32_T,
INT32_T,
FLOAT,
DOUBLE,
UNKNOWN_TYPE
};
Type();
Type(ActualType_t actualType);
Type(const Type &type);
Type& operator=(Type rhs);
Type& operator=(ActualType_t actualType);
operator ActualType_t() const;
bool operator==(const Type &rhs);
bool operator!=(const Type &rhs);
uint8_t getSize() const;
ReturnValue_t getPtcPfc(uint8_t *ptc, uint8_t *pfc) const;
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
size_t maxSize, Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
private:
ActualType_t actualType;
};
template<typename T>
struct PodTypeConversion {
static const Type::ActualType_t type = Type::UNKNOWN_TYPE;
};
template<>
struct PodTypeConversion<uint8_t> {
static const Type::ActualType_t type = Type::UINT8_T;
};
template<>
struct PodTypeConversion<uint16_t> {
static const Type::ActualType_t type = Type::UINT16_T;
};
template<>
struct PodTypeConversion<uint32_t> {
static const Type::ActualType_t type = Type::UINT32_T;
};
template<>
struct PodTypeConversion<int8_t> {
static const Type::ActualType_t type = Type::INT8_T;
};
template<>
struct PodTypeConversion<int16_t> {
static const Type::ActualType_t type = Type::INT16_T;
};
template<>
struct PodTypeConversion<int32_t> {
static const Type::ActualType_t type = Type::INT32_T;
};
template<>
struct PodTypeConversion<float> {
static const Type::ActualType_t type = Type::FLOAT;
};
template<>
struct PodTypeConversion<double> {
static const Type::ActualType_t type = Type::DOUBLE;
};
#endif /* TYPE_H_ */

View File

@ -1,61 +1,61 @@
#include "../globalfunctions/arrayprinter.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include <bitset>
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
bool printInfo, size_t maxCharPerLine) {
if(printInfo) {
sif::info << "Printing data with size " << size << ": ";
}
sif::info << "[";
if(type == OutputType::HEX) {
arrayprinter::printHex(data, size, maxCharPerLine);
}
else if (type == OutputType::DEC) {
arrayprinter::printDec(data, size, maxCharPerLine);
}
else if(type == OutputType::BIN) {
arrayprinter::printBin(data, size);
}
}
void arrayprinter::printHex(const uint8_t *data, size_t size,
size_t maxCharPerLine) {
sif::info << std::hex;
for(size_t i = 0; i < size; i++) {
sif::info << "0x" << static_cast<int>(data[i]);
if(i < size - 1){
sif::info << " , ";
if(i > 0 and i % maxCharPerLine == 0) {
sif::info << "\r\n" << std::flush;
}
}
}
sif::info << std::dec;
sif::info << "]" << std::endl;
}
void arrayprinter::printDec(const uint8_t *data, size_t size,
size_t maxCharPerLine) {
sif::info << std::dec;
for(size_t i = 0; i < size; i++) {
sif::info << static_cast<int>(data[i]);
if(i < size - 1){
sif::info << " , ";
if(i > 0 and i % maxCharPerLine == 0) {
sif::info << std::endl;
}
}
}
sif::info << "]" << std::endl;
}
void arrayprinter::printBin(const uint8_t *data, size_t size) {
sif::info << "\n" << std::flush;
for(size_t i = 0; i < size; i++) {
sif::info << "Byte " << i + 1 << ": 0b"<<
std::bitset<8>(data[i]) << ",\n" << std::flush;
}
sif::info << "]" << std::endl;
}
#include "../globalfunctions/arrayprinter.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include <bitset>
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
bool printInfo, size_t maxCharPerLine) {
if(printInfo) {
sif::info << "Printing data with size " << size << ": ";
}
sif::info << "[";
if(type == OutputType::HEX) {
arrayprinter::printHex(data, size, maxCharPerLine);
}
else if (type == OutputType::DEC) {
arrayprinter::printDec(data, size, maxCharPerLine);
}
else if(type == OutputType::BIN) {
arrayprinter::printBin(data, size);
}
}
void arrayprinter::printHex(const uint8_t *data, size_t size,
size_t maxCharPerLine) {
sif::info << std::hex;
for(size_t i = 0; i < size; i++) {
sif::info << "0x" << static_cast<int>(data[i]);
if(i < size - 1){
sif::info << " , ";
if(i > 0 and i % maxCharPerLine == 0) {
sif::info << "\r\n" << std::flush;
}
}
}
sif::info << std::dec;
sif::info << "]" << std::endl;
}
void arrayprinter::printDec(const uint8_t *data, size_t size,
size_t maxCharPerLine) {
sif::info << std::dec;
for(size_t i = 0; i < size; i++) {
sif::info << static_cast<int>(data[i]);
if(i < size - 1){
sif::info << " , ";
if(i > 0 and i % maxCharPerLine == 0) {
sif::info << std::endl;
}
}
}
sif::info << "]" << std::endl;
}
void arrayprinter::printBin(const uint8_t *data, size_t size) {
sif::info << "\n" << std::flush;
for(size_t i = 0; i < size; i++) {
sif::info << "Byte " << i + 1 << ": 0b"<<
std::bitset<8>(data[i]) << ",\n" << std::flush;
}
sif::info << "]" << std::endl;
}

View File

@ -1,41 +1,41 @@
#ifndef BINARYMATCHER_H_
#define BINARYMATCHER_H_
#include "../../globalfunctions/matching/MatcherIF.h"
template<typename T>
class BinaryMatcher: public MatcherIF<T> {
public:
bool inverted;
T mask, matchField;
BinaryMatcher() :
inverted(false), mask(0), matchField(0) {
}
BinaryMatcher(T mask, T match, bool inverted = false) :
inverted(inverted), mask(mask), matchField(match) {
}
bool match(T input) {
if (inverted) {
return ~doMatch(input, mask, matchField);
} else {
return doMatch(input, mask, matchField);
}
}
protected:
bool doMatch(T input, T mask, T match) {
match = match & mask;
input = input & mask;
if (input == match) {
return true;
} else {
return false;
}
}
};
#endif /* BINARYMATCHER_H_ */
#ifndef BINARYMATCHER_H_
#define BINARYMATCHER_H_
#include "../../globalfunctions/matching/MatcherIF.h"
template<typename T>
class BinaryMatcher: public MatcherIF<T> {
public:
bool inverted;
T mask, matchField;
BinaryMatcher() :
inverted(false), mask(0), matchField(0) {
}
BinaryMatcher(T mask, T match, bool inverted = false) :
inverted(inverted), mask(mask), matchField(match) {
}
bool match(T input) {
if (inverted) {
return ~doMatch(input, mask, matchField);
} else {
return doMatch(input, mask, matchField);
}
}
protected:
bool doMatch(T input, T mask, T match) {
match = match & mask;
input = input & mask;
if (input == match) {
return true;
} else {
return false;
}
}
};
#endif /* BINARYMATCHER_H_ */

View File

@ -1,50 +1,50 @@
#ifndef DECIMALMATCHER_H_
#define DECIMALMATCHER_H_
#include "../../globalfunctions/matching/MatcherIF.h"
template<typename T>
class DecimalMatcher: public MatcherIF<T> {
public:
bool inverted;
T mask, matchField;
DecimalMatcher() :
inverted(false), mask(0), matchField(0) {
}
DecimalMatcher(T mask, T match, bool inverted = false) :
inverted(inverted), mask(mask), matchField(match) {
}
bool match(T input) {
if (inverted) {
return ~doMatch(input, mask, matchField);
} else {
return doMatch(input, mask, matchField);
}
}
protected:
bool doMatch(T input, T mask, T match) {
T decimal = 1, remainderMask, remainderMatch, remainderInput;
while (mask != 0) {
remainderMask = mask % (decimal * 10);
remainderMatch = match % (decimal * 10);
remainderInput = input % (decimal * 10);
if (remainderMask != 0) {
if (remainderMatch != remainderInput) {
return false;
}
}
mask -= remainderMask;
match -= remainderMatch;
input -= remainderInput;
decimal *= 10;
}
return true;
}
};
#endif /* DECIMALMATCHER_H_ */
#ifndef DECIMALMATCHER_H_
#define DECIMALMATCHER_H_
#include "../../globalfunctions/matching/MatcherIF.h"
template<typename T>
class DecimalMatcher: public MatcherIF<T> {
public:
bool inverted;
T mask, matchField;
DecimalMatcher() :
inverted(false), mask(0), matchField(0) {
}
DecimalMatcher(T mask, T match, bool inverted = false) :
inverted(inverted), mask(mask), matchField(match) {
}
bool match(T input) {
if (inverted) {
return ~doMatch(input, mask, matchField);
} else {
return doMatch(input, mask, matchField);
}
}
protected:
bool doMatch(T input, T mask, T match) {
T decimal = 1, remainderMask, remainderMatch, remainderInput;
while (mask != 0) {
remainderMask = mask % (decimal * 10);
remainderMatch = match % (decimal * 10);
remainderInput = input % (decimal * 10);
if (remainderMask != 0) {
if (remainderMatch != remainderInput) {
return false;
}
}
mask -= remainderMask;
match -= remainderMatch;
input -= remainderInput;
decimal *= 10;
}
return true;
}
};
#endif /* DECIMALMATCHER_H_ */

View File

@ -1,216 +1,216 @@
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
#include "../../container/BinaryTree.h"
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
template<typename T>
class MatchTree: public SerializeableMatcherIF<T>, public BinaryTree<
SerializeableMatcherIF<T>> {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::MATCH_TREE_CLASS;
static const ReturnValue_t TOO_DETAILED_REQUEST = MAKE_RETURN_CODE(1);
static const ReturnValue_t TOO_GENERAL_REQUEST = MAKE_RETURN_CODE(2);
static const ReturnValue_t NO_MATCH = MAKE_RETURN_CODE(3);
static const ReturnValue_t FULL = MAKE_RETURN_CODE(4);
static const ReturnValue_t NEW_NODE_CREATED = MAKE_RETURN_CODE(5);
typedef typename BinaryTree<SerializeableMatcherIF<T>>::iterator iterator;
typedef BinaryNode<SerializeableMatcherIF<T>> Node;
static const bool AND = true; //LEFT
static const bool OR = false; //RIGHT
MatchTree(BinaryNode<SerializeableMatcherIF<T>>* root,
uint8_t maxDepth = -1) :
BinaryTree<SerializeableMatcherIF<T>>(root), maxDepth(maxDepth) {
}
MatchTree(iterator root, uint8_t maxDepth = -1) :
BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(
maxDepth) {
}
MatchTree() :
BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {
}
virtual ~MatchTree() {
}
virtual bool match(T number) {
return matchesTree(number);
}
bool matchesTree(T number) {
iterator iter = this->begin();
if (iter == this->end()) {
return false;
}
return matchSubtree(iter, number);
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, SerializeIF::Endianness streamEndianness) const override {
iterator iter = this->begin();
uint8_t count = this->countRight(iter);
ReturnValue_t result = SerializeAdapter::serialize(&count,
buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (iter == this->end()) {
return HasReturnvaluesIF::RETURN_OK;
}
result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, maxSize, streamEndianness);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
iter = iter.right();
while (iter != this->end()) {
result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, maxSize, streamEndianness);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
iter = iter.right();
}
return result;
}
size_t getSerializedSize() const override {
//Analogous to serialize!
uint32_t size = 1; //One for count
iterator iter = this->begin();
if (iter == this->end()) {
return size;
}
//Count object itself
size += iter->getSerializedSize();
//Handle everything below on AND side
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
size += temp.getSerializedSize();
}
//Handle everything on OR side
iter = iter.right();
//Iterate over every object on the OR branch
while (iter != this->end()) {
size += iter->getSerializedSize();
if (maxDepth > 0) {
//If we are allowed to go deeper, handle AND elements.
MatchTree<T> temp(iter.left(), maxDepth - 1);
size += temp.getSerializedSize();
}
iter = iter.right();
}
return size;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override {
return HasReturnvaluesIF::RETURN_OK;
}
protected:
bool isOnAndBranch(iterator position) {
if ((position == this->end()) || (position.up() == this->end())) {
return false;
}
if (position.up().left() == position) {
return true;
} else {
return false;
}
}
//SHOULDDO: What to do if insertion/deletion fails. Throw event?
ReturnValue_t removeElementAndAllChildren(iterator position) {
auto children = this->erase(position);
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (children.first != this->end()) {
result = removeElementAndAllChildren(children.first);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (children.second != this->end()) {
result = removeElementAndAllChildren(children.second);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
//Delete element itself.
return cleanUpElement(position);
}
ReturnValue_t removeElementAndReconnectChildren(iterator position) {
if (position == this->end()) {
return HasReturnvaluesIF::RETURN_OK;
}
//Delete everything from the AND branch.
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (position.left() != this->end()) {
result = removeElementAndAllChildren(position.left());
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
if (position.right() != this->end()) {
//There's something at the OR branch, reconnect to parent.
if (isOnAndBranch(position)) {
//Either one hierarchy up AND branch...
this->insert(AND, position.up(), position.right().element);
} else {
//or on another OR'ed element (or install new root node).
this->insert(OR, position.up(), position.right().element);
}
} else {
if (isOnAndBranch(position)) {
//Recursively delete parent node as well, because it is not expected to be there anymore.
return removeElementAndReconnectChildren(position.up());
} else {
//simply delete self.
this->erase(position);
}
}
//Delete element itself.
return cleanUpElement(position);
}
virtual ReturnValue_t cleanUpElement(iterator position) {
return HasReturnvaluesIF::RETURN_OK;
}
bool matchSubtree(iterator iter, T number) {
bool isMatch = iter->match(number);
if (isMatch) {
if (iter.left() == this->end()) {
return true;
}
isMatch = matchSubtree(iter.left(), number);
if (isMatch) {
return true;
}
}
if (iter.right() == this->end()) {
return false;
}
return matchSubtree(iter.right(), number);
}
private:
uint8_t maxDepth;
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_ */
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
#include "../../container/BinaryTree.h"
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
template<typename T>
class MatchTree: public SerializeableMatcherIF<T>, public BinaryTree<
SerializeableMatcherIF<T>> {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::MATCH_TREE_CLASS;
static const ReturnValue_t TOO_DETAILED_REQUEST = MAKE_RETURN_CODE(1);
static const ReturnValue_t TOO_GENERAL_REQUEST = MAKE_RETURN_CODE(2);
static const ReturnValue_t NO_MATCH = MAKE_RETURN_CODE(3);
static const ReturnValue_t FULL = MAKE_RETURN_CODE(4);
static const ReturnValue_t NEW_NODE_CREATED = MAKE_RETURN_CODE(5);
typedef typename BinaryTree<SerializeableMatcherIF<T>>::iterator iterator;
typedef BinaryNode<SerializeableMatcherIF<T>> Node;
static const bool AND = true; //LEFT
static const bool OR = false; //RIGHT
MatchTree(BinaryNode<SerializeableMatcherIF<T>>* root,
uint8_t maxDepth = -1) :
BinaryTree<SerializeableMatcherIF<T>>(root), maxDepth(maxDepth) {
}
MatchTree(iterator root, uint8_t maxDepth = -1) :
BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(
maxDepth) {
}
MatchTree() :
BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {
}
virtual ~MatchTree() {
}
virtual bool match(T number) {
return matchesTree(number);
}
bool matchesTree(T number) {
iterator iter = this->begin();
if (iter == this->end()) {
return false;
}
return matchSubtree(iter, number);
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, SerializeIF::Endianness streamEndianness) const override {
iterator iter = this->begin();
uint8_t count = this->countRight(iter);
ReturnValue_t result = SerializeAdapter::serialize(&count,
buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (iter == this->end()) {
return HasReturnvaluesIF::RETURN_OK;
}
result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, maxSize, streamEndianness);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
iter = iter.right();
while (iter != this->end()) {
result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, maxSize, streamEndianness);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
iter = iter.right();
}
return result;
}
size_t getSerializedSize() const override {
//Analogous to serialize!
uint32_t size = 1; //One for count
iterator iter = this->begin();
if (iter == this->end()) {
return size;
}
//Count object itself
size += iter->getSerializedSize();
//Handle everything below on AND side
if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1);
size += temp.getSerializedSize();
}
//Handle everything on OR side
iter = iter.right();
//Iterate over every object on the OR branch
while (iter != this->end()) {
size += iter->getSerializedSize();
if (maxDepth > 0) {
//If we are allowed to go deeper, handle AND elements.
MatchTree<T> temp(iter.left(), maxDepth - 1);
size += temp.getSerializedSize();
}
iter = iter.right();
}
return size;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override {
return HasReturnvaluesIF::RETURN_OK;
}
protected:
bool isOnAndBranch(iterator position) {
if ((position == this->end()) || (position.up() == this->end())) {
return false;
}
if (position.up().left() == position) {
return true;
} else {
return false;
}
}
//SHOULDDO: What to do if insertion/deletion fails. Throw event?
ReturnValue_t removeElementAndAllChildren(iterator position) {
auto children = this->erase(position);
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (children.first != this->end()) {
result = removeElementAndAllChildren(children.first);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (children.second != this->end()) {
result = removeElementAndAllChildren(children.second);
}
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
//Delete element itself.
return cleanUpElement(position);
}
ReturnValue_t removeElementAndReconnectChildren(iterator position) {
if (position == this->end()) {
return HasReturnvaluesIF::RETURN_OK;
}
//Delete everything from the AND branch.
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (position.left() != this->end()) {
result = removeElementAndAllChildren(position.left());
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
if (position.right() != this->end()) {
//There's something at the OR branch, reconnect to parent.
if (isOnAndBranch(position)) {
//Either one hierarchy up AND branch...
this->insert(AND, position.up(), position.right().element);
} else {
//or on another OR'ed element (or install new root node).
this->insert(OR, position.up(), position.right().element);
}
} else {
if (isOnAndBranch(position)) {
//Recursively delete parent node as well, because it is not expected to be there anymore.
return removeElementAndReconnectChildren(position.up());
} else {
//simply delete self.
this->erase(position);
}
}
//Delete element itself.
return cleanUpElement(position);
}
virtual ReturnValue_t cleanUpElement(iterator position) {
return HasReturnvaluesIF::RETURN_OK;
}
bool matchSubtree(iterator iter, T number) {
bool isMatch = iter->match(number);
if (isMatch) {
if (iter.left() == this->end()) {
return true;
}
isMatch = matchSubtree(iter.left(), number);
if (isMatch) {
return true;
}
}
if (iter.right() == this->end()) {
return false;
}
return matchSubtree(iter.right(), number);
}
private:
uint8_t maxDepth;
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_ */

View File

@ -1,70 +1,70 @@
#ifndef RANGEMATCHER_H_
#define RANGEMATCHER_H_
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
template<typename T>
class RangeMatcher: public SerializeableMatcherIF<T> {
public:
bool inverted;
T lowerBound;
T upperBound;
RangeMatcher() :
inverted(true), lowerBound(1), upperBound(0) {
}
RangeMatcher(T lowerBound, T upperBound, bool inverted = false) :
inverted(inverted), lowerBound(lowerBound), upperBound(upperBound) {
}
bool match(T input) {
if (inverted) {
return !doMatch(input);
} else {
return doMatch(input);
}
}
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override {
ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer,
size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&upperBound, buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SerializeAdapter::serialize(&inverted, buffer, size, maxSize,
streamEndianness);
}
size_t getSerializedSize() const override {
return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool);
}
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
SerializeIF::Endianness streamEndianness) override {
ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound,
buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&upperBound, buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SerializeAdapter::deSerialize(&inverted, buffer, size,
streamEndianness);
}
protected:
bool doMatch(T input) {
return (input >= lowerBound) && (input <= upperBound);
}
};
#endif /* RANGEMATCHER_H_ */
#ifndef RANGEMATCHER_H_
#define RANGEMATCHER_H_
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
template<typename T>
class RangeMatcher: public SerializeableMatcherIF<T> {
public:
bool inverted;
T lowerBound;
T upperBound;
RangeMatcher() :
inverted(true), lowerBound(1), upperBound(0) {
}
RangeMatcher(T lowerBound, T upperBound, bool inverted = false) :
inverted(inverted), lowerBound(lowerBound), upperBound(upperBound) {
}
bool match(T input) {
if (inverted) {
return !doMatch(input);
} else {
return doMatch(input);
}
}
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override {
ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer,
size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::serialize(&upperBound, buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SerializeAdapter::serialize(&inverted, buffer, size, maxSize,
streamEndianness);
}
size_t getSerializedSize() const override {
return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool);
}
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
SerializeIF::Endianness streamEndianness) override {
ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound,
buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = SerializeAdapter::deSerialize(&upperBound, buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SerializeAdapter::deSerialize(&inverted, buffer, size,
streamEndianness);
}
protected:
bool doMatch(T input) {
return (input >= lowerBound) && (input <= upperBound);
}
};
#endif /* RANGEMATCHER_H_ */

View File

@ -1,13 +1,13 @@
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
#include "../../globalfunctions/matching/MatcherIF.h"
#include "../../serialize/SerializeIF.h"
template<typename T>
class SerializeableMatcherIF : public MatcherIF<T>, public SerializeIF {
public:
virtual ~SerializeableMatcherIF() {}
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ */
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
#include "../../globalfunctions/matching/MatcherIF.h"
#include "../../serialize/SerializeIF.h"
template<typename T>
class SerializeableMatcherIF : public MatcherIF<T>, public SerializeIF {
public:
virtual ~SerializeableMatcherIF() {}
};
#endif /* FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_ */

View File

@ -1,156 +1,156 @@
#include "QuaternionOperations.h"
#include "../../globalfunctions/math/VectorOperations.h"
#include <cmath>
#include <cstring>
#include <stdint.h>
QuaternionOperations::~QuaternionOperations() {
}
void QuaternionOperations::multiply(const double* q1, const double* q2,
double* q) {
double out[4];
out[0] = q1[3] * q2[0] + q1[2] * q2[1] - q1[1] * q2[2] + q1[0] * q2[3];
out[1] = -q1[2] * q2[0] + q1[3] * q2[1] + q1[0] * q2[2] + q1[1] * q2[3];
out[2] = q1[1] * q2[0] - q1[0] * q2[1] + q1[3] * q2[2] + q1[2] * q2[3];
out[3] = -q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] + q1[3] * q2[3];
memcpy(q, out, 4 * sizeof(*q));
}
void QuaternionOperations::toDcm(const double* quaternion, double dcm[][3]) {
dcm[0][0] = 2
* (quaternion[0] * quaternion[0] + quaternion[3] * quaternion[3])
- 1;
dcm[0][1] = 2
* (quaternion[0] * quaternion[1] + quaternion[2] * quaternion[3]);
dcm[0][2] = 2
* (quaternion[0] * quaternion[2] - quaternion[1] * quaternion[3]);
dcm[1][0] = 2
* (quaternion[0] * quaternion[1] - quaternion[2] * quaternion[3]);
dcm[1][1] = 2
* (quaternion[1] * quaternion[1] + quaternion[3] * quaternion[3])
- 1;
dcm[1][2] = 2
* (quaternion[1] * quaternion[2] + quaternion[0] * quaternion[3]);
dcm[2][0] = 2
* (quaternion[0] * quaternion[2] + quaternion[1] * quaternion[3]);
dcm[2][1] = 2
* (quaternion[1] * quaternion[2] - quaternion[0] * quaternion[3]);
dcm[2][2] = 2
* (quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3])
- 1;
}
void QuaternionOperations::inverse(const double* quaternion,
double* inverseQuaternion) {
memcpy(inverseQuaternion, quaternion, 4 * sizeof(*quaternion));
VectorOperations<double>::mulScalar(inverseQuaternion, -1,
inverseQuaternion, 3);
}
QuaternionOperations::QuaternionOperations() {
}
void QuaternionOperations::normalize(const double* quaternion,
double* unitQuaternion) {
VectorOperations<double>::normalize(quaternion, unitQuaternion, 4);
}
float QuaternionOperations::norm(const double* quaternion) {
return VectorOperations<double>::norm(quaternion, 4);
}
void QuaternionOperations::fromDcm(const double dcm[][3], double* quaternion,
uint8_t *index) {
double a[4];
a[0] = 1 + dcm[0][0] - dcm[1][1] - dcm[2][2];
a[1] = 1 - dcm[0][0] + dcm[1][1] - dcm[2][2];
a[2] = 1 - dcm[0][0] - dcm[1][1] + dcm[2][2];
a[3] = 1 + dcm[0][0] + dcm[1][1] + dcm[2][2];
uint8_t maxAIndex = 0;
VectorOperations<double>::maxValue(a, 4, &maxAIndex);
if (index != 0) {
*index = maxAIndex;
}
switch (maxAIndex) {
case 0:
quaternion[0] = 0.5 * sqrt(a[0]);
quaternion[1] = (dcm[0][1] + dcm[1][0]) / (2 * sqrt(a[0]));
quaternion[2] = (dcm[0][2] + dcm[2][0]) / (2 * sqrt(a[0]));
quaternion[3] = (dcm[1][2] - dcm[2][1]) / (2 * sqrt(a[0]));
break;
case 1:
quaternion[0] = (dcm[0][1] + dcm[1][0]) / (2 * sqrt(a[1]));
quaternion[1] = 0.5 * sqrt(a[1]);
quaternion[2] = (dcm[1][2] + dcm[2][1]) / (2 * sqrt(a[1]));
quaternion[3] = (dcm[2][0] - dcm[0][2]) / (2 * sqrt(a[1]));
break;
case 2:
quaternion[0] = (dcm[0][2] + dcm[2][0]) / (2 * sqrt(a[2]));
quaternion[1] = (dcm[1][2] + dcm[2][1]) / (2 * sqrt(a[2]));
quaternion[2] = 0.5 * sqrt(a[2]);
quaternion[3] = (dcm[0][1] - dcm[1][0]) / (2 * sqrt(a[2]));
break;
case 3:
quaternion[0] = (dcm[1][2] - dcm[2][1]) / (2 * sqrt(a[3]));
quaternion[1] = (dcm[2][0] - dcm[0][2]) / (2 * sqrt(a[3]));
quaternion[2] = (dcm[0][1] - dcm[1][0]) / (2 * sqrt(a[3]));
quaternion[3] = 0.5 * sqrt(a[3]);
break;
}
}
void QuaternionOperations::toDcm(const double* quaternion, float dcm[][3]) {
dcm[0][0] = 2
* (quaternion[0] * quaternion[0] + quaternion[3] * quaternion[3])
- 1;
dcm[0][1] = 2
* (quaternion[0] * quaternion[1] + quaternion[2] * quaternion[3]);
dcm[0][2] = 2
* (quaternion[0] * quaternion[2] - quaternion[1] * quaternion[3]);
dcm[1][0] = 2
* (quaternion[0] * quaternion[1] - quaternion[2] * quaternion[3]);
dcm[1][1] = 2
* (quaternion[1] * quaternion[1] + quaternion[3] * quaternion[3])
- 1;
dcm[1][2] = 2
* (quaternion[1] * quaternion[2] + quaternion[0] * quaternion[3]);
dcm[2][0] = 2
* (quaternion[0] * quaternion[2] + quaternion[1] * quaternion[3]);
dcm[2][1] = 2
* (quaternion[1] * quaternion[2] - quaternion[0] * quaternion[3]);
dcm[2][2] = 2
* (quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3])
- 1;
}
void QuaternionOperations::normalize(double* quaternion) {
normalize(quaternion, quaternion);
}
double QuaternionOperations::getAngle(const double* quaternion, bool abs) {
if (quaternion[3] >= 0) {
return 2 * acos(quaternion[3]);
} else {
if (abs) {
return 2 * acos(-quaternion[3]);
} else {
return -2 * acos(-quaternion[3]);
}
}
}
#include "QuaternionOperations.h"
#include "../../globalfunctions/math/VectorOperations.h"
#include <cmath>
#include <cstring>
#include <stdint.h>
QuaternionOperations::~QuaternionOperations() {
}
void QuaternionOperations::multiply(const double* q1, const double* q2,
double* q) {
double out[4];
out[0] = q1[3] * q2[0] + q1[2] * q2[1] - q1[1] * q2[2] + q1[0] * q2[3];
out[1] = -q1[2] * q2[0] + q1[3] * q2[1] + q1[0] * q2[2] + q1[1] * q2[3];
out[2] = q1[1] * q2[0] - q1[0] * q2[1] + q1[3] * q2[2] + q1[2] * q2[3];
out[3] = -q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] + q1[3] * q2[3];
memcpy(q, out, 4 * sizeof(*q));
}
void QuaternionOperations::toDcm(const double* quaternion, double dcm[][3]) {
dcm[0][0] = 2
* (quaternion[0] * quaternion[0] + quaternion[3] * quaternion[3])
- 1;
dcm[0][1] = 2
* (quaternion[0] * quaternion[1] + quaternion[2] * quaternion[3]);
dcm[0][2] = 2
* (quaternion[0] * quaternion[2] - quaternion[1] * quaternion[3]);
dcm[1][0] = 2
* (quaternion[0] * quaternion[1] - quaternion[2] * quaternion[3]);
dcm[1][1] = 2
* (quaternion[1] * quaternion[1] + quaternion[3] * quaternion[3])
- 1;
dcm[1][2] = 2
* (quaternion[1] * quaternion[2] + quaternion[0] * quaternion[3]);
dcm[2][0] = 2
* (quaternion[0] * quaternion[2] + quaternion[1] * quaternion[3]);
dcm[2][1] = 2
* (quaternion[1] * quaternion[2] - quaternion[0] * quaternion[3]);
dcm[2][2] = 2
* (quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3])
- 1;
}
void QuaternionOperations::inverse(const double* quaternion,
double* inverseQuaternion) {
memcpy(inverseQuaternion, quaternion, 4 * sizeof(*quaternion));
VectorOperations<double>::mulScalar(inverseQuaternion, -1,
inverseQuaternion, 3);
}
QuaternionOperations::QuaternionOperations() {
}
void QuaternionOperations::normalize(const double* quaternion,
double* unitQuaternion) {
VectorOperations<double>::normalize(quaternion, unitQuaternion, 4);
}
float QuaternionOperations::norm(const double* quaternion) {
return VectorOperations<double>::norm(quaternion, 4);
}
void QuaternionOperations::fromDcm(const double dcm[][3], double* quaternion,
uint8_t *index) {
double a[4];
a[0] = 1 + dcm[0][0] - dcm[1][1] - dcm[2][2];
a[1] = 1 - dcm[0][0] + dcm[1][1] - dcm[2][2];
a[2] = 1 - dcm[0][0] - dcm[1][1] + dcm[2][2];
a[3] = 1 + dcm[0][0] + dcm[1][1] + dcm[2][2];
uint8_t maxAIndex = 0;
VectorOperations<double>::maxValue(a, 4, &maxAIndex);
if (index != 0) {
*index = maxAIndex;
}
switch (maxAIndex) {
case 0:
quaternion[0] = 0.5 * sqrt(a[0]);
quaternion[1] = (dcm[0][1] + dcm[1][0]) / (2 * sqrt(a[0]));
quaternion[2] = (dcm[0][2] + dcm[2][0]) / (2 * sqrt(a[0]));
quaternion[3] = (dcm[1][2] - dcm[2][1]) / (2 * sqrt(a[0]));
break;
case 1:
quaternion[0] = (dcm[0][1] + dcm[1][0]) / (2 * sqrt(a[1]));
quaternion[1] = 0.5 * sqrt(a[1]);
quaternion[2] = (dcm[1][2] + dcm[2][1]) / (2 * sqrt(a[1]));
quaternion[3] = (dcm[2][0] - dcm[0][2]) / (2 * sqrt(a[1]));
break;
case 2:
quaternion[0] = (dcm[0][2] + dcm[2][0]) / (2 * sqrt(a[2]));
quaternion[1] = (dcm[1][2] + dcm[2][1]) / (2 * sqrt(a[2]));
quaternion[2] = 0.5 * sqrt(a[2]);
quaternion[3] = (dcm[0][1] - dcm[1][0]) / (2 * sqrt(a[2]));
break;
case 3:
quaternion[0] = (dcm[1][2] - dcm[2][1]) / (2 * sqrt(a[3]));
quaternion[1] = (dcm[2][0] - dcm[0][2]) / (2 * sqrt(a[3]));
quaternion[2] = (dcm[0][1] - dcm[1][0]) / (2 * sqrt(a[3]));
quaternion[3] = 0.5 * sqrt(a[3]);
break;
}
}
void QuaternionOperations::toDcm(const double* quaternion, float dcm[][3]) {
dcm[0][0] = 2
* (quaternion[0] * quaternion[0] + quaternion[3] * quaternion[3])
- 1;
dcm[0][1] = 2
* (quaternion[0] * quaternion[1] + quaternion[2] * quaternion[3]);
dcm[0][2] = 2
* (quaternion[0] * quaternion[2] - quaternion[1] * quaternion[3]);
dcm[1][0] = 2
* (quaternion[0] * quaternion[1] - quaternion[2] * quaternion[3]);
dcm[1][1] = 2
* (quaternion[1] * quaternion[1] + quaternion[3] * quaternion[3])
- 1;
dcm[1][2] = 2
* (quaternion[1] * quaternion[2] + quaternion[0] * quaternion[3]);
dcm[2][0] = 2
* (quaternion[0] * quaternion[2] + quaternion[1] * quaternion[3]);
dcm[2][1] = 2
* (quaternion[1] * quaternion[2] - quaternion[0] * quaternion[3]);
dcm[2][2] = 2
* (quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3])
- 1;
}
void QuaternionOperations::normalize(double* quaternion) {
normalize(quaternion, quaternion);
}
double QuaternionOperations::getAngle(const double* quaternion, bool abs) {
if (quaternion[3] >= 0) {
return 2 * acos(quaternion[3]);
} else {
if (abs) {
return 2 * acos(-quaternion[3]);
} else {
return -2 * acos(-quaternion[3]);
}
}
}

View File

@ -1,99 +1,99 @@
#include "timevalOperations.h"
timeval& operator+=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum += rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator+(timeval lhs, const timeval& rhs) {
lhs += rhs;
return lhs;
}
timeval& operator-=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum -= rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator-(timeval lhs, const timeval& rhs) {
lhs -= rhs;
return lhs;
}
double operator/(const timeval& lhs, const timeval& rhs) {
double lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
double rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 / rhs64;
}
timeval& operator/=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product /= scalar;
lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator/(timeval lhs, double scalar) {
lhs /= scalar;
return lhs;
}
timeval& operator*=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product *= scalar;
lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator*(timeval lhs, double scalar) {
lhs *= scalar;
return lhs;
}
timeval operator*(double scalar, timeval rhs) {
rhs *= scalar;
return rhs;
}
bool operator==(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 == rhs64;
}
bool operator!=(const timeval& lhs, const timeval& rhs) {
return !operator==(lhs, rhs);
}
bool operator<(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 < rhs64;
}
bool operator>(const timeval& lhs, const timeval& rhs) {
return operator<(rhs, lhs);
}
bool operator<=(const timeval& lhs, const timeval& rhs) {
return !operator>(lhs, rhs);
}
bool operator>=(const timeval& lhs, const timeval& rhs) {
return !operator<(lhs, rhs);
}
double timevalOperations::toDouble(const timeval timeval) {
double result = timeval.tv_sec * 1000000. + timeval.tv_usec;
return result / 1000000.;
}
timeval timevalOperations::toTimeval(const double seconds) {
timeval tval;
tval.tv_sec = seconds;
tval.tv_usec = seconds *(double) 1e6 - (tval.tv_sec *1e6);
return tval;
}
#include "timevalOperations.h"
timeval& operator+=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum += rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator+(timeval lhs, const timeval& rhs) {
lhs += rhs;
return lhs;
}
timeval& operator-=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum -= rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator-(timeval lhs, const timeval& rhs) {
lhs -= rhs;
return lhs;
}
double operator/(const timeval& lhs, const timeval& rhs) {
double lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
double rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 / rhs64;
}
timeval& operator/=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product /= scalar;
lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator/(timeval lhs, double scalar) {
lhs /= scalar;
return lhs;
}
timeval& operator*=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product *= scalar;
lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs;
}
timeval operator*(timeval lhs, double scalar) {
lhs *= scalar;
return lhs;
}
timeval operator*(double scalar, timeval rhs) {
rhs *= scalar;
return rhs;
}
bool operator==(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 == rhs64;
}
bool operator!=(const timeval& lhs, const timeval& rhs) {
return !operator==(lhs, rhs);
}
bool operator<(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 < rhs64;
}
bool operator>(const timeval& lhs, const timeval& rhs) {
return operator<(rhs, lhs);
}
bool operator<=(const timeval& lhs, const timeval& rhs) {
return !operator>(lhs, rhs);
}
bool operator>=(const timeval& lhs, const timeval& rhs) {
return !operator<(lhs, rhs);
}
double timevalOperations::toDouble(const timeval timeval) {
double result = timeval.tv_sec * 1000000. + timeval.tv_usec;
return result / 1000000.;
}
timeval timevalOperations::toTimeval(const double seconds) {
timeval tval;
tval.tv_sec = seconds;
tval.tv_usec = seconds *(double) 1e6 - (tval.tv_sec *1e6);
return tval;
}