Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress on #235, adding unaligned copy. #266

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,32 @@
"functional": "cpp",
"iomanip": "cpp",
"ratio": "cpp",
"thread": "cpp"
"thread": "cpp",
"__bit_reference": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__functional_base": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__mutex_base": "cpp",
"__node_handle": "cpp",
"__nullptr": "cpp",
"__split_buffer": "cpp",
"__string": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__tuple": "cpp",
"atomic": "cpp",
"bitset": "cpp",
"cstdarg": "cpp",
"ios": "cpp",
"iterator": "cpp",
"locale": "cpp",
"map": "cpp",
"mutex": "cpp",
"set": "cpp",
"string": "cpp"
},
"C_Cpp.default.cppStandard": "c++11",
"C_Cpp.default.cStandard": "c99",
Expand Down
94 changes: 94 additions & 0 deletions libuavcan/include/libuavcan/platform/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,100 @@ class LIBUAVCAN_EXPORT PoolAllocator
}
};

/**
* Copy bits from a byte array using arbitrary alignment to an aligned byte array.
*
* @param src The byte array to copy from.
* @param src_offset_bits The offset, in bits, from the start of the src array to
* start copying from.
* @param dst The byte array to copy data into.
* @param length_bits The total length of bits to copy. The caller must ensure
* that the size of src and dst are >= this value.
*
* @return The number of bits copied.
*/
inline std::size_t copyBitsUnalignedToAligned(const std::uint8_t* const src,
const std::size_t src_offset_bits,
std::uint8_t* const dst,
const std::size_t length_bits)
{
if (nullptr == src || nullptr == dst || length_bits == 0)
{
return 0;
}
std::size_t bits_copied = 0;
std::size_t offset_bits = src_offset_bits;
const std::size_t local_offset = src_offset_bits % 8U;
do
{
std::size_t current_byte = offset_bits / 8U;
const std::size_t bits_from_src_byte = 8U - local_offset;
bits_copied += std::min(length_bits, bits_from_src_byte);
dst[current_byte] &= static_cast<std::uint8_t>(0xFF << bits_from_src_byte);
dst[current_byte] |= static_cast<std::uint8_t>(src[current_byte] >> local_offset);
offset_bits += 8U;
if (offset_bits < length_bits)
{
current_byte = offset_bits / 8U;
dst[current_byte] = static_cast<std::uint8_t>(src[current_byte] << bits_from_src_byte);
bits_copied += local_offset;
}
else
{
// we don't need to reevaluate the while condition.
break;
}
} while (true);
thirtytwobits marked this conversation as resolved.
Show resolved Hide resolved
return bits_copied;
}

/**
* Copy aligned bits from a byte array to another byte array using arbitrary alignment.
*
* @param src The byte array to copy from.
* @param dst The byte array to copy data into.
* @param dst_offset_bits The offset, in bits, from the start of the dst array to
* start writing to.
* @param length_bits The total length of bits to copy. The caller must ensure
* that the size of src and dst are >= this value.
*
* @return The number of bits copied.
*/
inline std::size_t copyBitsAlignedToUnaligned(const std::uint8_t* const src,
std::uint8_t* const dst,
const std::size_t dst_offset_bits,
const std::size_t length_bits)
{
if (nullptr == src || nullptr == dst || length_bits == 0)
{
return 0;
}
std::size_t bits_copied = 0;
std::size_t offset_bits = dst_offset_bits;
const std::size_t local_offset = dst_offset_bits % 8U;
do
{
std::size_t current_byte = offset_bits / 8U;
const std::size_t bits_from_src_byte = 8U - local_offset;
dst[current_byte] &= static_cast<std::uint8_t>(0xFF >> bits_from_src_byte);
dst[current_byte] |= static_cast<std::uint8_t>(src[current_byte] << local_offset);
offset_bits += 8U;
bits_copied += std::min(length_bits, bits_from_src_byte);
if (offset_bits < length_bits)
{
dst[current_byte] |= static_cast<std::uint8_t>(src[offset_bits / 8U] >> bits_from_src_byte);
bits_copied += local_offset;
}
else
{
// we don't need to reevaluate the while condition.
break;
}
} while (true);

return bits_copied;
}

} // namespace memory
} // namespace platform
} // namespace libuavcan
Expand Down
1 change: 1 addition & 0 deletions libuavcan_validation_suite/include/lvs/lvs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define LIBUAVCAN_LVS_HPP_INCLUDED

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "libuavcan/libuavcan.hpp"

#include <ostream>
Expand Down
Loading