# StructIO

[![pkgeval](https://juliahub.com/docs/StructIO/pkgeval.svg)](https://juliahub.com/ui/Packages/StructIO/aDnIf)
[![Build Status](https://github.com/JuliaIO/StructIO.jl/workflows/CI/badge.svg)](https://github.com/JuliaIO/StructIO.jl/actions?query=workflow%3ACI+branch%3Amaster)
[![Coverage](https://codecov.io/gh/JuliaIO/StructIO.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaIO/StructIO.jl)

Generates IO methods (`pack`, `unpack`) from structure definitions.  Also defines `packed_sizeof` to give the on-disk size of a packed structure, which is smaller than `sizeof` would give, if the struct is marked as `align_packed`.

# Example usage
```julia
julia> using StructIO

julia> @io struct TwoUInt64s
           x::UInt64
           y::UInt64
       end

julia> buf = IOBuffer(collect(UInt8(1):UInt8(16))); 

julia> seekstart(buf); unpack(buf, TwoUInt64s) # Default endianness depends on machine
TwoUInt64s(0x0807060504030201, 0x100f0e0d0c0b0a09)

julia> seekstart(buf); unpack(buf, TwoUInt64s, :BigEndian)
TwoUInt64s(0x0102030405060708, 0x090a0b0c0d0e0f10)

julia> @io struct DefaultExample
           a::UInt8   # Default packing includes a padding byte between fields
           b::UInt16
       end

julia> seekstart(buf); unpack(buf, DefaultExample) # Notice byte 0x02 is not used as part of `b`
DefaultExample(0x01, 0x0403)

julia> @io struct PackedExample
           a::UInt8
           b::UInt16
       end align_packed

julia> seekstart(buf); unpack(buf, PackedExample) # Now byte 0x02 is used
PackedExample(0x01, 0x0302)
```
