[Pkg-voip-commits] [bctoolbox] 38/57: Add bytes buffer/uints to hexa string conversion functions

daniel at gnoutcheff.name daniel at gnoutcheff.name
Thu Mar 30 04:31:34 UTC 2017


This is an automated email from the git hooks/post-receive script.

gnoutchd-guest pushed a commit to branch debian/sid
in repository bctoolbox.

commit fcebd9f0cc48a6cafb8a07c5e94e844e2e8dc81f
Author: Johan Pascal <johan.pascal at belledonne-communications.com>
Date:   Wed Feb 1 13:33:11 2017 +0700

    Add bytes buffer/uints to hexa string conversion functions
---
 include/bctoolbox/port.h  |  72 ++++++++++++++++++++
 src/utils/port.c          | 168 ++++++++++++++++++++++++++++++++++++++++++++++
 tester/CMakeLists.txt     |   1 +
 tester/bctoolbox_tester.c |   1 +
 tester/bctoolbox_tester.h |   1 +
 tester/port.c             |  91 +++++++++++++++++++++++++
 6 files changed, 334 insertions(+)

diff --git a/include/bctoolbox/port.h b/include/bctoolbox/port.h
index f273892..e6e1d31 100644
--- a/include/bctoolbox/port.h
+++ b/include/bctoolbox/port.h
@@ -483,6 +483,78 @@ BCTBX_PUBLIC bool_t bctbx_is_multicast_addr(const struct sockaddr *addr);
 
 #endif
 
+/**
+ * @brief	convert an hexa char [0-9a-fA-F] into the corresponding unsigned integer value
+ * Any invalid char will be converted to zero without any warning
+ *
+ * @param[in]	inputChar	a char which shall be in range [0-9a-fA-F]
+ *
+ * @return		the unsigned integer value in range [0-15]
+ */
+BCTBX_PUBLIC uint8_t bctbx_charToByte(const uint8_t inputChar);
+
+/**
+ * @brief	convert a byte which value is in range [0-15] into an hexa char [0-9a-fA-F]
+ *
+ * @param[in]	inputByte	an integer which shall be in range [0-15]
+ *
+ * @return		the hexa char [0-9a-f] corresponding to the input
+ */
+BCTBX_PUBLIC uint8_t bctbx_byteToChar(const uint8_t inputByte);
+
+
+/**
+ * @brief Convert an hexadecimal string into the corresponding byte buffer
+ *
+ * @param[out]	outputBytes			The output bytes buffer, must have a length of half the input string buffer
+ * @param[in]	inputString			The input string buffer, must be hexadecimal(it is not checked by function, any non hexa char is converted to 0)
+ * @param[in]	inputStringLength	The lenght in chars of the string buffer, output is half this length
+ */
+BCTBX_PUBLIC void bctbx_strToUint8(uint8_t *outputBytes, const uint8_t *inputString, const uint16_t inputStringLength);
+
+/**
+ * @brief Convert a byte buffer into the corresponding hexadecimal string
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of twice the input bytes buffer
+ * @param[in]	inputBytes			The input bytes buffer
+ * @param[in]	inputBytesLength	The lenght in bytes buffer, output is twice this length
+ */
+BCTBX_PUBLIC void bctbx_int8ToStr(uint8_t *outputString, const uint8_t *inputBytes, const uint16_t inputBytesLength);
+
+/**
+ * @brief Convert an unsigned 32 bits integer into the corresponding hexadecimal string(including null termination character)
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of at least 9 bytes(8 nibbles and the '\0')
+ * @param[in]	inputUint32		The input unsigned int
+ */
+BCTBX_PUBLIC void bctbx_uint32ToStr(uint8_t outputString[9], const uint32_t inputUint32);
+
+/**
+ * @brief Convert an hexadecimal string of 8 char length into the corresponding 32 bits unsigned integer
+ *
+ * @param[in]	inputString		The input string buffer, must be hexadecimal and at least 8 char long
+ *
+ * Note : there is no check on the length or validity as an hexa string on the input, incorrect byte is silently mapped to 0
+ */
+BCTBX_PUBLIC uint32_t bctbx_strToUint32(const uint8_t inputString[9]);
+
+/**
+ * @brief Convert an unsigned 64 bits integer into the corresponding hexadecimal string(including null termination character)
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of at least 17 bytes(16 nibbles and the '\0')
+ * @param[in]	inputUint64		The input unsigned int
+ */
+BCTBX_PUBLIC void bctbx_uint64ToStr(uint8_t outputString[17], const uint64_t inputUint64);
+
+/**
+ * @brief Convert an hexadecimal string of 8 char length into the corresponding 64 bits unsigned integer
+ *
+ * @param[in]	inputString		The input string buffer, must be hexadecimal and at leat 16 char long
+ *
+ * Note : there is no check on the length or validity as an hexa string on the input, incorrect byte is silently mapped to 0
+ */
+BCTBX_PUBLIC uint64_t bctbx_strToUint64(const uint8_t inputString[17]);
+
 #ifdef __cplusplus
 }
 
