From ba393a7ff8efd58093da267925d2f084af3e14b5 Mon Sep 17 00:00:00 2001 From: Martin Dagarin Date: Tue, 24 Jul 2018 22:39:05 +0200 Subject: [PATCH] Version 2 - Rewritten whole library - Improved preformace - Changed function names - Improved meson framework - Fixed issues in Readme.md - Added make file - Added CI for auto testing - Added tests - Added examples - Fixed issues in `Readme.md` --- .travis.yml | 26 +++++ ByteConvert/ByteConvert.cpp | 81 ++++++++++++++ ByteConvert/ByteConvert.hpp | 112 ++++++++++++++++++++ {libbyteconvert => ByteConvert}/meson.build | 0 CHANGELOG | 11 ++ Makefile | 8 ++ README.md | 83 +++++---------- examples/SimpleTest.cpp | 40 ------- examples/bytes_to_int.cpp | 21 ++++ examples/bytes_to_string.cpp | 25 +++++ examples/int_to_bytes.cpp | 53 +++++++++ examples/meson.build | 20 ++-- examples/string_to_bytes.cpp | 56 ++++++++++ libbyteconvert/ByteConvert.cpp | 48 --------- libbyteconvert/ByteConvert.hpp | 36 ------- meson.build | 12 ++- test/block_to_hex_string.cpp | 46 ++++++++ test/byte_to_hex.cpp | 45 ++++++++ test/hex_string_to_block.cpp | 64 +++++++++++ test/hex_to_byte.cpp | 45 ++++++++ test/meson.build | 15 +++ test/to_block.cpp | 47 ++++++++ test/to_variable.cpp | 29 +++++ 23 files changed, 729 insertions(+), 194 deletions(-) create mode 100644 .travis.yml create mode 100644 ByteConvert/ByteConvert.cpp create mode 100644 ByteConvert/ByteConvert.hpp rename {libbyteconvert => ByteConvert}/meson.build (100%) create mode 100644 CHANGELOG create mode 100644 Makefile delete mode 100644 examples/SimpleTest.cpp create mode 100644 examples/bytes_to_int.cpp create mode 100644 examples/bytes_to_string.cpp create mode 100644 examples/int_to_bytes.cpp create mode 100644 examples/string_to_bytes.cpp delete mode 100644 libbyteconvert/ByteConvert.cpp delete mode 100644 libbyteconvert/ByteConvert.hpp create mode 100644 test/block_to_hex_string.cpp create mode 100644 test/byte_to_hex.cpp create mode 100644 test/hex_string_to_block.cpp create mode 100644 test/hex_to_byte.cpp create mode 100644 test/meson.build create mode 100644 test/to_block.cpp create mode 100644 test/to_variable.cpp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..823bb77 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: generic +sudo: enabled +services: +- docker +stages: +- test +jobs: + include: + stage: test + install: + - sudo docker pull slocomptech/docker-meson-cpp:latest + - sudo docker run -it -d --name buildenv slocomptech/docker-meson-cpp bash + - sudo docker ps + - sudo docker exec buildenv apt-get install git -y + before_script: + - sudo docker exec buildenv git clone -b ${TRAVIS_BRANCH} https://github.com/SloCompTech/ByteConvert_cpp.git ByteConvert_cpp + script: + - sudo docker exec buildenv bash -c 'cd ByteConvert_cpp && meson build' + - sudo docker exec buildenv bash -c 'cd ByteConvert_cpp && ninja -C build' + - sudo docker exec buildenv bash -c 'cd ByteConvert_cpp && ninja -C build test' + - sudo docker exec buildenv bash -c 'cd ByteConvert_cpp && ninja -C build install' + after_script: + - sudo docker stop buildenv + - sudo docker rm buildenv + - sudo docker rmi slocomptech/docker-meson-cpp:latest + - sudo docker ps -a \ No newline at end of file diff --git a/ByteConvert/ByteConvert.cpp b/ByteConvert/ByteConvert.cpp new file mode 100644 index 0000000..7560e83 --- /dev/null +++ b/ByteConvert/ByteConvert.cpp @@ -0,0 +1,81 @@ +/** + * @file ByteConvert.cpp + * + * @authors Martin Dagarin + * @date 22/07/2018 + * + * @brief Source file of ByteConvert module + */ + +#include "ByteConvert.hpp" + +namespace ByteConvert +{ + std::string byte_to_hex(const uint8_t& byte) + { + std::string buffer(""); + uint8_t val; + + for (uint8_t i = 0; i < 2; i++) { + if (i == 0) + val = (byte >> 4); + else + val = byte & 0x0f; + if (val >= 16) + buffer += '?'; + else if (val < 10) + buffer += ('0' + val); + else + buffer += ('W' + val); + } + return buffer; + } + + uint8_t hex_to_byte(const std::string& hex) + { + uint8_t val = 0x00; + uint8_t pos = (hex.size() > 1) ? hex.size() - 2 : hex.size() - 1; + char c; + for (; pos < hex.size(); pos++) { + c = hex[pos]; + if (c >= 'A' && c <= 'F') + val += (c - '7'); + else if (c >= 'a' && c <= 'f') + val += (c - 'W'); + else if (c >= '0' && c <= '9') + val += (c - '0'); + else + val += '?'; + if (pos == 0 && hex.size() > 1) + val = (val << 4); + } + return val; + } + + std::string block_to_hex_string(const uint8_t* const block, const size_t& size) + { + std::string buffer(""); + for (size_t i = 0; i < size; i++) { + buffer += byte_to_hex(block[i]); + } + return buffer; + } + + uint8_t* hex_string_to_block(const std::string& hex_string, size_t* const size) + { + size_t block_size = hex_string.size()/2 + ((hex_string.size() % 2 == 1) ? 1 : 0); + uint8_t* block = new uint8_t[block_size]; + int offset = 0; + for (size_t i = 0;i < block_size; i++) { + if (i == 0 && hex_string.size() % 2 == 1) { + offset = -1; + block[i] = hex_to_byte(std::string("0") + hex_string[0]); + continue; + } + block[i] = hex_to_byte(std::string(1,hex_string[i*2 + offset]) + hex_string[i*2 + 1 + offset]); + } + if (size != nullptr) + *size = block_size; + return block; + } +} diff --git a/ByteConvert/ByteConvert.hpp b/ByteConvert/ByteConvert.hpp new file mode 100644 index 0000000..bc629ab --- /dev/null +++ b/ByteConvert/ByteConvert.hpp @@ -0,0 +1,112 @@ +/** + * @file ByteConvert.hpp + * + * @authors Martin Dagarin + * @date 22/07/2018 + * + * @brief Header of ByteConvert module + */ + +#ifndef _ByteConvert_hpp_ +#define _ByteConvert_hpp_ + +#include +#include + + +/** + * @brief Namespace which holds all ByteConvert functions + */ +namespace ByteConvert { + /** + * @brief Converts single byte to hex string + * + * @param[in] byte Byte to convert to hex string + * @return Hex string + */ + std::string byte_to_hex(const uint8_t& byte); + + /** + * @brief Converts hex string (1 or 2 chars) to byte + * + * @param[in] hex Hex string (1 or 2 chars) to convert to byte + * @return Byte + */ + uint8_t hex_to_byte(const std::string& hex); + + /** + * @brief Converts array of bytes to hex string + * + * @param[in] block Array of bytes + * @param[in] size Size of block + * @return Hex string + */ + std::string block_to_hex_string(const uint8_t* const block, const size_t& size); + + /** + * @brief Converts hex string to array of bytes + * + * @param[in] hex_string Hex string + * @param[out] size Size of returned array + * @return Array of bytes + */ + uint8_t* hex_string_to_block(const std::string& hex_string,size_t* const size); + + /** + * @brief Converts numeric without floating point variables (uses sizeof()) to array of bytes + * + * @param[in] variable Variable to convert to bytes + * @param[out] size Size of array (if pointer specifed) + * @return Array of bytes + */ + template + uint8_t* to_block(T variable,size_t* const size) + { + uint8_t block_size = sizeof(T)/sizeof(uint8_t); + uint8_t *block = new uint8_t[block_size]; + for (size_t i = 0; i < block_size; i++) { + if (i != 0) variable >>= 8; + block[block_size - 1 - i] = (uint8_t)(variable & 0xff); + } + if (size != nullptr) + *size = block_size; + return block; + } + + /** + * @brief Converts byte to variable + * + * @param[in] block Array of bytes + * @return Variable + */ + template + T to_variable(const uint8_t* block) + { + size_t var_size = sizeof(T)/sizeof(uint8_t); + T var = 0x00; + for (size_t i = 0; i < var_size; i++) { + if (i != 0) var <<= 8; + var |= block[i]; + } + return var; + } + + /** + * @brief Converts byte to variable + * + * @param[in] block Array of bytes + * @return Variable + */ + template + T to_variable(const uint8_t* block, const size_t& block_size) + { + T var = 0x00; + for (size_t i = 0; i < block_size; i++) { + if (i != 0) var <<= 8; + var |= block[i]; + } + return var; + } +} + +#endif diff --git a/libbyteconvert/meson.build b/ByteConvert/meson.build similarity index 100% rename from libbyteconvert/meson.build rename to ByteConvert/meson.build diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..7e1aaf1 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,11 @@ +# 2.0.0 +- Rewritten whole library +- Improved preformace +- Changed function names +- Improved meson framework +- Fixed issues in Readme.md +- Added make file +- Added CI for auto testing +- Added tests +- Added examples +- Fixed issues in `Readme.md` \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..198c72b --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +build: + meson build + ninja -C build + ninja -C build test +install: + ninja -C build install +clean: + rm -rf build \ No newline at end of file diff --git a/README.md b/README.md index 99a03fb..fe179db 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,51 @@

