Merge branch 'v0.21.x' into master

This commit is contained in:
Max Kellermann
2020-09-04 18:35:21 +02:00
17 changed files with 185 additions and 110 deletions

View File

@@ -59,9 +59,9 @@ public:
class Bzip2InputStream final : public InputStream {
std::shared_ptr<InputStream> input;
bool eof = false;
bz_stream bzstream{};
bz_stream bzstream;
bool eof = false;
char buffer[5000];
@@ -69,7 +69,7 @@ public:
Bzip2InputStream(std::shared_ptr<InputStream> _input,
const char *uri,
Mutex &mutex);
~Bzip2InputStream() override;
~Bzip2InputStream() noexcept override;
/* virtual methods from InputStream */
[[nodiscard]] bool IsEOF() const noexcept override;
@@ -81,25 +81,6 @@ private:
bool FillBuffer();
};
/* single archive handling allocation helpers */
inline void
Bzip2InputStream::Open()
{
bzstream.bzalloc = nullptr;
bzstream.bzfree = nullptr;
bzstream.opaque = nullptr;
bzstream.next_in = (char *)buffer;
bzstream.avail_in = 0;
int ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
if (ret != BZ_OK)
throw std::runtime_error("BZ2_bzDecompressInit() has failed");
SetReady();
}
/* archive open && listing routine */
static std::unique_ptr<ArchiveFile>
@@ -118,10 +99,16 @@ Bzip2InputStream::Bzip2InputStream(std::shared_ptr<InputStream> _input,
:InputStream(_uri, _mutex),
input(std::move(_input))
{
Open();
bzstream.next_in = (char *)buffer;
int ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
if (ret != BZ_OK)
throw std::runtime_error("BZ2_bzDecompressInit() has failed");
SetReady();
}
Bzip2InputStream::~Bzip2InputStream()
Bzip2InputStream::~Bzip2InputStream() noexcept
{
BZ2_bzDecompressEnd(&bzstream);
}
@@ -151,22 +138,18 @@ Bzip2InputStream::FillBuffer()
size_t
Bzip2InputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t length)
{
const ScopeUnlock unlock(mutex);
int bz_result;
size_t nbytes = 0;
if (eof)
return 0;
const ScopeUnlock unlock(mutex);
bzstream.next_out = (char *)ptr;
bzstream.avail_out = length;
do {
if (!FillBuffer())
return 0;
const bool had_input = FillBuffer();
bz_result = BZ2_bzDecompress(&bzstream);
const int bz_result = BZ2_bzDecompress(&bzstream);
if (bz_result == BZ_STREAM_END) {
eof = true;
@@ -175,9 +158,12 @@ Bzip2InputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t length)
if (bz_result != BZ_OK)
throw std::runtime_error("BZ2_bzDecompress() has failed");
if (!had_input && bzstream.avail_out == length)
throw std::runtime_error("Unexpected end of bzip2 file");
} while (bzstream.avail_out == length);
nbytes = length - bzstream.avail_out;
const size_t nbytes = length - bzstream.avail_out;
offset += nbytes;
return nbytes;

View File

@@ -148,24 +148,22 @@ Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor)
class Iso9660InputStream final : public InputStream {
std::shared_ptr<Iso9660> iso;
iso9660_stat_t *statbuf;
const lsn_t lsn;
public:
Iso9660InputStream(std::shared_ptr<Iso9660> _iso,
const char *_uri,
Mutex &_mutex,
iso9660_stat_t *_statbuf)
lsn_t _lsn, offset_type _size)
:InputStream(_uri, _mutex),
iso(std::move(_iso)), statbuf(_statbuf) {
size = statbuf->size;
iso(std::move(_iso)),
lsn(_lsn)
{
size = _size;
seekable = true;
SetReady();
}
~Iso9660InputStream() override {
free(statbuf);
}
/* virtual methods from InputStream */
[[nodiscard]] bool IsEOF() const noexcept override;
size_t Read(std::unique_lock<Mutex> &lock,
@@ -185,8 +183,12 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
throw FormatRuntimeError("not found in the ISO file: %s",
pathname);
const lsn_t lsn = statbuf->lsn;
const offset_type size = statbuf->size;
free(statbuf);
return std::make_unique<Iso9660InputStream>(iso, pathname, mutex,
statbuf);
lsn, size);
}
size_t
@@ -197,7 +199,7 @@ Iso9660InputStream::Read(std::unique_lock<Mutex> &,
int readed = 0;
int no_blocks, cur_block;
size_t left_bytes = statbuf->size - offset;
size_t left_bytes = size - offset;
if (left_bytes < read_size) {
no_blocks = CEILING(left_bytes, ISO_BLOCKSIZE);
@@ -210,7 +212,7 @@ Iso9660InputStream::Read(std::unique_lock<Mutex> &,
cur_block = offset / ISO_BLOCKSIZE;
readed = iso->SeekRead(ptr, statbuf->lsn + cur_block, no_blocks);
readed = iso->SeekRead(ptr, lsn + cur_block, no_blocks);
if (readed != no_blocks * ISO_BLOCKSIZE)
throw FormatRuntimeError("error reading ISO file at lsn %lu",

View File

@@ -34,6 +34,8 @@
#include <utility>
#include <inttypes.h> /* for PRIoffset (PRIu64) */
struct ZzipDir {
ZZIP_DIR *const dir;
@@ -56,8 +58,9 @@ class ZzipArchiveFile final : public ArchiveFile {
std::shared_ptr<ZzipDir> dir;
public:
explicit ZzipArchiveFile(std::shared_ptr<ZzipDir> &&_dir)
:dir(std::move(_dir)) {}
template<typename D>
explicit ZzipArchiveFile(D &&_dir) noexcept
:dir(std::forward<D>(_dir)) {}
void Visit(ArchiveVisitor &visitor) override;
@@ -93,11 +96,12 @@ class ZzipInputStream final : public InputStream {
ZZIP_FILE *const file;
public:
ZzipInputStream(std::shared_ptr<ZzipDir> _dir, const char *_uri,
template<typename D>
ZzipInputStream(D &&_dir, const char *_uri,
Mutex &_mutex,
ZZIP_FILE *_file)
:InputStream(_uri, _mutex),
dir(std::move(_dir)), file(_file) {
dir(std::forward<D>(_dir)), file(_file) {
//we are seekable (but its not recommendent to do so)
seekable = true;
@@ -108,7 +112,7 @@ public:
SetReady();
}
~ZzipInputStream() override {
~ZzipInputStream() noexcept override {
zzip_file_close(file);
}
@@ -148,12 +152,17 @@ ZzipInputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t read_size)
{
const ScopeUnlock unlock(mutex);
int ret = zzip_file_read(file, ptr, read_size);
if (ret < 0)
zzip_ssize_t nbytes = zzip_file_read(file, ptr, read_size);
if (nbytes < 0)
throw std::runtime_error("zzip_file_read() has failed");
if (nbytes == 0 && !IsEOF())
throw FormatRuntimeError("Unexpected end of file %s"
" at %" PRIoffset " of %" PRIoffset,
GetURI(), GetOffset(), GetSize());
offset = zzip_tell(file);
return ret;
return nbytes;
}
bool