From 89accf8940913213de1d5e067d42c1b2e09628e6 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 3 Jul 2020 15:46:00 +0200 Subject: [PATCH] Documented EndianConverter and changed length to size_t --- serialize/EndianConverter.h | 57 +++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/serialize/EndianConverter.h b/serialize/EndianConverter.h index e142c2a1..cd5d5497 100644 --- a/serialize/EndianConverter.h +++ b/serialize/EndianConverter.h @@ -5,12 +5,44 @@ #include #include +/** + * Helper class to convert variables or bitstreams between machine + * endian and either big or little endian. + * Machine endian is the endianness used by the machine running the + * program and is one of big or little endian. As this is portable + * code, it is not known at coding time which it is. At compile time + * it is however, which is why this is implemented using compiler + * macros and translates to a copy operation at runtime. + * + * This changes the layout of multi-byte variables in the machine's + * memory. In most cases, you should not need to use this class. + * Probably what you are looking for is the SerializeAdapter. + * If you still decide you need this class, please read and understand + * the code first. + * + * The order of the individual bytes of the multi-byte variable is + * reversed, the byte at the highest address is moved to the lowest + * address and vice versa, same for the bytes in between. + * + * Note that the conversion is also its inversion, that is converting + * from machine to a specified endianness is the same operation as + * converting from specified to machine (I looked it up, mathematicians + * would call it an involution): + * + * X == convertBigEndian(convertBigEndian(X)) + * + * Thus, there is only one function supplied to do the conversion. + */ class EndianConverter { private: EndianConverter() { } ; public: + /** + * Convert a typed variable between big endian and machine endian. + * Intended for plain old datatypes. + */ template static T convertBigEndian(T in) { #ifndef BYTE_ORDER_SYSTEM @@ -19,7 +51,7 @@ public: T tmp; uint8_t *pointerOut = (uint8_t*) &tmp; uint8_t *pointerIn = (uint8_t*) ∈ - for (uint8_t count = 0; count < sizeof(T); count++) { + for (size_t count = 0; count < sizeof(T); count++) { pointerOut[sizeof(T) - count - 1] = pointerIn[count]; } return tmp; @@ -29,12 +61,17 @@ public: #error Unknown Byte Order #endif } + + /** + * convert a bytestream representing a single variable between big endian + * and machine endian. + */ static void convertBigEndian(uint8_t *out, const uint8_t *in, - uint32_t size) { + size_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < size; count++) { + for (size_t count = 0; count < size; count++) { out[size - count - 1] = in[count]; } return; @@ -44,6 +81,10 @@ public: #endif } + /** + * Convert a typed variable between little endian and machine endian. + * Intended for plain old datatypes. + */ template static T convertLittleEndian(T in) { #ifndef BYTE_ORDER_SYSTEM @@ -52,7 +93,7 @@ public: T tmp; uint8_t *pointerOut = (uint8_t *) &tmp; uint8_t *pointerIn = (uint8_t *) ∈ - for (uint8_t count = 0; count < sizeof(T); count++) { + for (size_t count = 0; count < sizeof(T); count++) { pointerOut[sizeof(T) - count - 1] = pointerIn[count]; } return tmp; @@ -62,12 +103,16 @@ public: #error Unknown Byte Order #endif } + /** + * convert a bytestream representing a single variable between little endian + * and machine endian. + */ static void convertLittleEndian(uint8_t *out, const uint8_t *in, - uint32_t size) { + size_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - for (uint8_t count = 0; count < size; count++) { + for (size_t count = 0; count < size; count++) { out[size - count - 1] = in[count]; } return;