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 "pset.h"
#include "vector_string.h"
#include "virtualFileSystem.h"
#include <stdio.h>
#include <time.h>
@ -631,8 +632,17 @@ list_files(const vector_string &params) {
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;
}

View File

@ -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);

View File

@ -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);