diff --git a/src/utils/port.c b/src/utils/port.c
index 1862b98..e0442e5 100644
--- a/src/utils/port.c
+++ b/src/utils/port.c
@@ -1452,3 +1452,171 @@ void bctbx_freeaddrinfo(struct addrinfo *res){
 	else freeaddrinfo(beginit);
 }
 
+
+/* Useful byte buffer to/from hexa string manipulation */
+
+/**
+ * @brief	convert an hexa char [0-9a-fA-F] into the corresponding unsigned integer value
+ * Any invalid char will be converted to zero without any warning
+ *
+ * @param[in]	inputChar	a char which shall be in range [0-9a-fA-F]
+ *
+ * @return		the unsigned integer value in range [0-15]
+ */
+uint8_t bctbx_charToByte(const uint8_t inputChar) {
+	/* 0-9 */
+	if (inputChar>0x29 && inputChar<0x3A) {
+		return inputChar - 0x30;
+	}
+
+	/* a-f */
+	if (inputChar>0x60 && inputChar<0x67) {
+		return inputChar - 0x57; /* 0x57 = 0x61(a) + 0x0A*/
+	}
+
+	/* A-F */
+	if (inputChar>0x40 && inputChar<0x47) {
+		return inputChar - 0x37; /* 0x37 = 0x41(a) + 0x0A*/
+	}
+
+	/* shall never arrive here, string is not Hex*/
+	return 0;
+
+}
+
+/**
+ * @brief	convert a byte which value is in range [0-15] into an hexa char [0-9a-fA-F]
+ *
+ * @param[in]	inputByte	an integer which shall be in range [0-15]
+ *
+ * @return		the hexa char [0-9a-f] corresponding to the input
+ */
+uint8_t bctbx_byteToChar(const uint8_t inputByte) {
+	uint8_t inputByteCrop = inputByte&0x0F; /* restrict the input value to range [0-15] */
+	/* 0-9 */
+	if(inputByteCrop<0x0A) {
+		return inputByteCrop+0x30;
+	}
+	/* a-f */
+	return inputByteCrop + 0x57;
+}
+
+
+/**
+ * @brief Convert an hexadecimal string into the corresponding byte buffer
+ *
+ * @param[out]	outputBytes			The output bytes buffer, must have a length of half the input string buffer
+ * @param[in]	inputString			The input string buffer, must be hexadecimal(it is not checked by function, any non hexa char is converted to 0)
+ * @param[in]	inputStringLength	The lenght in chars of the string buffer, output is half this length
+ */
+void bctbx_strToUint8(uint8_t *outputBytes, const uint8_t *inputString, const uint16_t inputStringLength) {
+	int i;
+	for (i=0; i<inputStringLength/2; i++) {
+		outputBytes[i] = (bctbx_charToByte(inputString[2*i]))<<4 | bctbx_charToByte(inputString[2*i+1]);
+	}
+}
+
+/**
+ * @brief Convert a byte buffer into the corresponding hexadecimal string
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of twice the input bytes buffer
+ * @param[in]	inputBytes			The input bytes buffer
+ * @param[in]	inputBytesLength	The lenght in bytes buffer, output is twice this length
+ */
+void bctbx_int8ToStr(uint8_t *outputString, const uint8_t *inputBytes, const uint16_t inputBytesLength) {
+	int i;
+	for (i=0; i<inputBytesLength; i++) {
+		outputString[2*i] = bctbx_byteToChar((inputBytes[i]>>4)&0x0F);
+		outputString[2*i+1] = bctbx_byteToChar(inputBytes[i]&0x0F);
+	}
+}
+
+/**
+ * @brief Convert an unsigned 32 bits integer into the corresponding hexadecimal string(including null termination character)
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of at least 9 bytes(8 nibbles and the '\0')
+ * @param[in]	inputUint32		The input unsigned int
+ */
+void bctbx_uint32ToStr(uint8_t outputString[9], const uint32_t inputUint32) {
+
+	outputString[0] = bctbx_byteToChar((uint8_t)((inputUint32>>28)&0x0F));
+	outputString[1] = bctbx_byteToChar((uint8_t)((inputUint32>>24)&0x0F));
+	outputString[2] = bctbx_byteToChar((uint8_t)((inputUint32>>20)&0x0F));
+	outputString[3] = bctbx_byteToChar((uint8_t)((inputUint32>>16)&0x0F));
+	outputString[4] = bctbx_byteToChar((uint8_t)((inputUint32>>12)&0x0F));
+	outputString[5] = bctbx_byteToChar((uint8_t)((inputUint32>>8)&0x0F));
+	outputString[6] = bctbx_byteToChar((uint8_t)((inputUint32>>4)&0x0F));
+	outputString[7] = bctbx_byteToChar((uint8_t)((inputUint32)&0x0F));
+	outputString[8] = '\0';
+}
+
+/**
+ * @brief Convert an hexadecimal string of 8 char length into the corresponding 32 bits unsigned integer
+ *
+ * @param[in]	inputString			The input string buffer, must be hexadecimal(it is not checked by function, any non hexa char is converted to 0)
+ *
+ * Note : there is no check on the length or validity as an hexa string on the input, incorrect byte is silently mapped to 0
+ */
+uint32_t bctbx_strToUint32(const uint8_t *inputString) {
+	return  (((uint32_t)bctbx_charToByte(inputString[0]))<<28)
+		| (((uint32_t)bctbx_charToByte(inputString[1]))<<24)
+		| (((uint32_t)bctbx_charToByte(inputString[2]))<<20)
+		| (((uint32_t)bctbx_charToByte(inputString[3]))<<16)
+		| (((uint32_t)bctbx_charToByte(inputString[4]))<<12)
+		| (((uint32_t)bctbx_charToByte(inputString[5]))<<8)
+		| (((uint32_t)bctbx_charToByte(inputString[6]))<<4)
+		| (((uint32_t)bctbx_charToByte(inputString[7])));
+}
+
+/**
+ * @brief Convert an unsigned 64 bits integer into the corresponding hexadecimal string(including null termination character)
+ *
+ * @param[out]	outputString		The output string buffer, must have a length of at least 17 bytes(16 nibbles and the '\0')
+ * @param[in]	inputUint64		The input unsigned int
+ */
+void bctbx_uint64ToStr(uint8_t outputString[17], const uint64_t inputUint64) {
+
+	outputString[0] = bctbx_byteToChar((uint8_t)((inputUint64>>60)&0x0F));
+	outputString[1] = bctbx_byteToChar((uint8_t)((inputUint64>>56)&0x0F));
+	outputString[2] = bctbx_byteToChar((uint8_t)((inputUint64>>52)&0x0F));
+	outputString[3] = bctbx_byteToChar((uint8_t)((inputUint64>>48)&0x0F));
+	outputString[4] = bctbx_byteToChar((uint8_t)((inputUint64>>44)&0x0F));
+	outputString[5] = bctbx_byteToChar((uint8_t)((inputUint64>>40)&0x0F));
+	outputString[6] = bctbx_byteToChar((uint8_t)((inputUint64>>36)&0x0F));
+	outputString[7] = bctbx_byteToChar((uint8_t)((inputUint64>>32)&0x0F));
+	outputString[8] = bctbx_byteToChar((uint8_t)((inputUint64>>28)&0x0F));
+	outputString[9] = bctbx_byteToChar((uint8_t)((inputUint64>>24)&0x0F));
+	outputString[10] = bctbx_byteToChar((uint8_t)((inputUint64>>20)&0x0F));
+	outputString[11] = bctbx_byteToChar((uint8_t)((inputUint64>>16)&0x0F));
+	outputString[12] = bctbx_byteToChar((uint8_t)((inputUint64>>12)&0x0F));
+	outputString[13] = bctbx_byteToChar((uint8_t)((inputUint64>>8)&0x0F));
+	outputString[14] = bctbx_byteToChar((uint8_t)((inputUint64>>4)&0x0F));
+	outputString[15] = bctbx_byteToChar((uint8_t)((inputUint64)&0x0F));
+	outputString[16] = '\0';
+}
+
+/**
+ * @brief Convert an hexadecimal string of 8 char length into the corresponding 64 bits unsigned integer
+ *
+ * @param[in]	inputString		The input string buffer, must be hexadecimal and at leat 16 char long
+ *
+ * Note : there is no check on the length or validity as an hexa string on the input, incorrect byte is silently mapped to 0
+ */
+uint64_t bctbx_strToUint64(const uint8_t inputString[17]) {
+	return  (((uint64_t)bctbx_charToByte(inputString[0]))<<60)
+		| (((uint64_t)bctbx_charToByte(inputString[1]))<<56)
+		| (((uint64_t)bctbx_charToByte(inputString[2]))<<52)
+		| (((uint64_t)bctbx_charToByte(inputString[3]))<<48)
+		| (((uint64_t)bctbx_charToByte(inputString[4]))<<44)
+		| (((uint64_t)bctbx_charToByte(inputString[5]))<<40)
+		| (((uint64_t)bctbx_charToByte(inputString[6]))<<36)
+		| (((uint64_t)bctbx_charToByte(inputString[7]))<<32)
+		| (((uint64_t)bctbx_charToByte(inputString[8]))<<28)
+		| (((uint64_t)bctbx_charToByte(inputString[9]))<<24)
+		| (((uint64_t)bctbx_charToByte(inputString[10]))<<20)
+		| (((uint64_t)bctbx_charToByte(inputString[11]))<<16)
+		| (((uint64_t)bctbx_charToByte(inputString[12]))<<12)
+		| (((uint64_t)bctbx_charToByte(inputString[13]))<<8)
+		| (((uint64_t)bctbx_charToByte(inputString[14]))<<4)
+		| (((uint64_t)bctbx_charToByte(inputString[15])));
+}
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index c29538e..3cccdff 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -31,6 +31,7 @@ if(BCUNIT_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
 		bctoolbox_tester.c
 		bctoolbox_tester.h
 		containers.cc
+		port.c
 	)
 
 	string(REPLACE ";" " " LINK_FLAGS_STR "${LINK_FLAGS}")
