Skip to content

Commit

Permalink
[FOLD] unique_ptr to manage archive* resource
Browse files Browse the repository at this point in the history
  • Loading branch information
mellery451 committed Jun 5, 2018
1 parent d7a43bc commit 07415db
Showing 1 changed file with 38 additions and 50 deletions.
88 changes: 38 additions & 50 deletions src/ripple/basics/impl/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,53 @@ extractTarLz4(
boost::filesystem::path const& src,
boost::filesystem::path const& dst)
{
auto ar {archive_read_new()};
archive_read_support_format_tar(ar);
archive_read_support_filter_lz4(ar);
using archive_ptr =
std::unique_ptr<struct archive, void(*)(struct archive*)>;

archive_ptr ar {archive_read_new(),
[](struct archive* ar)
{
//TODO check return status, but can't throw
archive_read_close(ar);
archive_read_free(ar);
}};

archive_read_support_format_tar(ar.get());
archive_read_support_filter_lz4(ar.get());

// LibArchive example suggests this buffer size
int result {archive_read_open_filename(ar, src.string().c_str(), 10240)};
if (result != ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(ar));
if (archive_read_open_filename(ar.get(), src.string().c_str(), 10240) < ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(ar.get()));

archive_ptr aw {archive_write_disk_new(),
[](struct archive* aw)
{
//TODO check return status, but can't throw
archive_write_close(aw);
archive_write_free(aw);
}};

auto aw {archive_write_disk_new()};
archive_write_disk_set_options(
aw,
aw.get(),
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM |
ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS);
archive_write_disk_set_standard_lookup(aw);
archive_write_disk_set_standard_lookup(aw.get());

std::string err;
int result {0};
struct archive_entry *entry;
while(true)
{
result = archive_read_next_header(ar, &entry);
result = archive_read_next_header(ar.get(), &entry);
if (result == ARCHIVE_EOF)
break;
if (result != ARCHIVE_OK)
{
err = archive_error_string(ar);
break;
}
if (result != ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(ar.get()));

archive_entry_set_pathname(
entry,
(dst / archive_entry_pathname(entry)).string().c_str());
result = archive_write_header(aw, entry);
if (result != ARCHIVE_OK)
{
err = archive_error_string(aw);
break;
}
if (archive_write_header(aw.get(), entry) < ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(aw.get()));

if (archive_entry_size(entry) > 0)
{
Expand All @@ -76,41 +85,20 @@ extractTarLz4(
la_int64_t offset;
while (true)
{
result = archive_read_data_block(ar, &buff, &size, &offset);
result = archive_read_data_block(ar.get(), &buff, &size, &offset);
if (result == ARCHIVE_EOF)
break;
if (result != ARCHIVE_OK)
{
err = archive_error_string(ar);
break;
}
if (result < ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(ar.get()));

result = archive_write_data_block(aw, buff, size, offset);
if (result != ARCHIVE_OK)
{
err = archive_error_string(aw);
break;
}
if (archive_write_data_block(aw.get(), buff, size, offset) < ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(aw.get()));
}
if (!err.empty())
break;
}

result = archive_write_finish_entry(aw);
if (result != ARCHIVE_OK)
{
err = archive_error_string(aw);
break;
}
if (archive_write_finish_entry(aw.get()) < ARCHIVE_OK)
Throw<std::runtime_error>(archive_error_string(aw.get()));
}

archive_read_close(ar);
archive_read_free(ar);
archive_write_close(aw);
archive_write_free(aw);

if (!err.empty())
Throw<std::runtime_error>(err);
}

} // ripple

0 comments on commit 07415db

Please sign in to comment.