From 663174265d842cbd38c096023c750ab68e74221f Mon Sep 17 00:00:00 2001 From: Andrey Gusakov Date: Wed, 21 Dec 2022 12:36:00 +0300 Subject: [PATCH 1/2] fragments: getRangePtr() helper for memcpy-less access to fragments data --- util/include/rusefi/fragments.h | 3 +++ util/src/fragments.cpp | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/util/include/rusefi/fragments.h b/util/include/rusefi/fragments.h index cdf1530..2032798 100644 --- a/util/include/rusefi/fragments.h +++ b/util/include/rusefi/fragments.h @@ -49,3 +49,6 @@ struct FragmentList { // copy `size` of fragmented outputs in to destination, skipping the first `skip` bytes void copyRange(uint8_t* destination, FragmentList src, size_t skip, size_t size); +// returns pointer to actual data and size of contiguous data +// if data is located in more than one fragmnet - returned value will be size available in first fragment +size_t getRangePtr(uint8_t **ptr, FragmentList src, size_t offset, size_t size); diff --git a/util/src/fragments.cpp b/util/src/fragments.cpp index 1311d8a..e482f22 100644 --- a/util/src/fragments.cpp +++ b/util/src/fragments.cpp @@ -42,3 +42,26 @@ void copyRange(uint8_t* destination, FragmentList src, size_t skip, size_t size) fragmentIndex++; } } + +size_t getRangePtr(uint8_t **ptr, FragmentList src, size_t offset, size_t size) +{ + size_t fragmentIndex = 0; + + // Find which fragment to start - skip any full fragments smaller than `skip` parameter + while (fragmentIndex < src.count && offset >= src.fragments[fragmentIndex].size) { + offset -= src.fragments[fragmentIndex].size; + fragmentIndex++; + } + + if (fragmentIndex >= src.count) { + // out of range + *ptr = NULL; + return size; + } + + if (src.fragments[fragmentIndex].get() != NULL) + *ptr = (uint8_t *)src.fragments[fragmentIndex].get() + offset; + else + *ptr = NULL; + return minI(size, src.fragments[fragmentIndex].size - offset); +} From 753970a0565950a0cee91bc55c75a163b10a7966 Mon Sep 17 00:00:00 2001 From: Andrey Gusakov Date: Wed, 21 Dec 2022 13:16:19 +0300 Subject: [PATCH 2/2] fragments: getRangePtr(): tests --- util/test/test_fragments.cpp | 90 ++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/util/test/test_fragments.cpp b/util/test/test_fragments.cpp index 2e2c4db..0c2c830 100644 --- a/util/test/test_fragments.cpp +++ b/util/test/test_fragments.cpp @@ -63,6 +63,36 @@ TEST(Util_Fragments, fragments) { }; copyRange(buffer, fragments, 0, 10 + 5 + 5 + 10); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t offset = 0; + size_t ret; + /* pointer to first fragment */ + ret = getRangePtr(&ptr, fragments, offset, 10 + 5 + 5 + 10); + EXPECT_TRUE( 10 == ret); + EXPECT_TRUE( 0 == std::memcmp(ptr, expected, ret)); + EXPECT_TRUE( fragmentBuffer[0].get() == ptr); + + offset += ret; + /* pointer to second fragment */ + ret = getRangePtr(&ptr, fragments, offset, 5 + 5 + 10); + EXPECT_TRUE( 5 == ret); + EXPECT_TRUE( 0 == std::memcmp(ptr, expected + 10, ret)); + EXPECT_TRUE( fragmentBuffer[1].get() == ptr); + + offset += ret; + /* pointer to null */ + ret = getRangePtr(&ptr, fragments, offset, 5 + 10); + EXPECT_TRUE( 5 == ret); + EXPECT_TRUE( NULL == ptr); + EXPECT_TRUE( fragmentBuffer[2].get() == ptr); + + offset += ret; + /* pointer to fourth fragment */ + ret = getRangePtr(&ptr, fragments, offset, 10); + EXPECT_TRUE( 10 == ret); + EXPECT_TRUE( 0 == std::memcmp(ptr, expected + 10 + 5 + 5, ret)); + EXPECT_TRUE( fragmentBuffer[3].get() == ptr); } resetBuffer(); @@ -72,6 +102,18 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {9, 10, 11, 12, 13}; copyRange(buffer, fragments, 8, 5); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t offset = 8; + size_t ret; + ret = getRangePtr(&ptr, fragments, offset, 5); + EXPECT_TRUE( 2 == ret); + EXPECT_TRUE( fragmentBuffer[0].get() + 8 == ptr); + + offset += ret; + ret = getRangePtr(&ptr, fragments, offset, 5 - 2); + EXPECT_TRUE( 3 == ret); + EXPECT_TRUE( fragmentBuffer[1].get() + 0 == ptr); } resetBuffer(); @@ -81,6 +123,12 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {13, 14, 15}; copyRange(buffer, fragments, 12, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t ret; + ret = getRangePtr(&ptr, fragments, 12, 3); + EXPECT_TRUE( 3 == ret); + EXPECT_TRUE( fragmentBuffer[1].get() + 2 == ptr); } resetBuffer(); @@ -90,6 +138,18 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {15, 0, 0}; copyRange(buffer, fragments, 14, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t offset = 14; + size_t ret; + ret = getRangePtr(&ptr, fragments, offset, 5); + EXPECT_TRUE( 1 == ret); + EXPECT_TRUE( fragmentBuffer[1].get() + 4 == ptr); + + offset += ret; + ret = getRangePtr(&ptr, fragments, offset, 5 - 1); + EXPECT_TRUE( 4 == ret); + EXPECT_TRUE( NULL == ptr); } resetBuffer(); @@ -99,6 +159,18 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {0, 1, 2}; copyRange(buffer, fragments, 19, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t offset = 19; + size_t ret; + ret = getRangePtr(&ptr, fragments, offset, 3); + EXPECT_TRUE( 1 == ret); + EXPECT_TRUE( NULL == ptr); + + offset += ret; + ret = getRangePtr(&ptr, fragments, offset, 3 - 1); + EXPECT_TRUE( 2 == ret); + EXPECT_TRUE( fragmentBuffer[3].get() == ptr); } resetBuffer(); @@ -108,6 +180,18 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {9, 10, 0, 0}; copyRange(buffer, fragments, 28, 4); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t offset = 28; + size_t ret; + ret = getRangePtr(&ptr, fragments, offset, 4); + EXPECT_TRUE( 2 == ret); + EXPECT_TRUE( fragmentBuffer[3].get() + 8 == ptr); + + offset += ret; + ret = getRangePtr(&ptr, fragments, offset, 4 - 2); + EXPECT_TRUE( 2 == ret); + EXPECT_TRUE( NULL == ptr); } resetBuffer(); @@ -117,5 +201,11 @@ TEST(Util_Fragments, fragments) { uint8_t expected[] = {0, 0, 0}; copyRange(buffer, fragments, 1000, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + + uint8_t *ptr; + size_t ret; + ret = getRangePtr(&ptr, fragments, 1000, 3); + EXPECT_TRUE( 3 == ret); + EXPECT_TRUE( NULL == ptr); } }