Image
MITReleasesC++20buildcodecovplatform

Overview

Synopsis

binary_io is a cross-platform i/o library which enables developers to painlessly read/write artbitrary binary formats. binary_io is a not a serialization library, such as cereal or Boost.Serialization. It does not define its own binary formats to seralize data to/from.

Inspiration

Loosely based on Modern std::byte stream IO for C++.

Examples

Reading a local file header from a zip file

https://en.wikipedia.org/wiki/ZIP_(file_format)#Local_file_header

#include <bit>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <span>
#include <string>

#include <binary_io/binary_io.hpp>

struct local_file_header
{
    std::uint32_t local_file_header_signature{ 0 };
    std::uint16_t version_needed_to_extract{ 0 };
    std::uint16_t general_purpose_bit_flag{ 0 };
    std::uint16_t compression_method{ 0 };
    std::uint16_t file_last_modification_time{ 0 };
    std::uint16_t file_last_modification_date{ 0 };
    std::uint32_t crc_32_of_uncompressed_data{ 0 };
    std::uint32_t compressed_size{ 0 };
    std::uint32_t uncompressed_size{ 0 };
    std::uint16_t file_name_length{ 0 };
    std::uint16_t extra_field_length{ 0 };
    std::string file_name;
    std::string extra_field;
};

int main()
{
    binary_io::file_istream in{ "example.zip" };
    const auto read_string = [&](std::string& a_dst, std::size_t a_len) {
        a_dst.resize(a_len);
        in.read_bytes(std::as_writable_bytes(std::span{ a_dst.data(), a_dst.size() }));
    };

    local_file_header h;
    in.read(
        std::endian::little,
        h.local_file_header_signature,
        h.version_needed_to_extract,
        h.general_purpose_bit_flag,
        h.compression_method,
        h.file_last_modification_time,
        h.file_last_modification_date,
        h.crc_32_of_uncompressed_data,
        h.compressed_size,
        h.uncompressed_size,
        h.file_name_length,
        h.extra_field_length);
    read_string(h.file_name, h.file_name_length);
    read_string(h.extra_field, h.extra_field_length);

    std::cout << std::hex;
#define DUMP(a_var) std::cout << #a_var << ": " << h.a_var << '\n';
    DUMP(local_file_header_signature);
    DUMP(version_needed_to_extract);
    DUMP(general_purpose_bit_flag);
    DUMP(compression_method);
    DUMP(file_last_modification_time);
    DUMP(file_last_modification_date);
    DUMP(crc_32_of_uncompressed_data);
    DUMP(compressed_size);
    DUMP(uncompressed_size);
    DUMP(file_name_length);
    DUMP(extra_field_length);
    DUMP(file_name);
    DUMP(extra_field);
}

Writing an anonymous compiled papyrus script header

https://en.uesp.net/wiki/Skyrim_Mod:Compiled_Script_File_Format#Header

#include <bit>
#include <cstdint>
#include <span>
#include <string>
#include <string_view>

#include <binary_io/binary_io.hpp>

struct script_header
{
    enum class game_id : std::uint16_t
    {
        skyrim = 1,
    };

    std::uint32_t magic{ 0xFA57C0DE };
    std::uint8_t major{ 3 };
    std::uint8_t minor{ 2 };
    game_id id{ game_id::skyrim };
    std::uint64_t timestamp{ 0 };
    std::string source_name{ "script.psc" };
    std::string user_name;
    std::string machine_name;
};

int main()
{
    binary_io::file_ostream out{ "script.pex" };
    out.endian(std::endian::big);
    const auto write_wstring = [&](std::string_view a_str) {
        out.write(static_cast<std::uint16_t>(a_str.length()));
        out.write_bytes(std::as_bytes(std::span{ a_str.data(), a_str.length() }));
    };

    script_header h;
    out.write(
        h.magic,
        h.major,
        h.minor,
        h.id,
        h.timestamp);
    write_wstring(h.source_name);
    write_wstring(h.user_name);
    write_wstring(h.machine_name);
}

CMake Options

OptionDefault ValueDescription
BINARY_IO_BUILD_DOCSOFFSet to ON to build the documentation.
BINARY_IO_BUILD_SRCON ✔️Set to ON to build the main library.
BUILD_TESTINGON ✔️Set to ON to build the tests. See also the CMake documentation for this option.

Integration

Package ManagerPackage Name
vcpkgrsm-binary-io

binary_io uses CMake as its primary build system. Assuming that binary_io has been installed to a place where CMake can find it, then using it in your project is as simple as:

find_package(binary_io REQUIRED CONFIG)
target_link_libraries(${PROJECT_NAME} PUBLIC binary_io::binary_io)