Here's a slightly improved version of the patch that also removes the code
duplication in core.cpp and binarize.cpp.
--- a/src/LibBGCode/core/core.cpp
+++ b/src/LibBGCode/core/core.cpp
@@ -3,22 +3,6 @@
namespace bgcode { namespace core {
-template<class T>
-static bool write_to_file(FILE& file, const T* data, size_t data_size)
-{
- const size_t wsize = fwrite(static_cast<const void*>(data), 1, data_size, &file);
- return !ferror(&file) && wsize == data_size;
-}
-
-template<class T>
-static bool read_from_file(FILE& file, T *data, size_t data_size)
-{
- static_assert(!std::is_const_v<T>, "Type of output buffer cannot be const!");
-
- const size_t rsize = fread(static_cast<void *>(data), 1, data_size, &file);
- return !ferror(&file) && rsize == data_size;
-}
-
EResult verify_block_checksum(FILE& file, const FileHeader& file_header,
const BlockHeader& block_header, std::byte* buffer, size_t buffer_size)
{
@@ -112,11 +96,11 @@
if (checksum_type >= checksum_types_count())
return EResult::InvalidChecksumType;
- if (!write_to_file(file, &magic, sizeof(magic)))
+ if (!write_to_file_le(file, magic))
return EResult::WriteError;
- if (!write_to_file(file, &version, sizeof(version)))
+ if (!write_to_file_le(file, version))
return EResult::WriteError;
- if (!write_to_file(file, &checksum_type, sizeof(checksum_type)))
+ if (!write_to_file_le(file, checksum_type))
return EResult::WriteError;
return EResult::Success;
@@ -124,17 +108,17 @@
EResult FileHeader::read(FILE& file, const uint32_t* const max_version)
{
- if (!read_from_file(file, &magic, sizeof(magic)))
+ if (!read_from_file_le(file, magic))
return EResult::ReadError;
if (magic != MAGICi32)
return EResult::InvalidMagicNumber;
- if (!read_from_file(file, &version, sizeof(version)))
+ if (!read_from_file_le(file, version))
return EResult::ReadError;
if (max_version != nullptr && version > *max_version)
return EResult::InvalidVersionNumber;
- if (!read_from_file(file, &checksum_type, sizeof(checksum_type)))
+ if (!read_from_file_le(file, checksum_type))
return EResult::ReadError;
if (checksum_type >= checksum_types_count())
return EResult::InvalidChecksumType;
@@ -157,14 +141,14 @@
EResult BlockHeader::write(FILE& file)
{
m_position = ftell(&file);
- if (!write_to_file(file, &type, sizeof(type)))
+ if (!write_to_file_le(file, type))
return EResult::WriteError;
- if (!write_to_file(file, &compression, sizeof(compression)))
+ if (!write_to_file_le(file, compression))
return EResult::WriteError;
- if (!write_to_file(file, &uncompressed_size, sizeof(uncompressed_size)))
+ if (!write_to_file_le(file, uncompressed_size))
return EResult::WriteError;
if (compression != (uint16_t)ECompressionType::None) {
- if (!write_to_file(file, &compressed_size, sizeof(compressed_size)))
+ if (!write_to_file_le(file, compressed_size))
return EResult::WriteError;
}
return EResult::Success;
@@ -173,20 +157,20 @@
EResult BlockHeader::read(FILE& file)
{
m_position = ftell(&file);
- if (!read_from_file(file, &type, sizeof(type)))
+ if (!read_from_file_le(file, type))
return EResult::ReadError;
if (type >= block_types_count())
return EResult::InvalidBlockType;
- if (!read_from_file(file, &compression, sizeof(compression)))
+ if (!read_from_file_le(file, compression))
return EResult::ReadError;
if (compression >= compression_types_count())
return EResult::InvalidCompressionType;
- if (!read_from_file(file, &uncompressed_size, sizeof(uncompressed_size)))
+ if (!read_from_file_le(file, uncompressed_size))
return EResult::ReadError;
if (compression != (uint16_t)ECompressionType::None) {
- if (!read_from_file(file, &compressed_size, sizeof(compressed_size)))
+ if (!read_from_file_le(file, compressed_size))
return EResult::ReadError;
}
@@ -199,21 +183,21 @@
}
EResult ThumbnailParams::write(FILE& file) const {
- if (!write_to_file(file, &format, sizeof(format)))
+ if (!write_to_file_le(file, format))
return EResult::WriteError;
- if (!write_to_file(file, &width, sizeof(width)))
+ if (!write_to_file_le(file, width))
return EResult::WriteError;
- if (!write_to_file(file, &height, sizeof(height)))
+ if (!write_to_file_le(file, height))
return EResult::WriteError;
return EResult::Success;
}
EResult ThumbnailParams::read(FILE& file){
- if (!read_from_file(file, &format, sizeof(format)))
+ if (!read_from_file_le(file, format))
return EResult::ReadError;
- if (!read_from_file(file, &width, sizeof(width)))
+ if (!read_from_file_le(file, width))
return EResult::ReadError;
- if (!read_from_file(file, &height, sizeof(height)))
+ if (!read_from_file_le(file, height))
return EResult::ReadError;
return EResult::Success;
}
--- a/src/LibBGCode/binarize/binarize.cpp
+++ b/src/LibBGCode/binarize/binarize.cpp
@@ -18,22 +18,6 @@
namespace binarize {
-template<class T>
-static bool write_to_file(FILE& file, const T* data, size_t data_size)
-{
- const size_t wsize = fwrite(static_cast<const void*>(data), 1, data_size, &file);
- return !ferror(&file) && wsize == data_size;
-}
-
-template<class T>
-static bool read_from_file(FILE& file, T *data, size_t data_size)
-{
- static_assert(!std::is_const_v<T>, "Type of output buffer cannot be const!");
-
- const size_t rsize = fread(static_cast<void *>(data), 1, data_size, &file);
- return !ferror(&file) && rsize == data_size;
-}
-
void update_checksum(Checksum& checksum, const ThumbnailBlock &th)
{
checksum.append(th.params.format);
@@ -420,7 +404,7 @@
return res;
// write block payload
- if (!write_to_file(file, &block.encoding_type, sizeof(block.encoding_type)))
+ if (!write_to_file_le(file, block.encoding_type))
return EResult::WriteError;
if (!out_data.empty()) {
if (!write_to_file(file, out_data.data(), out_data.size()))
@@ -443,7 +427,7 @@
{
const ECompressionType compression_type = (ECompressionType)block_header.compression;
- if (!read_from_file(file, (void*)&encoding_type, sizeof(encoding_type)))
+ if (!read_from_file_le(file, encoding_type))
return EResult::ReadError;
if (encoding_type > metadata_encoding_types_count())
return EResult::InvalidMetadataEncodingType;
@@ -452,7 +436,7 @@
const size_t data_size = (compression_type == ECompressionType::None) ? block_header.uncompressed_size : block_header.compressed_size;
if (data_size > 0) {
data.resize(data_size);
- if (!read_from_file(file, (void*)data.data(), data_size))
+ if (!read_from_file(file, data.data(), data_size))
return EResult::ReadError;
}
@@ -638,7 +622,7 @@
return EResult::InvalidThumbnailDataSize;
data.resize(block_header.uncompressed_size);
- if (!read_from_file(file, (void*)data.data(), block_header.uncompressed_size))
+ if (!read_from_file(file, data.data(), block_header.uncompressed_size))
return EResult::ReadError;
const EChecksumType checksum_type = (EChecksumType)file_header.checksum_type;
@@ -683,7 +667,7 @@
return res;
// write block payload
- if (!write_to_file(file, &encoding_type, sizeof(encoding_type)))
+ if (!write_to_file_le(file, encoding_type))
return EResult::WriteError;
if (!out_data.empty()) {
if (!write_to_file(file, out_data.data(), out_data.size()))
@@ -696,8 +680,10 @@
// update checksum with block header
update_checksum(cs, block_header);
// update checksum with block payload
+ std::array<std::byte, sizeof(encoding_type)> swapped_encoding;
+ store_integer_le(encoding_type, swapped_encoding.data());
std::vector<uint8_t> data_to_encode =
- encode(reinterpret_cast<const std::byte*>(&encoding_type), sizeof(encoding_type));
+ encode(swapped_encoding.data(), swapped_encoding.size());
cs.append(data_to_encode.data(), data_to_encode.size());
if (!out_data.empty())
cs.append(static_cast<unsigned char *>(out_data.data()), out_data.size());
@@ -713,7 +699,7 @@
{
const ECompressionType compression_type = (ECompressionType)block_header.compression;
- if (!read_from_file(file, (void*)&encoding_type, sizeof(encoding_type)))
+ if (!read_from_file_le(file, encoding_type))
return EResult::ReadError;
if (encoding_type > gcode_encoding_types_count())
return EResult::InvalidGCodeEncodingType;
@@ -722,7 +708,7 @@
const size_t data_size = (compression_type == ECompressionType::None) ? block_header.uncompressed_size : block_header.compressed_size;
if (data_size > 0) {
data.resize(data_size);
- if (!read_from_file(file, (void*)data.data(), data_size))
+ if (!read_from_file(file, data.data(), data_size))
return EResult::ReadError;
}
--- a/src/LibBGCode/core/core_impl.hpp
+++ b/src/LibBGCode/core/core_impl.hpp
@@ -120,7 +120,7 @@
// Append any aritmetic data to the checksum (shorthand for aritmetic types)
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
- void append(T& data) { append(reinterpret_cast<const std::byte*>(&data), sizeof(data)); }
+ void append(T& data);
// Returns true if the given checksum is equal to this one
bool matches(Checksum& other);
@@ -168,12 +168,53 @@
}
}
+template<typename T, typename>
+void Checksum::append(T& data)
+{
+ std::array<std::byte, sizeof(T)> temp;
+ store_integer_le(data, temp.begin(), temp.size());
+ append(temp.data(), temp.size());
+}
+
static constexpr auto MAGICi32 = load_integer<uint32_t>(std::begin(MAGIC), std::end(MAGIC));
constexpr auto checksum_types_count() noexcept { auto v = to_underlying(EChecksumType::CRC32); ++v; return v;}
constexpr auto block_types_count() noexcept { auto v = to_underlying(EBlockType::Thumbnail); ++v; return v; }
constexpr auto compression_types_count() noexcept { auto v = to_underlying(ECompressionType::Heatshrink_12_4); ++v; return v; }
+template<class BufT>
+static bool write_to_file(FILE& file, const BufT* data, size_t data_size)
+{
+ const size_t wsize = fwrite(static_cast<const void*>(data), 1, data_size, &file);
+ return !ferror(&file) && wsize == data_size;
+}
+
+template<class T>
+static bool write_to_file_le(FILE& file, const T &data)
+{
+ std::array<std::byte, sizeof(T)> temp;
+ store_integer_le(data, temp.begin(), temp.size());
+ return write_to_file(file, temp.data(), temp.size());
+}
+
+template<class BufT>
+static bool read_from_file(FILE& file, BufT *data, size_t data_size)
+{
+ const size_t rsize = fread(static_cast<BufT *>(data), 1, data_size, &file);
+ return !ferror(&file) && rsize == data_size;
+}
+
+template<class T>
+static bool read_from_file_le(FILE& file, T &data)
+{
+ std::array<std::byte, sizeof(T)> temp;
+ if (!read_from_file(file, temp.data(), temp.size())) {
+ return false;
+ }
+ data = load_integer<T>(temp.begin(), temp.end());
+ return true;
+}
+
} // namespace core
} // namespace bgcode