Byteconvert

# ByteConvert + [![Build Status](https://travis-ci.org/SloCompTech/ByteConvert_cpp.svg?branch=master)](https://travis-ci.org/SloCompTech/ByteConvert_cpp) [![Packagist](https://img.shields.io/packagist/l/doctrine/orm.svg)]() ## What's about ? -Have you ever wanted to transmit `int`,`short`,`long`,`double` or any other numeric type over I2C,SPI,serial or other protocol or bus, but you converted variable to string to be able to transmit it char by char. This library enables you to convert any numeric value to bytes or other way around and you can also print array of bytes. + +Have you ever wanted to transmit `int`,`short`,`long` or any other numeric type over I2C,SPI,serial or other protocol or bus, but you converted variable to string to be able to transmit it char by char. This library enables you to convert any numeric value to bytes or other way around and you can also print array of bytes. ## What you need to consider, when you are using this library + When you are using this library, you need to consider variable byte size, because if you are using different platforms, then there may be some errors, because int on platform 1 has 4 bytes and int on platform 2 may has 2 bytes. ## What you need to install this project ? -You need [python3](https://www.python.org/), [ninja](https://ninja-build.org/) and [meson](http://mesonbuild.com). - -``` -$ sudo apt-get install python3 python3-pip ninja-build -``` - -## How to install -``` -$ cd -$ mkdir build -$ meson build && cd build -$ ninja -$ sudo ninja install -``` - -If you have problems, that library can't be found run `sudo ldconfig /usr/local/lib/x86_64-linux-gnu/` if you haven't changed prefix, else mofidy path. - -## How to include library to your c or c++ project ? -It's simple. At the top of your source file include library: -``` c++ -#include -``` -And when you compile add flag `-lbyteconvert`, example `g++ -std=c++11 MyProject.cpp -lbyteconvert -o MyProject`. -## Examples -Convert numeric variable for eg. `int`,`short`,`float`,`double` to array of bytes. -``` c++ -int somevar = 5; -size_t blk_size = 0; -uint8_t *block = ByteConvert::varToArray(blk_size,somevar); - -// Use array +You need [python3](https://www.python.org/), [ninja](https://ninja-build.org/) and [meson](http://mesonbuild.com). -delete block; // Don't forget to free memory, when you don't need array any more +```bash +sudo apt-get install python3 python3-pip ninja-build +sudo pip3 install meson ``` -Convert array of bytes to numeric variable. -``` c++ -uint8_t *block; // Predefined byte array with size of int -int somevar = ByteConvert::arrayToVar(block); - -// Use block & somevar +## Installing +```bash +meson build +ninja -C build +ninja -C build test +ninja -C build install -delete block; // Don't forget to free memory, when you don't need array any more - -// Use somevar +# Or simply +make +sudo make install ``` -Convert array of bytes to string of hex characters -``` c++ -size_t blk_size; // Predefined size of byte array -uint8_t *block; // Predefined byte array with size of int -String somevar = ByteConvert::arrayToString(blk_size,block); +If you have problems, that library can't be found run `sudo ldconfig /usr/local/lib/x86_64-linux-gnu/` if you haven't changed prefix, else modify path. -// Use block & somevar +## How to include library to your c or c++ project ? -delete block; // Don't forget to free memory, when you don't need array any more +It's simple. At the top of your source file include library: -// Use somevar +```c++ +#include ``` -Convert string of hex characters to array of bytes -``` c++ -String somevar = ""; // Predefined string -size_t blk_size = 0; -uint8_t *block = ByteConvert::stringToArray(blk_size,somevar); +And when you compile add flag `-lbyteconvert`, example `g++ -std=c++11 MyProject.cpp -lbyteconvert -o MyProject`. -// Use block +## Examples -delete block; // Don't forget to free memory, when you don't need array any more -``` +See [**examples folder**](https://github.com/SloCompTech/ByteConvert_cpp/tree/master/examples) \ No newline at end of file diff --git a/examples/SimpleTest.cpp b/examples/SimpleTest.cpp deleted file mode 100644 index 75493f1..0000000 --- a/examples/SimpleTest.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -// Use: #include -// For testing -#include "../libbyteconvert/ByteConvert.hpp" - -using namespace std; - -int main() { - cout << "Simple test" << endl; - cout << "size(short): " << sizeof(short) << endl; - cout << "size(int): " << sizeof(int) << endl; - cout << "size(float): " << sizeof(float) << endl; - cout << "size(char): " << sizeof(char) << endl; - cout << "size(uint8_t): " << sizeof(uint8_t) << endl; - cout << "valToHex: 9->" << ByteConvert::valToHex(0x09) << endl; - cout << "valToHex: b->" << ByteConvert::valToHex(0x0b) << endl; - cout << "byteToHexString: fa->" << ByteConvert::byteToHexString(0xfa) << endl; - - uint8_t array1[] = {0xfa,0xca,0xde,0xda}; - cout << "facadeda -> " << ByteConvert::arrayToString(4,array1) << endl; - - size_t s2 = 0; - uint8_t *array2 = ByteConvert::stringToArray(s2,"bedababa"); - cout << "Size(bedababba): " << s2 << endl; - cout << "bedababba -> " << ByteConvert::arrayToString(s2,array2) << endl; - - delete array2; - - int in = 5; - cout << "Orig: 5 -> " << in << endl; - size_t s3 = 0; - uint8_t *array3 = ByteConvert::varToArray(s3,in); - cout << "00000005 -> " << ByteConvert::arrayToString(s3,array3) << endl; - cout << "5 -> " << ByteConvert::arrayToVar(array3) << endl; - - delete array3; - - return 0; -} \ No newline at end of file diff --git a/examples/bytes_to_int.cpp b/examples/bytes_to_int.cpp new file mode 100644 index 0000000..bc38250 --- /dev/null +++ b/examples/bytes_to_int.cpp @@ -0,0 +1,21 @@ +#include +#include + +#include + +int main() +{ + // Create array of bytes that represent 1 (type: int) + uint8_t block[sizeof(int)]; + memset(block,0,sizeof(int)-1); + block[sizeof(int)-1] = 1; + + int val = ByteConvert::to_variable(block); // Convert array of bytes to int + if (val != 1) { // Check if we got, what we expected to get + // Error, something went wrong + return -1; + } + + // Success + return 0; +} \ No newline at end of file diff --git a/examples/bytes_to_string.cpp b/examples/bytes_to_string.cpp new file mode 100644 index 0000000..670bb9a --- /dev/null +++ b/examples/bytes_to_string.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +#include + +int main() +{ + // Set array of bytes which we will convert to string + uint8_t block[8] = {0xfa, 0xca, 0xba, 0xba, 0xde, 0xda, 0xce, 0xca}; + // Set expected string + std::string expected_string = "facababadedaceca"; + + // Convert bytes to string (8 is size of block) + std::string converted_string = ByteConvert::block_to_hex_string(block, 8); + + // Check the result + if (converted_string != expected_string) { + // Error + return -1; + } + + // Success + return 0; +} \ No newline at end of file diff --git a/examples/int_to_bytes.cpp b/examples/int_to_bytes.cpp new file mode 100644 index 0000000..527de5d --- /dev/null +++ b/examples/int_to_bytes.cpp @@ -0,0 +1,53 @@ +#include +#include +#include + +#include + +int main() +{ + // Variable we will change into bytes + int val = 2; + // Array of bytes we expect to get back + uint8_t block[sizeof(int)]; + memset(block,0,sizeof(int)-1); + block[sizeof(int)-1] = 2; + + // Convert variable to bytes + size_t result_size = 0; // Size of block, we get back (you can pass nullptr if you know size of result) + uint8_t* result = ByteConvert::to_block(val, &result_size); + + // Check result + if (result_size != sizeof(int)) { + // Error + delete[] result; + return -1; + } + for (size_t i = 0; i < result_size; i++) { + if (result[i] != block[i]) { + // Error: result and expected result don't match + delete[] result; + return -2; + } + } + // Clear result !!! It was allocated to heap so we need to manualy free it !!!!!! + delete[] result; + + // Same as above, just implemented with smart pointers, which is safer + std::unique_ptr result1(ByteConvert::to_block(val, &result_size)); + // Check result + if (result_size != sizeof(int)) { + // Error + return -3; + } + for (size_t i = 0; i < result_size; i++) { + if (result1[i] != block[i]) { + // Error: result and expected result don't match + return -4; + } + } + // No need to free result1, because it clears itself when it goes out of scope + + // Success + return 0; +} \ No newline at end of file diff --git a/examples/meson.build b/examples/meson.build index 66c32f1..5e5139b 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,9 +1,13 @@ -# Build simple executable -SimpleTest = executable( - 'SimpleTest', - 'SimpleTest.cpp', - link_with: libbyteconvert -) +# List of examples +examples = [ + ['bytes_to_int',['bytes_to_int.cpp']], + ['bytes_to_string',['bytes_to_string.cpp']], + ['int_to_bytes',['int_to_bytes.cpp']], + ['string_to_bytes',['string_to_bytes.cpp']] +] -# Specify test for library -test('SimpleTest',SimpleTest) \ No newline at end of file +# Compile all test +foreach example: examples + exe = executable(example[0], example[1], link_with: libbyteconvert, include_directories: libbyteconvert_include) + test('example_' + example[0],exe) +endforeach diff --git a/examples/string_to_bytes.cpp b/examples/string_to_bytes.cpp new file mode 100644 index 0000000..ed97b92 --- /dev/null +++ b/examples/string_to_bytes.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#include + +int main() +{ + // String that we will convert to bytes + std::string example_string = "facaceca"; + // Array of bytes we expect to get + uint8_t expected[4] = {0xfa, 0xca, 0xce, 0xca}; + + // Convert string to bytes + size_t result_size = 0; + uint8_t* result = ByteConvert::hex_string_to_block(example_string, &result_size); + + // Check result + if (result_size != 4) { + // Error, unexpected size of result + delete[] result; + return -1; + } + for (size_t i = 0; i < result_size; i++) { + if (expected[i] != result[i]) { + // Error, result not expected + delete[] result; + return -2; + } + } + + // Clear result !!! It was allocated to heap so we need to manualy free it !!!!!! + delete[] result; + + // Same as above, just implemented with smart pointers, which is safer + std::unique_ptr result1(ByteConvert::hex_string_to_block(example_string, &result_size)); + + // Check result + if (result_size != 4) { + // Error, unexpected size of result + return -1; + } + for (size_t i = 0; i < result_size; i++) { + if (expected[i] != result1[i]) { + // Error, result not expected + return -2; + } + } + + + // No need to free result1, because it clears itself when it goes out of scope + + // Success + return 0; +} \ No newline at end of file diff --git a/libbyteconvert/ByteConvert.cpp b/libbyteconvert/ByteConvert.cpp deleted file mode 100644 index 631acf7..0000000 --- a/libbyteconvert/ByteConvert.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "ByteConvert.hpp" -namespace ByteConvert { - char valToHex(uint8_t val) { - if ((val & 0x0f) < 10) - return ('0' + val); - else - return ('a' + (val - 10)); - } - uint8_t hexToVal(char c) { - if (c >= 'a') - return (15 - ('f' - c)); - else - return (9 - ('9' - c)); - } - std::string byteToHexString(uint8_t b) { - std::string buffer = ""; - buffer += valToHex(b & 0x0f); - b >>= 4; - buffer = valToHex(b & 0x0f) + buffer; - return buffer; - } - uint8_t hexStringToByte(std::string block) { - if (block.length() != 2) - return 0x00; - return 16*hexToVal(block.at(0))+hexToVal(block.at(1)); - } - - std::string arrayToString(size_t size,uint8_t *src) { - std::string buffer = ""; - for (size_t i = 0;i < (size);i++) - buffer += byteToHexString(src[i]); - return buffer; - } - uint8_t* stringToArray(size_t &size,std::string src) { - // Length of src must be odd !! - if (src.length() % 2 == 1) - src = "0" + src; - size = src.length()/2; - uint8_t *dst = new uint8_t[size]; // Allocate memory space - std::string buff = ""; - for (size_t i = 0;i < (size);i++) { - buff = src.at(i*2); - buff += src.at(i*2+1); - dst[i] = hexStringToByte(buff); - } - return dst; - } -} diff --git a/libbyteconvert/ByteConvert.hpp b/libbyteconvert/ByteConvert.hpp deleted file mode 100644 index cd3a44c..0000000 --- a/libbyteconvert/ByteConvert.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _ByteConvert_hpp_ -#define _ByteConvert_hpp_ - -#include -#include - -namespace ByteConvert { - template - T arrayToVar(uint8_t *array) { - size_t size = sizeof(T)/sizeof(uint8_t); - T var = 0x00; - for (size_t i = 0;i < (size);i++) { - if (i != 0) var <<= 8; - var |= array[i]; - } - return var; - } - template - uint8_t *varToArray(size_t &size,T var) { - size = sizeof(T)/sizeof(uint8_t); - uint8_t *array = new uint8_t[size]; // Alocate memory - for (size_t i = 0;i < size;i++) { - if (i != 0) var >>= 8; - array[size-1-i] = (uint8_t)(var&0xff); - } - return array; - } - char valToHex(uint8_t val); - uint8_t hexToVal(char c); - std::string byteToHexString(uint8_t b); - uint8_t hexStringToByte(std::string block); - std::string arrayToString(size_t size,uint8_t *src); - uint8_t* stringToArray(size_t &size,std::string src); -} - -#endif diff --git a/meson.build b/meson.build index 07a4253..1c6ad6b 100644 --- a/meson.build +++ b/meson.build @@ -1,11 +1,16 @@ # Project info -project('byteconvert', 'cpp', version:'1.0.0', license: 'MIT', default_options : ['cpp_std=c++11']) +project('byteconvert', 'cpp', version:'2.0.0', license: 'MIT', default_options : ['cpp_std=c++11']) # Import modules pkg = import('pkgconfig') -subdir('libbyteconvert') # Run meson script in libbyteconvert dir +# Include directories +libbyteconvert_include = include_directories('.') + +# Run subscripts +subdir('ByteConvert') # Run meson script in libbyteconvert dir subdir('examples') # Run meson script in examples dir +subdir('test') # Package info pkg.generate( @@ -18,8 +23,7 @@ pkg.generate( ) # Declare as dependency so it can be used elsewhere -libbyteconvert_inc = include_directories('libbyteconvert') libbyteconvert_dep = declare_dependency( link_with: libbyteconvert, - include_directories: libbyteconvert_inc + include_directories: libbyteconvert_include ) \ No newline at end of file diff --git a/test/block_to_hex_string.cpp b/test/block_to_hex_string.cpp new file mode 100644 index 0000000..6a89867 --- /dev/null +++ b/test/block_to_hex_string.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +#include + +int main() +{ + std::cout << "Testing block_to_hex_string function" << std::endl; + + // Generate all posible values for 1 byte + std::cout << "Generating all posibilities" << std::endl; + + std::vector> test_values; + test_values.reserve(256); + std::stringstream ss(""); + + for (uint8_t i = 0; i <= 0xff; i++) { + ss << std::hex << unsigned(i); + test_values.push_back(std::make_pair(i,(ss.str().size()==2)? ss.str() : "0" + ss.str())); + ss.str(""); + if (i == 0xff) + break; + } + + // Test function + std::cout << "Testing" << std::endl; + + std::string value(""); + for (uint8_t i = 0; i < 0xff;i++) { + uint8_t block[2] = {test_values[(int)i].first,test_values[((int)i)+1].first}; + value = ByteConvert::block_to_hex_string(block,2); + if (value != (test_values[(int)i].second + test_values[((int)i)+1].second)) { + std::cout << "Expected: " << (test_values[(int)i].second + test_values[((int)i)+1].second) << " Got: " << value << std::endl; + return -1; + } + if (i == 0xff) + break; + } + + std::cout << "Done" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/test/byte_to_hex.cpp b/test/byte_to_hex.cpp new file mode 100644 index 0000000..0d2934a --- /dev/null +++ b/test/byte_to_hex.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +#include + +int main() +{ + std::cout << "Testing byte_to_hex function" << std::endl; + + // Generate all posible values for 1 byte + std::cout << "Generating all posibilities" << std::endl; + + std::vector> test_values; + test_values.reserve(256); + std::stringstream ss(""); + + for (uint8_t i = 0; i <= 0xff; i++) { + ss << std::hex << unsigned(i); + test_values.push_back(std::make_pair(i,(ss.str().size()==2)? ss.str() : "0" + ss.str())); + ss.str(""); + if (i == 0xff) + break; + } + + // Test function + std::cout << "Testing" << std::endl; + + std::string value(""); + for (uint8_t i = 0; i <= 0xff; i++) { + value = ByteConvert::byte_to_hex(test_values[(int)i].first); + if (value != test_values[(int)i].second) { + std::cout << "Expected: " << test_values[(int)i].second << " Got: " << value << std::endl; + return -1; + } + if (i == 0xff) + break; + } + + std::cout << "Done" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/test/hex_string_to_block.cpp b/test/hex_string_to_block.cpp new file mode 100644 index 0000000..21c0d2b --- /dev/null +++ b/test/hex_string_to_block.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + +#include + +int main() +{ + std::cout << "Testing hex_string_to_block function" << std::endl; + + // Generate all posible values for 1 byte + std::cout << "Generating all posibilities" << std::endl; + + std::vector> test_values; + test_values.reserve(256); + std::stringstream ss(""); + + for (uint8_t i = 0; i <= 0xff; i++) { + ss << std::hex << unsigned(i); + test_values.push_back(std::make_pair(i,(ss.str().size()==2)? ss.str() : "0" + ss.str())); + ss.str(""); + if (i == 0xff) + break; + } + + // Test odd length hex strings + std::cout << "Testing" << std::endl; + + size_t block_size = 0; + std::string inval(""); + for (uint8_t i = 0; i < 0xff;i++) { + inval = test_values[(int)i].second + test_values[((int)i)+1].second; + std::unique_ptr block(ByteConvert::hex_string_to_block(inval,&block_size)); + if (block_size != 2 || block[0] != test_values[(int)i].first || block[1] != test_values[((int)i)+1].first) { + uint8_t bl1[2] = {test_values[(int)i].first, test_values[((int)i)+1].first}; + uint8_t bl2[2] = {block[0], block[1]}; + std::cout << "Expected: " << ByteConvert::block_to_hex_string(bl1,2) << " Got: " << ByteConvert::block_to_hex_string(bl2,2) << std::endl; + return -1; + } + if (i == 0xff) + break; + } + + // Test even length hex strings + for (uint8_t i = 0; i < 0xff;i++) { + inval = test_values[(int)i].second[1] + test_values[((int)i)+1].second; + std::unique_ptr block(ByteConvert::hex_string_to_block(inval,&block_size)); + if (block_size != 2 || block[0] != static_cast(test_values[(int)i].first & 0x0f) || block[1] != test_values[((int)i)+1].first) { + uint8_t bl1[2] = {static_cast(test_values[(int)i].first & 0x0f), test_values[((int)i)+1].first}; + uint8_t bl2[2] = {block[0], block[1]}; + std::cout << "Expected: " << ByteConvert::block_to_hex_string(bl1,2) << " Got: " << ByteConvert::block_to_hex_string(bl2,2) << std::endl; + return -1; + } + if (i == 0xff) + break; + } + + std::cout << "Done" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/test/hex_to_byte.cpp b/test/hex_to_byte.cpp new file mode 100644 index 0000000..df1963a --- /dev/null +++ b/test/hex_to_byte.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +#include + +int main() +{ + std::cout << "Testing hex_to_byte function" << std::endl; + + // Generate all posible values for 1 byte + std::cout << "Generating all posibilities" << std::endl; + + std::vector> test_values; + test_values.reserve(256); + std::stringstream ss(""); + + for (uint8_t i = 0; i <= 0xff; i++) { + ss << std::hex << unsigned(i); + test_values.push_back(std::make_pair(i,(ss.str().size()==2)? ss.str() : "0" + ss.str())); + ss.str(""); + if (i == 0xff) + break; + } + + // Test function + std::cout << "Testing" << std::endl; + + uint8_t value; + for (uint8_t i = 0; i <= 0xff; i++) { + value = ByteConvert::hex_to_byte(test_values[(int)i].second); + if (value != test_values[(int)i].first) { + std::cout << "Expected: " << unsigned(test_values[(int)i].first) << " Got: " << unsigned(value) << std::endl; + return -1; + } + if (i == 0xff) + break; + } + + std::cout << "Done" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000..414a396 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,15 @@ +# List of tests +tests = [ + ['byte_to_hex',['byte_to_hex.cpp']], + ['hex_to_byte',['hex_to_byte.cpp']], + ['block_to_hex_string',['block_to_hex_string.cpp']], + ['hex_string_to_block',['hex_string_to_block.cpp']], + ['to_block',['to_block.cpp']], + ['to_variable',['to_variable.cpp']] +] + +# Compile all test +foreach test: tests + exe = executable(test[0], test[1], link_with: libbyteconvert, include_directories: libbyteconvert_include) + test(test[0],exe) +endforeach diff --git a/test/to_block.cpp b/test/to_block.cpp new file mode 100644 index 0000000..da8aba3 --- /dev/null +++ b/test/to_block.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include + +int main() +{ + std::cout << "Testing to_block function" << std::endl; + + std::cout << "Testing" << std::endl; + + // Test int + int int_var = 1; + size_t int_size; + std::unique_ptr int_res(ByteConvert::to_block(int_var,&int_size)); + for (size_t i = 0; i < int_size; i++) { + if (i != int_size - 1 && int_res[i] != 0x00) { + std::cout << "Expected: 0 Got: " << unsigned(int_res[i]) << std::endl; + } else if (i == int_size - 1 && int_res[i] != 0x01) { + std::cout << "Expected: 1 Got: " << unsigned(int_res[i]) << std::endl; + } + } + + int int_var1 = -1; + size_t int_size1; + std::unique_ptr int_res1(ByteConvert::to_block(int_var1,&int_size1)); + for (size_t i = 0; i < int_size1; i++) { + if (int_res1[i] != 0xff) { + std::cout << "Expected: 255 Got: " << unsigned(int_res1[i]) << std::endl; + } + } + + // Test uint8_t + uint8_t uint8_var = 2; + size_t uint8_size; + std::unique_ptr uint8_res(ByteConvert::to_block(uint8_var,&uint8_size)); + for (size_t i = 0; i < uint8_size; i++) { + if (uint8_res[i] != 0x02) { + std::cout << "Expected: 2 Got: " << unsigned(uint8_res[i]) << std::endl; + } + } + + + std::cout << "Done" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/test/to_variable.cpp b/test/to_variable.cpp new file mode 100644 index 0000000..60ebf33 --- /dev/null +++ b/test/to_variable.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include + +int main() +{ + // Create array of bytes that represent 1 (type: int) + uint8_t block[sizeof(int)]; + memset(block,0,sizeof(int)-1); + block[sizeof(int)-1] = 1; + + int val = ByteConvert::to_variable(block); // Convert array of bytes to int + if (val != 1) { // Check if we got, what we expected to get + // Error, something went wrong + return -1; + } + + // Test with negative values + memset(block,0xff,sizeof(int)); + val = ByteConvert::to_variable(block); // Convert array of bytes to int + if (val != -1) { // Check if we got, what we expected to get + // Error, something went wrong + return -2; + } + + // Success + return 0; +} \ No newline at end of file