Merge branch 'v0.21.x' into master
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user