From Wikipedia:
"XAR (short for eXtensible ARchive format) is an open source file archiver and the archiver's file format. It was created within the OpenDarwin project and is used in macOS X 10.5 and up for software installation routines, as well as browser extensions in Safari 5.0 and up."
This page hosts a formal specification of XAR (eXtensible ARchive) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream). One can open local file for that, or use existing std::string or char* buffer.
        
        #include <fstream>
std::ifstream is("path/to/local/file.xar", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
xar_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.header_prefix() // => internal; access `_root.header` instead
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
class xar_t;
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <set>
#if KAITAI_STRUCT_VERSION < 11000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.11 or later is required"
#endif
/**
 * From [Wikipedia](https://en.wikipedia.org/wiki/Xar_(archiver)):
 * 
 * "XAR (short for eXtensible ARchive format) is an open source file archiver
 * and the archiver's file format. It was created within the OpenDarwin project
 * and is used in macOS X 10.5 and up for software installation routines, as
 * well as browser extensions in Safari 5.0 and up."
 * \sa https://github.com/mackyle/xar/wiki/xarformat Source
 */
class xar_t : public kaitai::kstruct {
public:
    class file_header_t;
    class file_header_prefix_t;
    class toc_type_t;
    enum checksum_algorithms_apple_t {
        CHECKSUM_ALGORITHMS_APPLE_NONE = 0,
        CHECKSUM_ALGORITHMS_APPLE_SHA1 = 1,
        CHECKSUM_ALGORITHMS_APPLE_MD5 = 2,
        CHECKSUM_ALGORITHMS_APPLE_SHA256 = 3,
        CHECKSUM_ALGORITHMS_APPLE_SHA512 = 4
    };
    static bool _is_defined_checksum_algorithms_apple_t(checksum_algorithms_apple_t v);
private:
    static const std::set<checksum_algorithms_apple_t> _values_checksum_algorithms_apple_t;
public:
    xar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, xar_t* p__root = nullptr);
private:
    void _read();
    void _clean_up();
public:
    ~xar_t();
    class file_header_t : public kaitai::kstruct {
    public:
        file_header_t(kaitai::kstream* p__io, xar_t* p__parent = nullptr, xar_t* p__root = nullptr);
    private:
        void _read();
        void _clean_up();
    public:
        ~file_header_t();
    private:
        bool f_checksum_algorithm_name;
        std::string m_checksum_algorithm_name;
    public:
        /**
         * If it is not
         * 
         * * `""` (empty string), indicating an unknown integer value (access
         *   `checksum_algorithm_int` for debugging purposes to find out
         *   what that value is), or
         * * `"none"`, indicating that the TOC checksum is not provided (in that
         *   case, the `<checksum>` property or its `style` attribute should be
         *   missing, or the `style` attribute must be set to `"none"`),
         * 
         * it must exactly match the `style` attribute value of the
         * `<checksum>` property in the root node `<toc>`. See
         * <https://github.com/mackyle/xar/blob/66d451d/xar/lib/archive.c#L345-L371>
         * for reference.
         * 
         * The `xar` (eXtensible ARchiver) program [uses OpenSSL's function
         * `EVP_get_digestbyname`](
         *   https://github.com/mackyle/xar/blob/66d451d/xar/lib/archive.c#L328
         * ) to verify this value (if it's not `""` or `"none"`, of course).
         * So it's reasonable to assume that this can only have one of the values
         * that OpenSSL recognizes.
         */
        std::string checksum_algorithm_name();
    private:
        bool f_has_checksum_alg_name;
        bool m_has_checksum_alg_name;
    public:
        bool has_checksum_alg_name();
    private:
        bool f_len_header;
        uint16_t m_len_header;
    public:
        uint16_t len_header();
    private:
        uint16_t m_version;
        uint64_t m_len_toc_compressed;
        uint64_t m_toc_length_uncompressed;
        uint32_t m_checksum_algorithm_int;
        std::string m_checksum_alg_name;
        bool n_checksum_alg_name;
    public:
        bool _is_null_checksum_alg_name() { checksum_alg_name(); return n_checksum_alg_name; };
    private:
        xar_t* m__root;
        xar_t* m__parent;
    public:
        uint16_t version() const { return m_version; }
        uint64_t len_toc_compressed() const { return m_len_toc_compressed; }
        uint64_t toc_length_uncompressed() const { return m_toc_length_uncompressed; }
        /**
         * internal; access `checksum_algorithm_name` instead
         */
        uint32_t checksum_algorithm_int() const { return m_checksum_algorithm_int; }
        /**
         * internal; access `checksum_algorithm_name` instead
         */
        std::string checksum_alg_name() const { return m_checksum_alg_name; }
        xar_t* _root() const { return m__root; }
        xar_t* _parent() const { return m__parent; }
    };
    class file_header_prefix_t : public kaitai::kstruct {
    public:
        file_header_prefix_t(kaitai::kstream* p__io, xar_t* p__parent = nullptr, xar_t* p__root = nullptr);
    private:
        void _read();
        void _clean_up();
    public:
        ~file_header_prefix_t();
    private:
        std::string m_magic;
        uint16_t m_len_header;
        xar_t* m__root;
        xar_t* m__parent;
    public:
        std::string magic() const { return m_magic; }
        /**
         * internal; access `_root.header.len_header` instead
         */
        uint16_t len_header() const { return m_len_header; }
        xar_t* _root() const { return m__root; }
        xar_t* _parent() const { return m__parent; }
    };
    class toc_type_t : public kaitai::kstruct {
    public:
        toc_type_t(kaitai::kstream* p__io, xar_t* p__parent = nullptr, xar_t* p__root = nullptr);
    private:
        void _read();
        void _clean_up();
    public:
        ~toc_type_t();
    private:
        std::string m_xml_string;
        xar_t* m__root;
        xar_t* m__parent;
    public:
        std::string xml_string() const { return m_xml_string; }
        xar_t* _root() const { return m__root; }
        xar_t* _parent() const { return m__parent; }
    };
private:
    bool f_checksum_algorithm_other;
    int8_t m_checksum_algorithm_other;
public:
    /**
     * \sa https://github.com/mackyle/xar/blob/66d451d/xar/include/xar.h.in#L85 Source
     */
    int8_t checksum_algorithm_other();
private:
    std::unique_ptr<file_header_prefix_t> m_header_prefix;
    std::unique_ptr<file_header_t> m_header;
    std::unique_ptr<toc_type_t> m_toc;
    xar_t* m__root;
    kaitai::kstruct* m__parent;
    std::string m__raw_header;
    std::unique_ptr<kaitai::kstream> m__io__raw_header;
    std::string m__raw_toc;
    std::unique_ptr<kaitai::kstream> m__io__raw_toc;
    std::string m__raw__raw_toc;
public:
    /**
     * internal; access `_root.header` instead
     */
    file_header_prefix_t* header_prefix() const { return m_header_prefix.get(); }
    file_header_t* header() const { return m_header.get(); }
    /**
     * zlib compressed XML further describing the content of the archive
     */
    toc_type_t* toc() const { return m_toc.get(); }
    xar_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
    std::string _raw_header() const { return m__raw_header; }
    kaitai::kstream* _io__raw_header() const { return m__io__raw_header.get(); }
    std::string _raw_toc() const { return m__raw_toc; }
    kaitai::kstream* _io__raw_toc() const { return m__io__raw_toc.get(); }
    std::string _raw__raw_toc() const { return m__raw__raw_toc; }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "xar.h"
#include "kaitai/exceptions.h"
const std::set<xar_t::checksum_algorithms_apple_t> xar_t::_values_checksum_algorithms_apple_t{
    xar_t::CHECKSUM_ALGORITHMS_APPLE_NONE,
    xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA1,
    xar_t::CHECKSUM_ALGORITHMS_APPLE_MD5,
    xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA256,
    xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA512,
};
bool xar_t::_is_defined_checksum_algorithms_apple_t(xar_t::checksum_algorithms_apple_t v) {
    return xar_t::_values_checksum_algorithms_apple_t.find(v) != xar_t::_values_checksum_algorithms_apple_t.end();
}
xar_t::xar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, xar_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root ? p__root : this;
    m_header_prefix = nullptr;
    m_header = nullptr;
    m__io__raw_header = nullptr;
    m_toc = nullptr;
    m__io__raw_toc = nullptr;
    f_checksum_algorithm_other = false;
    _read();
}
void xar_t::_read() {
    m_header_prefix = std::unique_ptr<file_header_prefix_t>(new file_header_prefix_t(m__io, this, m__root));
    m__raw_header = m__io->read_bytes(header_prefix()->len_header() - 6);
    m__io__raw_header = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_header));
    m_header = std::unique_ptr<file_header_t>(new file_header_t(m__io__raw_header.get(), this, m__root));
    m__raw__raw_toc = m__io->read_bytes(header()->len_toc_compressed());
    m__raw_toc = kaitai::kstream::process_zlib(m__raw__raw_toc);
    m__io__raw_toc = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_toc));
    m_toc = std::unique_ptr<toc_type_t>(new toc_type_t(m__io__raw_toc.get(), this, m__root));
}
xar_t::~xar_t() {
    _clean_up();
}
void xar_t::_clean_up() {
}
xar_t::file_header_t::file_header_t(kaitai::kstream* p__io, xar_t* p__parent, xar_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_checksum_algorithm_name = false;
    f_has_checksum_alg_name = false;
    f_len_header = false;
    _read();
}
void xar_t::file_header_t::_read() {
    m_version = m__io->read_u2be();
    if (!(m_version == 1)) {
        throw kaitai::validation_not_equal_error<uint16_t>(1, m_version, m__io, std::string("/types/file_header/seq/0"));
    }
    m_len_toc_compressed = m__io->read_u8be();
    m_toc_length_uncompressed = m__io->read_u8be();
    m_checksum_algorithm_int = m__io->read_u4be();
    n_checksum_alg_name = true;
    if (has_checksum_alg_name()) {
        n_checksum_alg_name = false;
        m_checksum_alg_name = kaitai::kstream::bytes_to_str(kaitai::kstream::bytes_terminate(m__io->read_bytes_full(), 0, false), "UTF-8");
        {
            std::string _ = m_checksum_alg_name;
            if (!( ((_ != std::string("")) && (_ != std::string("none"))) )) {
                throw kaitai::validation_expr_error<std::string>(m_checksum_alg_name, m__io, std::string("/types/file_header/seq/4"));
            }
        }
    }
}
xar_t::file_header_t::~file_header_t() {
    _clean_up();
}
void xar_t::file_header_t::_clean_up() {
    if (!n_checksum_alg_name) {
    }
}
std::string xar_t::file_header_t::checksum_algorithm_name() {
    if (f_checksum_algorithm_name)
        return m_checksum_algorithm_name;
    f_checksum_algorithm_name = true;
    m_checksum_algorithm_name = ((has_checksum_alg_name()) ? (checksum_alg_name()) : (((checksum_algorithm_int() == xar_t::CHECKSUM_ALGORITHMS_APPLE_NONE) ? (std::string("none")) : (((checksum_algorithm_int() == xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA1) ? (std::string("sha1")) : (((checksum_algorithm_int() == xar_t::CHECKSUM_ALGORITHMS_APPLE_MD5) ? (std::string("md5")) : (((checksum_algorithm_int() == xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA256) ? (std::string("sha256")) : (((checksum_algorithm_int() == xar_t::CHECKSUM_ALGORITHMS_APPLE_SHA512) ? (std::string("sha512")) : (std::string("")))))))))))));
    return m_checksum_algorithm_name;
}
bool xar_t::file_header_t::has_checksum_alg_name() {
    if (f_has_checksum_alg_name)
        return m_has_checksum_alg_name;
    f_has_checksum_alg_name = true;
    m_has_checksum_alg_name =  ((checksum_algorithm_int() == _root()->checksum_algorithm_other()) && (len_header() >= 32) && (kaitai::kstream::mod(len_header(), 4) == 0)) ;
    return m_has_checksum_alg_name;
}
uint16_t xar_t::file_header_t::len_header() {
    if (f_len_header)
        return m_len_header;
    f_len_header = true;
    m_len_header = _root()->header_prefix()->len_header();
    return m_len_header;
}
xar_t::file_header_prefix_t::file_header_prefix_t(kaitai::kstream* p__io, xar_t* p__parent, xar_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}
void xar_t::file_header_prefix_t::_read() {
    m_magic = m__io->read_bytes(4);
    if (!(m_magic == std::string("\x78\x61\x72\x21", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x78\x61\x72\x21", 4), m_magic, m__io, std::string("/types/file_header_prefix/seq/0"));
    }
    m_len_header = m__io->read_u2be();
}
xar_t::file_header_prefix_t::~file_header_prefix_t() {
    _clean_up();
}
void xar_t::file_header_prefix_t::_clean_up() {
}
xar_t::toc_type_t::toc_type_t(kaitai::kstream* p__io, xar_t* p__parent, xar_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}
void xar_t::toc_type_t::_read() {
    m_xml_string = kaitai::kstream::bytes_to_str(m__io->read_bytes_full(), "UTF-8");
}
xar_t::toc_type_t::~toc_type_t() {
    _clean_up();
}
void xar_t::toc_type_t::_clean_up() {
}
int8_t xar_t::checksum_algorithm_other() {
    if (f_checksum_algorithm_other)
        return m_checksum_algorithm_other;
    f_checksum_algorithm_other = true;
    m_checksum_algorithm_other = 3;
    return m_checksum_algorithm_other;
}