37    boost::filesystem::path 
const& src,
 
   38    boost::filesystem::path 
const& dst)
 
   40    if (!is_regular_file(src))
 
   41        Throw<std::runtime_error>(
"Invalid source file");
 
   46        archive_read_new(), [](
struct archive* a) { archive_read_free(a); }};
 
   48        Throw<std::runtime_error>(
"Failed to allocate archive");
 
   50    if (archive_read_support_format_tar(ar.get()) < ARCHIVE_OK)
 
   51        Throw<std::runtime_error>(archive_error_string(ar.get()));
 
   53    if (archive_read_support_filter_lz4(ar.get()) < ARCHIVE_OK)
 
   54        Throw<std::runtime_error>(archive_error_string(ar.get()));
 
   57    if (archive_read_open_filename(ar.get(), src.string().c_str(), 10240) <
 
   60        Throw<std::runtime_error>(archive_error_string(ar.get()));
 
   63    archive_ptr aw{archive_write_disk_new(), [](
struct archive* a) {
 
   64                       archive_write_free(a);
 
   67        Throw<std::runtime_error>(
"Failed to allocate archive");
 
   69    if (archive_write_disk_set_options(
 
   71            ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL |
 
   72                ARCHIVE_EXTRACT_FFLAGS) < ARCHIVE_OK)
 
   74        Throw<std::runtime_error>(archive_error_string(aw.get()));
 
   77    if (archive_write_disk_set_standard_lookup(aw.get()) < ARCHIVE_OK)
 
   78        Throw<std::runtime_error>(archive_error_string(aw.get()));
 
   81    struct archive_entry* entry;
 
   84        result = archive_read_next_header(ar.get(), &entry);
 
   85        if (result == ARCHIVE_EOF)
 
   87        if (result < ARCHIVE_OK)
 
   88            Throw<std::runtime_error>(archive_error_string(ar.get()));
 
   90        archive_entry_set_pathname(
 
   91            entry, (dst / archive_entry_pathname(entry)).
string().c_str());
 
   92        if (archive_write_header(aw.get(), entry) < ARCHIVE_OK)
 
   93            Throw<std::runtime_error>(archive_error_string(aw.get()));
 
   95        if (archive_entry_size(entry) > 0)
 
  102                result = archive_read_data_block(ar.get(), &buf, &sz, &offset);
 
  103                if (result == ARCHIVE_EOF)
 
  105                if (result < ARCHIVE_OK)
 
  106                    Throw<std::runtime_error>(archive_error_string(ar.get()));
 
  108                if (archive_write_data_block(aw.get(), buf, sz, offset) <
 
  111                    Throw<std::runtime_error>(archive_error_string(aw.get()));
 
  116        if (archive_write_finish_entry(aw.get()) < ARCHIVE_OK)
 
  117            Throw<std::runtime_error>(archive_error_string(aw.get()));