separated encoder functions as well

This commit is contained in:
Robin Müller 2021-08-18 13:33:00 +02:00
parent 94c2e703e0
commit 026f7f00de
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
2 changed files with 125 additions and 62 deletions

View File

@ -8,76 +8,131 @@ DleEncoder::~DleEncoder() {}
ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream,
size_t sourceLen, uint8_t* destStream, size_t maxDestLen, size_t sourceLen, uint8_t* destStream, size_t maxDestLen,
size_t* encodedLen, bool addStxEtx) { size_t* encodedLen, bool addStxEtx) {
if (maxDestLen < 2) { size_t minAllowedLen = 0;
return STREAM_TOO_SHORT; if(escapeStxEtx) {
} minAllowedLen = 2;
size_t encodedIndex = 0, sourceIndex = 0;
uint8_t nextByte; }
else {
minAllowedLen = 1;
}
if(maxDestLen < minAllowedLen) {
return STREAM_TOO_SHORT;
}
if (addStxEtx) { if (addStxEtx) {
if(not escapeStxEtx) { if(not escapeStxEtx) {
destStream[0] = DLE_CHAR; destStream[0] = DLE_CHAR;
++encodedIndex;
} }
destStream[0] = STX_CHAR; destStream[0] = STX_CHAR;
++encodedIndex;
} }
while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { if(escapeStxEtx) {
nextByte = sourceStream[sourceIndex]; return encodeStreamEscaped(sourceStream, sourceLen,
// STX, ETX and CR characters in the stream need to be escaped with DLE destStream, maxDestLen, encodedLen, addStxEtx);
if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or }
(this->escapeCr and nextByte == CARRIAGE_RETURN)) { else {
if(this->escapeStxEtx) { return encodeStreamNonEscaped(sourceStream, sourceLen,
if (encodedIndex + 1 >= maxDestLen) { destStream, maxDestLen, encodedLen, addStxEtx);
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) {
if(not escapeStxEtx) { ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_t sourceLen,
destStream[encodedIndex] = DLE_CHAR; uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
++encodedIndex; bool addStxEtx) {
} size_t encodedIndex = 2;
destStream[encodedIndex] = ETX_CHAR; size_t sourceIndex = 0;
++encodedIndex; uint8_t nextByte = 0;
} while (encodedIndex < maxDestLen and sourceIndex < sourceLen) {
*encodedLen = encodedIndex; nextByte = sourceStream[sourceIndex];
return RETURN_OK; // STX, ETX and CR characters in the stream need to be escaped with DLE
} if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or
else { (this->escapeCr and nextByte == CARRIAGE_RETURN)) {
return STREAM_TOO_SHORT; 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::encodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceLen,
uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
bool addStxEtx) {
size_t encodedIndex = 1;
size_t sourceIndex = 0;
uint8_t nextByte = 0;
while (encodedIndex < maxDestLen and sourceIndex < sourceLen) {
nextByte = sourceStream[sourceIndex];
// DLE characters are simply escaped with DLE.
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, ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream,

View File

@ -89,6 +89,14 @@ public:
private: private:
ReturnValue_t encodeStreamEscaped(const uint8_t *sourceStream, size_t sourceLen,
uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
bool addStxEtx = true);
ReturnValue_t encodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceLen,
uint8_t *destStream, size_t maxDestLen, size_t *encodedLen,
bool addStxEtx = true);
ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen,
size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen);