diff --git a/CMakeLists.txt b/CMakeLists.txt index 29884c5..9c74384 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.12) project(network_packet_composer) -set(CMAKE_CXX_FLAGS "--std=c++14 -g -Wall") +set(CMAKE_CXX_FLAGS "-std=c++14 -g -Wall") # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/doc/model.md b/doc/model.md index 85f485e..d959a81 100644 --- a/doc/model.md +++ b/doc/model.md @@ -1,8 +1,8 @@ # NPC core ```plantuml -abstract class ARepository -abstract class ARepositoryFactory + + class RepositoryFactory class Repository { +addStructure() @@ -10,10 +10,10 @@ class Repository { +getStructure() } -abstract class AStackModelFactory + class StackModelFactory -abstract class AStackModel + class StackModel { +getBinary():byte[] +getStructures():Structure[] @@ -21,9 +21,9 @@ class StackModel { +removeStructure() } -abstract class AStructureFactory + class StructureFactory -abstract class AStructure + class Structure { -name -description @@ -34,15 +34,15 @@ class Structure { +updateData() } -abstract class AFieldFactory{ + +class FieldFactory{ + createField() + createFieldBinaryInformation() + createFieldLogicalInformation() + createFieldVisualInformation() + createFieldRepresentation() } -class FieldFactory -abstract class AField + class Field { - owningStructure - binary @@ -81,22 +81,14 @@ class RandomAccessBinary { + get_hex_string() } -ARepositoryFactory <|-- RepositoryFactory -ARepository <|-- Repository RepositoryFactory --> Repository : creates > -AStackModelFactory <|-- StackModelFactory -AStackModel <|-- StackModel StackModelFactory --> StackModel: creates > -AStructureFactory <|-- StructureFactory -AStructure <|-- Structure StructureFactory --> Structure : creates > StackModel *-- Structure Repository *-- Structure -AFieldFactory <|-- FieldFactory -AField <|-- Field FieldFactory --> Field : creates > Structure *-- Field diff --git a/src/core/RandomAccessBinary.cpp b/src/core/RandomAccessBinary.cpp index 352ec25..8a588e5 100644 --- a/src/core/RandomAccessBinary.cpp +++ b/src/core/RandomAccessBinary.cpp @@ -1,17 +1,18 @@ #include "RandomAccessBinary.h" #include #include +#include +#include +#include -RandomAccessBinary::RandomAccessBinary() -{ - this->ptr_data = std::make_unique>(); - this->ptr_data->reserve(1548); -} +RandomAccessBinary::RandomAccessBinary() : RandomAccessBinary(1548) +{} RandomAccessBinary::RandomAccessBinary(uint possible_packetsize) { this->ptr_data = std::make_unique>(); this->ptr_data->reserve(possible_packetsize); + this->endianness = RandomAccessBinary::Endianness::BIG; } RandomAccessBinary::~RandomAccessBinary() @@ -19,7 +20,7 @@ RandomAccessBinary::~RandomAccessBinary() } -const RandomAccessBinary::Endianness RandomAccessBinary::getEndianness() +RandomAccessBinary::Endianness RandomAccessBinary::getEndianness() { return this->endianness; } @@ -31,32 +32,34 @@ void RandomAccessBinary::setEndianness(RandomAccessBinary::Endianness endianness void RandomAccessBinary::setBytes(uint position, const std::vector &data) { + auto it = this->ptr_data->begin(); for(uint i = 0; i < data.size(); ++i) - (*this->ptr_data)[position+i] = data[i]; + this->ptr_data->insert(it+(position+i), data[i]); } void RandomAccessBinary::setByte(uint position, const uint8_t &data) { - (*this->ptr_data)[position] = data; + auto it = this->ptr_data->begin(); + this->ptr_data->insert(it+position, data); } void RandomAccessBinary::setBit(uint64_t position, const bool &value) { - uint64_t bytePosition = position>>3; + uint bytePosition = static_cast(position>>3); uint bitPosition = position%8; this->setBit(bytePosition, bitPosition, value); } void RandomAccessBinary::setBit(uint bytePosition, uint bitPosition, const bool &value) { - uint8_t byte = (*this->ptr_data)[bytePosition]; + uint8_t byte = this->ptr_data->at(bytePosition); uint8_t newbyte = 1; if (value) newbyte = byte | (newbyte << (7-bitPosition)); else { newbyte = byte & ~(newbyte << (7-bitPosition)); } - (*this->ptr_data)[bytePosition] = newbyte; + ptr_data->insert(ptr_data->begin()+bytePosition, newbyte); } void RandomAccessBinary::setBits(uint64_t position, uint bits, const uint8_t &value) @@ -68,7 +71,7 @@ void RandomAccessBinary::setBits(uint64_t position, uint bits, const uint8_t &va void RandomAccessBinary::setBits(uint bytePosition, uint bitPosition, uint bits, const uint8_t &value) { - uint8_t byte = (*this->ptr_data)[bytePosition]; + uint8_t byte = this->ptr_data->at(bytePosition); uint8_t newbyte = value; uint8_t mask = 0; for(uint i = bits-1; i >= 0; --i) @@ -77,94 +80,81 @@ void RandomAccessBinary::setBits(uint bytePosition, uint bitPosition, uint bits, byte &= ~mask; newbyte <<= (7-bits-bitPosition); byte |= newbyte; - (*this->ptr_data)[bytePosition] = byte; + ptr_data->insert(ptr_data->begin()+bytePosition, byte); } void RandomAccessBinary::set_uint16(uint byteOffset, const uint16_t &data) { - if (this->endianness == Endianness::BIG) { - this->setByte(byteOffset, (uint8_t)(data >> 8)); - this->setByte(byteOffset+1, (uint8_t)(data & 0x0FF)); - } else if (this->endianness == Endianness::LITTLE) { - this->setByte(byteOffset, (uint8_t)(data & 0x0FF)); - this->setByte(byteOffset+1, (uint8_t)(data >> 8)); - } else { - //TODO - } + uint8_t * conv = (uint8_t*)&data; + std::vector tmp; + tmp.assign(conv, conv+sizeof(uint16_t)); + if (this->endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + this->setBytes(byteOffset, tmp); } void RandomAccessBinary::set_uint32(uint byteOffset, const uint32_t &data) { - if (this->endianness == Endianness::BIG) { - this->setByte(byteOffset+0, (uint8_t)((data >> 24) & 0x0FF)); - this->setByte(byteOffset+1, (uint8_t)((data >> 16) & 0x0FF)); - this->setByte(byteOffset+2, (uint8_t)((data >> 8) & 0x0FF)); - this->setByte(byteOffset+3, (uint8_t)(data & 0x0FF)); - } else if (this->endianness == Endianness::LITTLE) { - this->setByte(byteOffset+3, (uint8_t)((data >> 24) & 0x0FF)); - this->setByte(byteOffset+2, (uint8_t)((data >> 16) & 0x0FF)); - this->setByte(byteOffset+1, (uint8_t)((data >> 8) & 0x0FF)); - this->setByte(byteOffset+0, (uint8_t)(data & 0x0FF)); - } + uint8_t * conv = (uint8_t*)&data; + std::vector tmp; + tmp.assign(conv, conv+sizeof(uint32_t)); + if (this->endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + this->setBytes(byteOffset, tmp); } void RandomAccessBinary::set_uint64(uint byteOffset, const uint64_t &data) { - if (this->endianness == Endianness::BIG) { - this->setByte(byteOffset+0, (uint8_t)((data >> 56) & 0x0FF)); - this->setByte(byteOffset+1, (uint8_t)((data >> 48) & 0x0FF)); - this->setByte(byteOffset+2, (uint8_t)((data >> 40) & 0x0FF)); - this->setByte(byteOffset+3, (uint8_t)((data >> 32) & 0x0FF)); - this->setByte(byteOffset+4, (uint8_t)((data >> 24) & 0x0FF)); - this->setByte(byteOffset+5, (uint8_t)((data >> 16) & 0x0FF)); - this->setByte(byteOffset+6, (uint8_t)((data >> 8) & 0x0FF)); - this->setByte(byteOffset+7, (uint8_t)(data & 0x0FF)); - } else if (this->endianness == Endianness::LITTLE) { - this->setByte(byteOffset+7, (uint8_t)((data >> 56) & 0x0FF)); - this->setByte(byteOffset+6, (uint8_t)((data >> 48) & 0x0FF)); - this->setByte(byteOffset+5, (uint8_t)((data >> 40) & 0x0FF)); - this->setByte(byteOffset+4, (uint8_t)((data >> 32) & 0x0FF)); - this->setByte(byteOffset+3, (uint8_t)((data >> 24) & 0x0FF)); - this->setByte(byteOffset+2, (uint8_t)((data >> 16) & 0x0FF)); - this->setByte(byteOffset+1, (uint8_t)((data >> 8) & 0x0FF)); - this->setByte(byteOffset+0, (uint8_t)(data & 0x0FF)); - } + uint8_t * conv = (uint8_t*)&data; + std::vector tmp; + tmp.assign(conv, conv+sizeof(uint64_t)); + if (this->endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + this->setBytes(byteOffset, tmp); } void RandomAccessBinary::set_float(uint position, float &data) { - float * conv = &data; - this->set_uint32(position, *conv); + uint8_t * conv = (uint8_t*)&data; + std::vector tmp; + tmp.assign(conv, conv+sizeof(float)); + if (this->endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + this->setBytes(position, tmp); } void RandomAccessBinary::set_double(uint position, double &data) { - double * conv = &data; - this->set_uint64(position, *conv); + uint8_t * conv = (uint8_t*)&data; + std::vector tmp; + tmp.assign(conv, conv+sizeof(double)); + if (this->endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + this->setBytes(position, tmp); } uint8_t RandomAccessBinary::getByte(uint position) { - return (*this->ptr_data)[position]; + return this->ptr_data->at(position); } const std::vector RandomAccessBinary::getBytes(uint position, uint length) { - std::vector vec; - for(uint i = position; i< position+length; ++i) - vec.push_back((*this->ptr_data)[i]); + auto begin = ptr_data->begin() + position; + auto end = ptr_data->begin() + position + length; + std::vector vec(begin, end); return vec; } bool RandomAccessBinary::getBit(uint byteOffset, uint bitOffset) { - uint8_t byte = (*this->ptr_data)[byteOffset]; + uint8_t byte = this->ptr_data->at(byteOffset); return (byte & (1 << (7-bitOffset))) > 0; } bool RandomAccessBinary::getBit(uint64_t position) { - uint64_t byteOffset = position>>3; + uint byteOffset = static_cast(position>>3); uint bitOffset = position%8; return this->getBit(byteOffset, bitOffset); } @@ -181,40 +171,95 @@ const std::vector RandomAccessBinary::getBits(uint64_t position, uint64_t uint16_t RandomAccessBinary::get_uint16(uint byteOffset) { + auto tmp = getBytes(byteOffset, sizeof(uint16_t)); + if (endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + if (tmp.data() != nullptr) { + uint16_t* d = (uint16_t*)tmp.data(); + return *d; + } return 0; } uint32_t RandomAccessBinary::get_uint32(uint byteOffset) { + auto tmp = getBytes(byteOffset, sizeof(uint32_t)); + if (endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + if (tmp.data() != nullptr) { + uint32_t* d = (uint32_t*)tmp.data(); + return *d; + } return 0; } uint64_t RandomAccessBinary::get_uint64(uint byteOffset) { + auto tmp = getBytes(byteOffset, sizeof(uint64_t)); + if (endianness != Endianness::LITTLE) + std::reverse(tmp.begin(), tmp.end()); + if (tmp.data() != nullptr) { + uint64_t* d = (uint64_t*)tmp.data(); + return *d; + } return 0; } float RandomAccessBinary::get_float(uint byteOffset) { - return 0.0f; + float tmp = 0.0; + auto bytes = this->getBytes(byteOffset, sizeof(float)); + uint8_t* ptr_tmp = (uint8_t*)&tmp; + if (endianness != Endianness::LITTLE) { + std::reverse(std::begin(bytes), std::end(bytes)); + } + uint8_t i = 0; + for(auto it = bytes.begin(); it != bytes.end();++it, ++i) + *(ptr_tmp+i) = *it; + return tmp; } double RandomAccessBinary::get_double(uint byteOffset) { - return 0.0; + double tmp = 0.0; + auto bytes = this->getBytes(byteOffset, sizeof(double)); + uint8_t* ptr_tmp = (uint8_t*)&tmp; + if (endianness != Endianness::LITTLE) { + std::reverse(std::begin(bytes), std::end(bytes)); + } + uint8_t i = 0; + for(auto it = bytes.begin(); it != bytes.end();++it, ++i) + *(ptr_tmp+i) = *it; + return tmp; } std::__cxx11::string RandomAccessBinary::get_string(uint byteOffset, uint length) { - return ""; + std::stringstream output; + uint i = 0; + for(auto it = ptr_data->begin(); it != ptr_data->end() && i < length; ++it, ++i) { + output << *it; + } + return output.str(); } std::__cxx11::string RandomAccessBinary::get_hex_string(uint byteOffset, uint length) { - return ""; + std::stringstream output; + output << std::hex << std::noshowbase << std::right << std::setfill('0'); + uint i = 0; + for(auto it = ptr_data->begin()+byteOffset; it != ptr_data->end() && i < length; ++it, ++i) { + output << std::setw(2) << static_cast(*it); + } + return output.str(); } std::__cxx11::string RandomAccessBinary::get_hex_string() { - return ""; + std::stringstream output; + output << std::hex << std::noshowbase << std::right << std::setfill('0'); + for(auto it = ptr_data->begin(); it != ptr_data->end(); ++it) { + output << std::setw(2) << static_cast(*it); + } + return output.str(); } diff --git a/src/core/RandomAccessBinary.h b/src/core/RandomAccessBinary.h index 5846fb9..3eb4cb3 100644 --- a/src/core/RandomAccessBinary.h +++ b/src/core/RandomAccessBinary.h @@ -19,7 +19,9 @@ public: virtual ~RandomAccessBinary(); void setEndianness(Endianness endianess); - const Endianness getEndianness(); + Endianness getEndianness(); + + void clear() { ptr_data->clear(); } void setBytes(uint position, const std::vector& data); void setByte(uint position, const uint8_t& data); @@ -61,6 +63,8 @@ public: std::string get_hex_string(uint byteOffset, uint length); std::string get_hex_string(); + + uint64_t size() { return ptr_data->size(); } private: std::unique_ptr> ptr_data; Endianness endianness; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 275686b..3093124 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,8 +6,9 @@ INCLUDE_DIRECTORIES(/usr/include/gtest) set(SOURCES core/test_tree.cpp + core/test_rab.cpp ) add_executable(runUnitTests ${SOURCES}) -target_link_libraries(runUnitTests gtest gtest_main) +target_link_libraries(runUnitTests gtest gtest_main core) add_test(runUnitTests runUnitTests) diff --git a/test/core/test_rab.cpp b/test/core/test_rab.cpp new file mode 100644 index 0000000..36a86ba --- /dev/null +++ b/test/core/test_rab.cpp @@ -0,0 +1,92 @@ + +#include +#include +#include "gtest/gtest.h" +#include "../src/core/RandomAccessBinary.h" + +class RABTest : public ::testing::Test { +protected: + virtual void SetUp(){ + uint64_t bigdata = 0x0CAFEBABE; + test2.set_uint64(0, bigdata); + test4.setEndianness(RandomAccessBinary::Endianness::LITTLE); + } + + virtual void TearDown(){ + test.clear(); + test2.clear(); + test3.clear(); + test4.clear(); + } + + RandomAccessBinary test; + RandomAccessBinary test2; + RandomAccessBinary test3; + RandomAccessBinary test4; +}; + +TEST_F(RABTest, IsEmptyInitially) { + EXPECT_EQ(0, test.size()); + EXPECT_EQ("", test.get_hex_string()); +} + +TEST_F(RABTest, SomeData) { + EXPECT_EQ(8, test2.size()); + EXPECT_EQ("00000000cafebabe", test2.get_hex_string()); + EXPECT_EQ("cafebabe", test2.get_hex_string(4,4)); +} + +TEST_F(RABTest, Double) { + //double a = 3.1415; + double a = 2.7182818284; + test3.set_double(0, a); + EXPECT_EQ("4005bf0a8b12500b", test3.get_hex_string()); + EXPECT_DOUBLE_EQ(2.7182818284, test3.get_double(0)); + // LITTLE ENDIAN + test4.set_double(0, a); + EXPECT_EQ("0b50128b0abf0540", test4.get_hex_string()); + EXPECT_DOUBLE_EQ(2.7182818284, test4.get_double(0)); +} + +TEST_F(RABTest, Float) { + float a = 2.71828f; + test3.set_float(0, a); + EXPECT_EQ("402df84d", test3.get_hex_string()); + EXPECT_FLOAT_EQ(2.71828f, test3.get_float(0)); + // LITTLE ENDIAN + test4.set_float(0, a); + EXPECT_EQ("4df82d40", test4.get_hex_string()); + EXPECT_FLOAT_EQ(2.71828f, test4.get_float(0)); +} + +TEST_F(RABTest, VariousInteger) { + uint8_t byte = 42; + uint16_t a_short = 31337; + uint32_t a_int = 0xdeadbeef; + uint64_t a_long = 0xcafebabedeadbeef; + + test3.setByte(0, byte); + test3.set_uint16(1, a_short); + test3.set_uint32(3, a_int); + test3.set_uint64(7, a_long); + + test4.setByte(0, byte); + test4.set_uint16(1, a_short); + test4.set_uint32(3, a_int); + test4.set_uint64(7, a_long); + std::cout << "BIG ENDIAN: " << test3.get_hex_string() << std::endl; + std::cout << "LITTLE ENDIAN: "<< test4.get_hex_string() << std::endl; + EXPECT_EQ("2a7a69deadbeefcafebabedeadbeef", test3.get_hex_string()); + EXPECT_EQ("2a697aefbeaddeefbeaddebebafeca", test4.get_hex_string()); +} + +TEST_F(RABTest, Strings) { + std::string a = "Dies ist ein Test."; + test3.setBytes(0, std::vector(a.begin(), a.end())); + EXPECT_EQ("Dies ist ein Test.", test3.get_string(0, test3.size())); + EXPECT_EQ("44696573206973742065696e20546573742e", test3.get_hex_string()); +} + +TEST_F(RABTest, Bits) { + +}