From 679bf0a554f647248a33156143765a9467f4e428 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Jun 2016 16:12:37 +0200 Subject: [PATCH] Implement tellg() on ZStream, make multify -t work with .pz/.gz compressed multifiles --- panda/src/downloadertools/multify.cxx | 12 +++++++++++- panda/src/express/multifile.cxx | 12 ++++++++---- panda/src/express/zStreamBuf.cxx | 26 +++++++++++++------------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/panda/src/downloadertools/multify.cxx b/panda/src/downloadertools/multify.cxx index 8caaa80736..72506f4095 100644 --- a/panda/src/downloadertools/multify.cxx +++ b/panda/src/downloadertools/multify.cxx @@ -18,6 +18,7 @@ #include "filename.h" #include "pset.h" #include "vector_string.h" +#include "virtualFileSystem.h" #include #include @@ -631,8 +632,17 @@ list_files(const vector_string ¶ms) { cerr << multifile_name << " not found.\n"; return false; } + // We happen to know that we can read the index without doing a seek. + // So this is the only place where we accept a .pz/.gz compressed .mf. + VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); + istream *istr = vfs->open_read_file(multifile_name, true); + if (istr == NULL) { + cerr << "Unable to open " << multifile_name << " for reading.\n"; + return false; + } + PT(Multifile) multifile = new Multifile; - if (!multifile->open_read(multifile_name)) { + if (!multifile->open_read(new IStreamWrapper(istr, true), true)) { cerr << "Unable to open " << multifile_name << " for reading.\n"; return false; } diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index b0a1952a6c..63177a3dfe 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -2297,9 +2297,11 @@ read_index() { } // Now read the index out. - _next_index = read->tellg() - _offset; - _next_index = normalize_streampos(_next_index); - read->seekg(_next_index + _offset); + streampos curr_pos = read->tellg() - _offset; + _next_index = normalize_streampos(curr_pos); + if (_next_index > curr_pos) { + read->ignore(_next_index - curr_pos); + } _last_index = 0; _last_data_byte = 0; streampos index_forward; @@ -2336,7 +2338,9 @@ read_index() { } streampos curr_pos = normalize_streampos(read->tellg() - _offset); bytes_skipped = index_forward - curr_pos; - read->seekg(index_forward + _offset); + if (bytes_skipped > 0) { + read->ignore(bytes_skipped); + } _next_index = index_forward; subfile = new Subfile; index_forward = subfile->read_index(*read, _next_index, this); diff --git a/panda/src/express/zStreamBuf.cxx b/panda/src/express/zStreamBuf.cxx index 2662478e16..c6af03499b 100644 --- a/panda/src/express/zStreamBuf.cxx +++ b/panda/src/express/zStreamBuf.cxx @@ -176,13 +176,19 @@ close_write() { */ streampos ZStreamBuf:: seekoff(streamoff off, ios_seekdir dir, ios_openmode which) { - // Necessary for tellg() to work after seeking to 0. - if (dir == ios::cur && off == 0) { - if (_source->tellg() == (streampos)0) { - return 0; - } else { - return -1; - } + if (which != ios::in) { + // We can only do this with the input stream. + return -1; + } + + // Determine the current position. + size_t n = egptr() - gptr(); + streampos gpos = _z_source.total_out - n; + + // Implement tellg() and seeks to current position. + if ((dir == ios::cur && off == 0) || + (dir == ios::beg && off == gpos)) { + return gpos; } if (off != 0 || dir != ios::beg) { @@ -190,12 +196,6 @@ seekoff(streamoff off, ios_seekdir dir, ios_openmode which) { return -1; } - if (which != ios::in) { - // We can only do this with the input stream. - return -1; - } - - size_t n = egptr() - gptr(); gbump(n); _source->seekg(0, ios::beg);