fragments

This commit is contained in:
Matthew Kennedy 2022-07-18 13:14:51 -07:00
parent 7fea28f1c1
commit 9554b4d674
4 changed files with 165 additions and 0 deletions

View File

@ -0,0 +1,31 @@
/*
* FragmentEntry.h
*
* Created on: Jan 5, 2022
* @author Andrey Belomutskiy, (c) 2012-2022
*/
#pragma once
#include <cstddef>
#include <cstdint>
struct FragmentEntry {
template <typename TData>
FragmentEntry(const TData* data)
: data(reinterpret_cast<const uint8_t*>(data))
, size(sizeof(TData))
{
}
const uint8_t* const data;
const size_t size;
};
struct FragmentList {
const FragmentEntry* fragments;
const size_t count;
};
// 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);

44
util/src/fragments.cpp Normal file
View File

@ -0,0 +1,44 @@
/*
* FragmentEntry.cpp
*
* Created on: Jan 5, 2022
* @author Andrey Belomutskiy, (c) 2012-2022
*/
#include <rusefi/fragments.h>
#include <rusefi/math.h>
#include <cstring>
void copyRange(uint8_t* destination, FragmentList src, size_t skip, size_t size) {
int fragmentIndex = 0;
// Find which fragment to start - skip any full fragments smaller than `skip` parameter
while (skip > src.fragments[fragmentIndex].size && fragmentIndex <= src.count) {
skip -= src.fragments[fragmentIndex].size;
fragmentIndex++;
}
int destinationIndex = 0;
while (size > 0) {
if (fragmentIndex >= src.count) {
// somehow we are past the end of fragments - fill with zeros
memset(destination + destinationIndex, 0, size);
return;
}
int copyNowSize = minI(size, src.fragments[fragmentIndex].size - skip);
const uint8_t* fromBase = src.fragments[fragmentIndex].data;
if (!fromBase) {
// we have no buffer for this fragment - fill with zeroes
memset(destination + destinationIndex, 0, copyNowSize);
} else {
memcpy(destination + destinationIndex, fromBase + skip, copyNowSize);
}
destinationIndex += copyNowSize;
skip = 0;
size -= copyNowSize;
fragmentIndex++;
}
}

View File

@ -0,0 +1,88 @@
#include <rusefi/fragments.h>
struct obj1 {
const uint8_t x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
};
static_assert(sizeof(obj1) == 10);
struct obj2 {
const uint8_t x[5] = { 11, 12, 13, 14, 15 };
};
static_assert(sizeof(obj2) == 5);
obj1 buffer10;
obj2 buffer5;
static FragmentEntry fragmentBuffer[] = {
&buffer10,
&buffer5,
reinterpret_cast<obj2*>(0), // null fragment for fun
&buffer10
};
static uint8_t buffer[120];
static void resetBuffer() {
memset(buffer, 0xFF, sizeof(buffer));
}
TEST(outputs, fragments) {
static_assert(4 == efi::size(fragmentBuffer));
FragmentList fragments{ fragmentBuffer, efi::size(fragmentBuffer) };
resetBuffer();
{
// Check overlap between first and second fragments
uint8_t expected[] = {9, 10, 11, 12, 13};
copyRange(buffer, fragments, 8, 5);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
resetBuffer();
{
// Check partial of only second fragment
uint8_t expected[] = {13, 14, 15};
copyRange(buffer, fragments, 12, 3);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
resetBuffer();
{
// Check overlap between second fragment and null fragment
uint8_t expected[] = {15, 0, 0};
copyRange(buffer, fragments, 14, 3);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
resetBuffer();
{
// Check overlap between null fragment and 4th fragment
uint8_t expected[] = {0, 1, 2};
copyRange(buffer, fragments, 19, 3);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
resetBuffer();
{
// Check overlap between last fragment and off-end of buffer (off-buffer should give 0s)
uint8_t expected[] = {9, 10, 0, 0};
copyRange(buffer, fragments, 28, 4);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
resetBuffer();
{
// Check way off the end of the buffer
uint8_t expected[] = {0, 0, 0};
copyRange(buffer, fragments, 1000, 3);
EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected)));
}
}

View File

@ -3,9 +3,11 @@ RUSEFI_LIB_INC += $(RUSEFI_LIB)/util/include
RUSEFI_LIB_CPP += \
$(RUSEFI_LIB)/util/src/util_dummy.cpp \
$(RUSEFI_LIB)/util/src/crc.cpp \
$(RUSEFI_LIB)/util/src/fragments.cpp \
$(RUSEFI_LIB)/util/src/math.cpp \
RUSEFI_LIB_CPP_TEST += \
$(RUSEFI_LIB)/util/test/test_arrays.cpp \
$(RUSEFI_LIB)/util/test/test_framgents.cpp \
$(RUSEFI_LIB)/util/test/test_math.cpp \