restructure repository
This commit is contained in:
230
src/core/globalfunctions/AsciiConverter.cpp
Normal file
230
src/core/globalfunctions/AsciiConverter.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include "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;
|
||||
}
|
13
src/core/globalfunctions/CMakeLists.txt
Normal file
13
src/core/globalfunctions/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
arrayprinter.cpp
|
||||
AsciiConverter.cpp
|
||||
CRC.cpp
|
||||
DleEncoder.cpp
|
||||
PeriodicOperationDivider.cpp
|
||||
timevalOperations.cpp
|
||||
Type.cpp
|
||||
bitutility.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(math)
|
139
src/core/globalfunctions/CRC.cpp
Normal file
139
src/core/globalfunctions/CRC.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
#include "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() */
|
||||
|
||||
|
124
src/core/globalfunctions/DleEncoder.cpp
Normal file
124
src/core/globalfunctions/DleEncoder.cpp
Normal file
@ -0,0 +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 prevent 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;
|
||||
}
|
||||
}
|
||||
|
44
src/core/globalfunctions/PeriodicOperationDivider.cpp
Normal file
44
src/core/globalfunctions/PeriodicOperationDivider.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "PeriodicOperationDivider.h"
|
||||
|
||||
|
||||
PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
|
||||
bool resetAutomatically): resetAutomatically(resetAutomatically),
|
||||
counter(divider), divider(divider) {
|
||||
}
|
||||
|
||||
bool PeriodicOperationDivider::checkAndIncrement() {
|
||||
bool opNecessary = check();
|
||||
if(opNecessary) {
|
||||
if(resetAutomatically) {
|
||||
counter = 0;
|
||||
}
|
||||
return opNecessary;
|
||||
}
|
||||
counter ++;
|
||||
return opNecessary;
|
||||
}
|
||||
|
||||
bool PeriodicOperationDivider::check() {
|
||||
if(counter >= divider) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PeriodicOperationDivider::resetCounter() {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
void PeriodicOperationDivider::setDivider(uint32_t newDivider) {
|
||||
divider = newDivider;
|
||||
}
|
||||
|
||||
uint32_t PeriodicOperationDivider::getCounter() const {
|
||||
return counter;
|
||||
}
|
||||
|
||||
uint32_t PeriodicOperationDivider::getDivider() const {
|
||||
return divider;
|
||||
}
|
181
src/core/globalfunctions/Type.cpp
Normal file
181
src/core/globalfunctions/Type.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
#include "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;
|
||||
}
|
138
src/core/globalfunctions/arrayprinter.cpp
Normal file
138
src/core/globalfunctions/arrayprinter.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#include "arrayprinter.h"
|
||||
#include "../serviceinterface/ServiceInterface.h"
|
||||
#include <bitset>
|
||||
|
||||
|
||||
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
|
||||
bool printInfo, size_t maxCharPerLine) {
|
||||
if(size == 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Size is zero, nothing to print" << std::endl;
|
||||
#else
|
||||
sif::printInfo("Size is zero, nothing to print\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if(printInfo) {
|
||||
sif::info << "Printing data with size " << size << ": " << std::endl;
|
||||
}
|
||||
#else
|
||||
#if FSFW_NO_C99_IO == 1
|
||||
sif::printInfo("Printing data with size %lu: \n", static_cast<unsigned long>(size));
|
||||
#else
|
||||
sif::printInfo("Printing data with size %zu: \n", size);
|
||||
#endif /* FSFW_NO_C99_IO == 1 */
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
|
||||
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) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if(sif::info.crAdditionEnabled()) {
|
||||
std::cout << "\r" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "[" << std::hex;
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
std::cout << "0x" << static_cast<int>(data[i]);
|
||||
if(i < size - 1) {
|
||||
std::cout << " , ";
|
||||
if(i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::dec;
|
||||
std::cout << "]" << std::endl;
|
||||
#else
|
||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
||||
// plus line break plus small safety margin.
|
||||
char printBuffer[(size + 1) * 7 + 1] = {};
|
||||
size_t currentPos = 0;
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
// To avoid buffer overflows.
|
||||
if(sizeof(printBuffer) - currentPos <= 7) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPos += snprintf(printBuffer + currentPos, 6, "0x%02x", data[i]);
|
||||
if(i < size - 1) {
|
||||
currentPos += sprintf(printBuffer + currentPos, ", ");
|
||||
if(i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
printf("[%s]\n", printBuffer);
|
||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||
#endif
|
||||
}
|
||||
|
||||
void arrayprinter::printDec(const uint8_t *data, size_t size,
|
||||
size_t maxCharPerLine) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if(sif::info.crAdditionEnabled()) {
|
||||
std::cout << "\r" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "[" << std::dec;
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
std::cout << static_cast<int>(data[i]);
|
||||
if(i < size - 1){
|
||||
std::cout << " , ";
|
||||
if(i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
#else
|
||||
// General format: 32, 243, -12 so it is number of chars times 5
|
||||
// plus line break plus small safety margin.
|
||||
char printBuffer[(size + 1) * 5 + 1] = {};
|
||||
size_t currentPos = 0;
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
// To avoid buffer overflows.
|
||||
if(sizeof(printBuffer) - currentPos <= 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPos += snprintf(printBuffer + currentPos, 3, "%d", data[i]);
|
||||
if(i < size - 1) {
|
||||
currentPos += sprintf(printBuffer + currentPos, ", ");
|
||||
if(i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
printf("[%s]\n", printBuffer);
|
||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||
#endif
|
||||
}
|
||||
|
||||
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
sif::info << "Byte " << i + 1 << ": 0b" << std::bitset<8>(data[i]) << std::endl;
|
||||
}
|
||||
#else
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
sif::printInfo("Byte %d: 0b" BYTE_TO_BINARY_PATTERN "\n", i + 1, BYTE_TO_BINARY(data[i]));
|
||||
}
|
||||
#endif
|
||||
}
|
33
src/core/globalfunctions/bitutility.cpp
Normal file
33
src/core/globalfunctions/bitutility.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "bitutility.h"
|
||||
|
||||
void bitutil::bitSet(uint8_t *byte, uint8_t position) {
|
||||
if(position > 7) {
|
||||
return;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
*byte |= 1 << shiftNumber;
|
||||
}
|
||||
|
||||
void bitutil::bitToggle(uint8_t *byte, uint8_t position) {
|
||||
if(position > 7) {
|
||||
return;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
*byte ^= 1 << shiftNumber;
|
||||
}
|
||||
|
||||
void bitutil::bitClear(uint8_t *byte, uint8_t position) {
|
||||
if(position > 7) {
|
||||
return;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
*byte &= ~(1 << shiftNumber);
|
||||
}
|
||||
|
||||
bool bitutil::bitGet(const uint8_t *byte, uint8_t position) {
|
||||
if(position > 7) {
|
||||
return false;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
return *byte & (1 << shiftNumber);
|
||||
}
|
4
src/core/globalfunctions/math/CMakeLists.txt
Normal file
4
src/core/globalfunctions/math/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
QuaternionOperations.cpp
|
||||
)
|
156
src/core/globalfunctions/math/QuaternionOperations.cpp
Normal file
156
src/core/globalfunctions/math/QuaternionOperations.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include "QuaternionOperations.h"
|
||||
#include "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]);
|
||||
}
|
||||
}
|
||||
}
|
99
src/core/globalfunctions/timevalOperations.cpp
Normal file
99
src/core/globalfunctions/timevalOperations.cpp
Normal file
@ -0,0 +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;
|
||||
}
|
Reference in New Issue
Block a user