Implement tellg() on ZStream, make multify -t work with .pz/.gz compressed multifiles

This commit is contained in:
rdb 2016-06-03 16:12:37 +02:00
parent 0d770deeaa
commit 679bf0a554
3 changed files with 32 additions and 18 deletions

View File

@ -18,6 +18,7 @@
#include "filename.h" #include "filename.h"
#include "pset.h" #include "pset.h"
#include "vector_string.h" #include "vector_string.h"
#include "virtualFileSystem.h"
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -631,8 +632,17 @@ list_files(const vector_string &params) {
cerr << multifile_name << " not found.\n"; cerr << multifile_name << " not found.\n";
return false; 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; 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"; cerr << "Unable to open " << multifile_name << " for reading.\n";
return false; return false;
} }

View File

@ -2297,9 +2297,11 @@ read_index() {
} }
// Now read the index out. // Now read the index out.
_next_index = read->tellg() - _offset; streampos curr_pos = read->tellg() - _offset;
_next_index = normalize_streampos(_next_index); _next_index = normalize_streampos(curr_pos);
read->seekg(_next_index + _offset); if (_next_index > curr_pos) {
read->ignore(_next_index - curr_pos);
}
_last_index = 0; _last_index = 0;
_last_data_byte = 0; _last_data_byte = 0;
streampos index_forward; streampos index_forward;
@ -2336,7 +2338,9 @@ read_index() {
} }
streampos curr_pos = normalize_streampos(read->tellg() - _offset); streampos curr_pos = normalize_streampos(read->tellg() - _offset);
bytes_skipped = index_forward - curr_pos; bytes_skipped = index_forward - curr_pos;
read->seekg(index_forward + _offset); if (bytes_skipped > 0) {
read->ignore(bytes_skipped);
}
_next_index = index_forward; _next_index = index_forward;
subfile = new Subfile; subfile = new Subfile;
index_forward = subfile->read_index(*read, _next_index, this); index_forward = subfile->read_index(*read, _next_index, this);

View File

@ -176,13 +176,19 @@ close_write() {
*/ */
streampos ZStreamBuf:: streampos ZStreamBuf::
seekoff(streamoff off, ios_seekdir dir, ios_openmode which) { seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
// Necessary for tellg() to work after seeking to 0. if (which != ios::in) {
if (dir == ios::cur && off == 0) { // We can only do this with the input stream.
if (_source->tellg() == (streampos)0) { return -1;
return 0; }
} else {
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) { if (off != 0 || dir != ios::beg) {
@ -190,12 +196,6 @@ seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
return -1; return -1;
} }
if (which != ios::in) {
// We can only do this with the input stream.
return -1;
}
size_t n = egptr() - gptr();
gbump(n); gbump(n);
_source->seekg(0, ios::beg); _source->seekg(0, ios::beg);