Skip to content

Commit

Permalink
Fixing byte ordering issues and adhering to strict aliasing rules
Browse files Browse the repository at this point in the history
Some incorrect casts may still remain
Some tests fail
  • Loading branch information
tamasmeszaros committed Oct 19, 2023
1 parent e1b6b45 commit cbd61d6
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 128 deletions.
42 changes: 25 additions & 17 deletions src/LibBGCode/binarize/binarize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,28 @@ extern "C" {
#include <cassert>

namespace bgcode {

using namespace core;

namespace binarize {

static bool write_to_file(FILE& file, const void* data, size_t data_size)
template<class T>
static bool write_to_file(FILE& file, const T* data, size_t data_size)
{
const size_t wsize = fwrite(data, 1, data_size, &file);
const size_t wsize = fwrite(static_cast<const void*>(data), 1, data_size, &file);
return !ferror(&file) && wsize == data_size;
}

static bool read_from_file(FILE& file, void* data, size_t data_size)
template<class T>
static bool read_from_file(FILE& file, T *data, size_t data_size)
{
const size_t rsize = fread(data, 1, data_size, &file);
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;
}

static std::vector<uint8_t> encode(const void* data, size_t data_size)
static std::vector<uint8_t> encode(const std::byte* data, size_t data_size)
{
std::vector<uint8_t> ret(data_size);
memcpy(ret.data(), data, data_size);
Expand Down Expand Up @@ -135,7 +141,7 @@ static bool decode_gcode(const std::vector<uint8_t>& src, std::string& dst, EGCo
return true;
}

static bool compress(const std::vector<uint8_t>& src, std::vector<uint8_t>& dst, ECompressionType compression_type)
static bool compress(std::vector<uint8_t>& src, std::vector<uint8_t>& dst, ECompressionType compression_type)
{
switch (compression_type)
{
Expand All @@ -147,8 +153,8 @@ static bool compress(const std::vector<uint8_t>& src, std::vector<uint8_t>& dst,
std::vector<uint8_t> temp_buffer(BUFSIZE);

z_stream strm{};
strm.next_in = const_cast<uint8_t*>(src.data());
strm.avail_in = (uInt)src.size();
strm.next_in = static_cast<Bytef*>(src.data());
strm.avail_in = static_cast<uInt>(src.size());
strm.next_out = temp_buffer.data();
strm.avail_out = BUFSIZE;

Expand Down Expand Up @@ -203,7 +209,7 @@ static bool compress(const std::vector<uint8_t>& src, std::vector<uint8_t>& dst,
const size_t max_compressed_size = src_size + (src_size >> 2);
dst.resize(max_compressed_size);

uint8_t* buf = const_cast<uint8_t*>(src.data());
uint8_t* buf = src.data();
uint8_t* outbuf = dst.data();

// compress data
Expand Down Expand Up @@ -403,10 +409,10 @@ EResult BaseMetadataBlock::write(FILE& file, EBlockType block_type, ECompression
return res;

// write block payload
if (!write_to_file(file, (const void*)&encoding_type, sizeof(encoding_type)))
if (!write_to_file(file, &encoding_type, sizeof(encoding_type)))
return EResult::WriteError;
if (!out_data.empty()) {
if (!write_to_file(file, (const void*)out_data.data(), out_data.size()))
if (!write_to_file(file, out_data.data(), out_data.size()))
return EResult::WriteError;
}

Expand All @@ -416,7 +422,7 @@ EResult BaseMetadataBlock::write(FILE& file, EBlockType block_type, ECompression
// update checksum with block payload
checksum.append(encoding_type);
if (!out_data.empty())
checksum.append(out_data);
checksum.append(static_cast<unsigned char*>(out_data.data()), out_data.size());
}
return EResult::Success;
}
Expand Down Expand Up @@ -585,7 +591,7 @@ EResult ThumbnailBlock::write(FILE& file, EChecksumType checksum_type)
return res;
}

if (!write_to_file(file, (const void*)data.data(), data.size()))
if (!write_to_file(file, data.data(), data.size()))
return EResult::WriteError;

if (checksum_type != EChecksumType::None) {
Expand Down Expand Up @@ -673,10 +679,10 @@ EResult GCodeBlock::write(FILE& file, ECompressionType compression_type, EChecks
return res;

// write block payload
if (!write_to_file(file, (const void*)&encoding_type, sizeof(encoding_type)))
if (!write_to_file(file, &encoding_type, sizeof(encoding_type)))
return EResult::WriteError;
if (!out_data.empty()) {
if (!write_to_file(file, (const void*)out_data.data(), out_data.size()))
if (!write_to_file(file, out_data.data(), out_data.size()))
return EResult::WriteError;
}

Expand All @@ -686,9 +692,11 @@ EResult GCodeBlock::write(FILE& file, ECompressionType compression_type, EChecks
// update checksum with block header
block_header.update_checksum(cs);
// update checksum with block payload
cs.append(encode((const void*)&encoding_type, sizeof(encoding_type)));
std::vector<uint8_t> data_to_encode =
encode(reinterpret_cast<const std::byte*>(&encoding_type), sizeof(encoding_type));
cs.append(data_to_encode.data(), data_to_encode.size());
if (!out_data.empty())
cs.append(out_data);
cs.append(static_cast<unsigned char *>(out_data.data()), out_data.size());
res = cs.write(file);
if (res != EResult::Success)
// propagate error
Expand Down
28 changes: 14 additions & 14 deletions src/LibBGCode/binarize/binarize.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#ifndef _BGCODE_BINARIZE_HPP_
#define _BGCODE_BINARIZE_HPP_
#ifndef BGCODE_BINARIZE_HPP
#define BGCODE_BINARIZE_HPP

#include "binarize/export.h"
#include "core/core.hpp"

namespace bgcode { namespace binarize {

struct BaseMetadataBlock
BGCODE_BINARIZE_EXPORT struct BaseMetadataBlock
{
// type of data encoding
uint16_t encoding_type{ 0 };
Expand All @@ -19,34 +19,34 @@ struct BaseMetadataBlock
core::EResult read_data(FILE& file, const core::BlockHeader& block_header);
};

struct FileMetadataBlock : public BaseMetadataBlock
BGCODE_BINARIZE_EXPORT struct FileMetadataBlock : public BaseMetadataBlock
{
// write block header and data
core::EResult write(FILE& file, core::ECompressionType compression_type, core::EChecksumType checksum_type) const;
// read block data
core::EResult read_data(FILE& file, const core::FileHeader& file_header, const core::BlockHeader& block_header);
};

struct PrintMetadataBlock : public BaseMetadataBlock
BGCODE_BINARIZE_EXPORT struct PrintMetadataBlock : public BaseMetadataBlock
{
// write block header and data
core::EResult write(FILE& file, core::ECompressionType compression_type, core::EChecksumType checksum_type) const;
// read block data
core::EResult read_data(FILE& file, const core::FileHeader& file_header, const core::BlockHeader& block_header);
};

struct PrinterMetadataBlock : public BaseMetadataBlock
BGCODE_BINARIZE_EXPORT struct PrinterMetadataBlock : public BaseMetadataBlock
{
// write block header and data
core::EResult write(FILE& file, core::ECompressionType compression_type, core::EChecksumType checksum_type) const;
// read block data
core::EResult read_data(FILE& file, const core::FileHeader& file_header, const core::BlockHeader& block_header);
};

struct ThumbnailBlock
BGCODE_BINARIZE_EXPORT struct ThumbnailBlock
{
core::ThumbnailParams params;
std::vector<uint8_t> data;
std::vector<std::byte> data;

// write block header and data
core::EResult write(FILE& file, core::EChecksumType checksum_type);
Expand All @@ -57,7 +57,7 @@ struct ThumbnailBlock
void update_checksum(core::Checksum& checksum) const;
};

struct GCodeBlock
BGCODE_BINARIZE_EXPORT struct GCodeBlock
{
uint16_t encoding_type{ 0 };
std::string raw_data;
Expand All @@ -68,15 +68,15 @@ struct GCodeBlock
core::EResult read_data(FILE& file, const core::FileHeader& file_header, const core::BlockHeader& block_header);
};

struct SlicerMetadataBlock : public BaseMetadataBlock
BGCODE_BINARIZE_EXPORT struct SlicerMetadataBlock : public BaseMetadataBlock
{
// write block header and data
core::EResult write(FILE& file, core::ECompressionType compression_type, core::EChecksumType checksum_type) const;
// read block data
core::EResult read_data(FILE& file, const core::FileHeader& file_header, const core::BlockHeader& block_header);
};

struct BinarizerConfig
BGCODE_BINARIZE_EXPORT struct BinarizerConfig
{
struct Compression
{
Expand All @@ -92,7 +92,7 @@ struct BinarizerConfig
core::EChecksumType checksum{ core::EChecksumType::CRC32 };
};

struct BinaryData
BGCODE_BINARIZE_EXPORT struct BinaryData
{
FileMetadataBlock file_metadata;
PrinterMetadataBlock printer_metadata;
Expand All @@ -101,7 +101,7 @@ struct BinaryData
PrintMetadataBlock print_metadata;
};

class Binarizer
BGCODE_BINARIZE_EXPORT class Binarizer
{
public:
bool is_enabled() const;
Expand All @@ -128,4 +128,4 @@ class Binarizer

}} // bgcode::core

#endif // _BGCODE_BINARIZE_HPP_
#endif // BGCODE_BINARIZE_HPP_
13 changes: 7 additions & 6 deletions src/LibBGCode/convert/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,11 @@ BGCODE_CONVERT_EXPORT EResult from_ascii_to_binary(FILE& src_file, FILE& dst_fil
ThumbnailBlock& thumbnail = binary_data.thumbnails.back();
if (thumbnail.data.size() > curr_thumbnail_data_loaded)
thumbnail.data.resize(curr_thumbnail_data_loaded);
std::string decoded;
decoded.resize(boost::beast::detail::base64::decoded_size(thumbnail.data.size()));
decoded.resize(boost::beast::detail::base64::decode((void*)&decoded[0], (const char*)thumbnail.data.data(), thumbnail.data.size()).first);
std::vector<std::byte> decoded(boost::beast::detail::base64::decoded_size(thumbnail.data.size()));
auto thumbnail_buf = reinterpret_cast<const char *>(thumbnail.data.data());
decoded.resize(boost::beast::detail::base64::decode(decoded.data(), thumbnail_buf, thumbnail.data.size()).first);
thumbnail.data.clear();
thumbnail.data.insert(thumbnail.data.end(), decoded.begin(), decoded.end());
std::copy(decoded.begin(), decoded.end(), std::back_inserter(thumbnail.data));
processed_lines.emplace_back(lines_counter++);
return;
}
Expand All @@ -467,7 +467,8 @@ BGCODE_CONVERT_EXPORT EResult from_ascii_to_binary(FILE& src_file, FILE& dst_fil
return;
}
ThumbnailBlock& thumbnail = binary_data.thumbnails.back();
thumbnail.data.insert(thumbnail.data.begin() + curr_thumbnail_data_loaded, sv_line.begin(), sv_line.end());
auto sv_line_bytes = reinterpret_cast<const std::byte*>(sv_line.data());
std::copy(sv_line_bytes, sv_line_bytes + sv_line.size(), std::back_inserter(thumbnail.data));
curr_thumbnail_data_loaded += sv_line.size();
processed_lines.emplace_back(lines_counter++);
return;
Expand Down Expand Up @@ -561,7 +562,7 @@ BGCODE_CONVERT_EXPORT EResult from_ascii_to_binary(FILE& src_file, FILE& dst_fil
BGCODE_CONVERT_EXPORT EResult from_binary_to_ascii(FILE& src_file, FILE& dst_file, bool verify_checksum)
{
// initialize buffer for checksum calculation, if verify_checksum is true
std::vector<uint8_t> checksum_buffer;
std::vector<std::byte> checksum_buffer;
if (verify_checksum)
checksum_buffer.resize(65535);

Expand Down
Loading

0 comments on commit cbd61d6

Please sign in to comment.