diff --git a/tester/bctoolbox_tester.c b/tester/bctoolbox_tester.c
index bb1a8e5..64dc03a 100644
--- a/tester/bctoolbox_tester.c
+++ b/tester/bctoolbox_tester.c
@@ -44,6 +44,7 @@ static void log_handler(int lev, const char *fmt, va_list args) {
 void bctoolbox_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
 	bc_tester_init(log_handler,BCTBX_LOG_ERROR, 0,NULL);
 	bc_tester_add_suite(&containers_test_suite);
+	bc_tester_add_suite(&utils_test_suite);
 }
 
 void bctoolbox_tester_uninit(void) {
diff --git a/tester/bctoolbox_tester.h b/tester/bctoolbox_tester.h
index bb91654..32c1a7e 100644
--- a/tester/bctoolbox_tester.h
+++ b/tester/bctoolbox_tester.h
@@ -33,6 +33,7 @@ extern "C" {
 #endif
 
 extern test_suite_t containers_test_suite;
+extern test_suite_t utils_test_suite;
 
 #ifdef __cplusplus
 };
diff --git a/tester/port.c b/tester/port.c
new file mode 100644
index 0000000..0e88b22
--- /dev/null
+++ b/tester/port.c
@@ -0,0 +1,91 @@
+/*
+	bctoolbox
+    Copyright (C) 2017  Belledonne Communications SARL
+
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include "bctoolbox_tester.h"
+#include "bctoolbox/port.h"
+
+static void bytesToFromHexaStrings(void) {
+	const uint8_t a55aBytes[2] = {0xa5, 0x5a};
+	const uint8_t a55aString[5] = "a55a";
+	const uint8_t upBytes[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
+	const uint8_t upString[17] = "0123456789abcdef";
+	const uint8_t downBytes[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
+	const uint8_t downString[17] = "fedcba9876543210";
+	uint8_t outputBytes[16];
+	uint8_t outputString[16];
+
+	BC_ASSERT_EQUAL(bctbx_charToByte("1"[0]), 1, uint8_t, "%d");
+	BC_ASSERT_EQUAL(bctbx_charToByte("5"[0]), 5, uint8_t, "%d");
+	BC_ASSERT_EQUAL(bctbx_charToByte("a"[0]), 10, uint8_t, "%d");
+	BC_ASSERT_EQUAL(bctbx_charToByte("e"[0]), 14, uint8_t, "%d");
+	BC_ASSERT_EQUAL(bctbx_charToByte("B"[0]), 11, uint8_t, "%d");
+	BC_ASSERT_EQUAL(bctbx_charToByte("F"[0]), 15, uint8_t, "%d");
+
+	BC_ASSERT_EQUAL(bctbx_byteToChar(0), "0"[0], char, "%c");
+	BC_ASSERT_EQUAL(bctbx_byteToChar(2), "2"[0], char, "%c");
+	BC_ASSERT_EQUAL(bctbx_byteToChar(5), "5"[0], char, "%c");
+	BC_ASSERT_EQUAL(bctbx_byteToChar(0x0a), "a"[0], char, "%c");
+	BC_ASSERT_EQUAL(bctbx_byteToChar(0x0c), "c"[0], char, "%c");
+	BC_ASSERT_EQUAL(bctbx_byteToChar(0x0e), "e"[0], char, "%c");
+
+	bctbx_strToUint8(outputBytes, a55aString, 4);
+	BC_ASSERT_NSTRING_EQUAL(outputBytes, a55aBytes, 2);
+	bctbx_strToUint8(outputBytes, upString, 16);
+	BC_ASSERT_NSTRING_EQUAL(outputBytes, upBytes, 8);
+	bctbx_strToUint8(outputBytes, downString, 16);
+	BC_ASSERT_NSTRING_EQUAL(outputBytes, downBytes, 8);
+
+	bctbx_int8ToStr(outputString, a55aBytes, 2);
+	BC_ASSERT_NSTRING_EQUAL(outputString, a55aString, 4);
+	bctbx_int8ToStr(outputString, upBytes, 8);
+	BC_ASSERT_NSTRING_EQUAL(outputString, upString, 16);
+	bctbx_int8ToStr(outputString, downBytes, 8);
+	BC_ASSERT_NSTRING_EQUAL(outputString, downString, 16);
+
+	bctbx_uint32ToStr(outputString, 0x5aa5c376);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "5aa5c376", 8);
+	bctbx_uint32ToStr(outputString, 0x01234567);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "01234567", 8);
+	bctbx_uint32ToStr(outputString, 0xfedcba98);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "fedcba98", 8);
+
+	BC_ASSERT_EQUAL(bctbx_strToUint32("5aa5c376"), 0x5aa5c376, uint32_t, "0x%08x");
+	BC_ASSERT_EQUAL(bctbx_strToUint32("01234567"), 0x01234567, uint32_t, "0x%08x");
+	BC_ASSERT_EQUAL(bctbx_strToUint32("fedcba98"), 0xfedcba98, uint32_t, "0x%08x");
+
+	bctbx_uint64ToStr(outputString, 0xfa5c37643cde8de0);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "fa5c37643cde8de0", 16);
+	bctbx_uint64ToStr(outputString, 0x0123456789abcdef);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "0123456789abcdef", 16);
+	bctbx_uint64ToStr(outputString, 0xfedcba9876543210);
+	BC_ASSERT_NSTRING_EQUAL(outputString, "fedcba9876543210", 16);
+
+	BC_ASSERT_EQUAL(bctbx_strToUint64("fa5c37643cde8de0"), 0xfa5c37643cde8de0, uint64_t, "0x%016lx");
+	BC_ASSERT_EQUAL(bctbx_strToUint64("0123456789abcdef"), 0x0123456789abcdef, uint64_t, "0x%016lx");
+	BC_ASSERT_EQUAL(bctbx_strToUint64("fedcba9876543210"), 0xfedcba9876543210, uint64_t, "0x%016lx");
+}
+
+
+static test_t utils_tests[] = {
+	TEST_NO_TAG("Bytes to/from Hexa strings", bytesToFromHexaStrings),
+};
+
+test_suite_t utils_test_suite = {"Utils", NULL, NULL, NULL, NULL,
+							   sizeof(utils_tests) / sizeof(utils_tests[0]), utils_tests};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/bctoolbox.git



More information about the Pkg-voip-commits mailing list