Skip to content

Commit ad59524

Browse files
committed
Fix input stream counter
1 parent 506f920 commit ad59524

File tree

1 file changed

+47
-2
lines changed

1 file changed

+47
-2
lines changed

core/src/dataio.cxx

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,51 @@ class LZMADecoder : public Decoder<lzma_stream, uint8_t> {
332332
};
333333
#endif
334334

335+
class InputStreamCounter : public std::streambuf {
336+
public:
337+
InputStreamCounter(std::streambuf* buffer)
338+
: buffer_(buffer), bytes_(0) {
339+
if (!buffer_)
340+
log_fatal("Input file stream buffer required");
341+
}
342+
343+
std::streampos bytes() const { return bytes_; }
344+
345+
protected:
346+
int_type underflow() {
347+
return buffer_->sgetc();
348+
}
349+
350+
std::streamsize xsgetn(char* s, std::streamsize n) {
351+
std::streamsize nget = buffer_->sgetn(s, n);
352+
if (nget > 0)
353+
bytes_ += nget;
354+
return nget;
355+
}
356+
357+
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way,
358+
std::ios_base::openmode mode) {
359+
// short-circuit for tellg
360+
if (off == 0 && way == std::ios_base::cur)
361+
return bytes_;
362+
std::streampos n = buffer_->pubseekoff(off, way, mode);
363+
if (n != std::streampos(std::streamoff(-1)))
364+
bytes_ = n;
365+
return n;
366+
}
367+
368+
std::streampos seekpos(std::streampos pos, std::ios_base::openmode mode) {
369+
std::streampos n = buffer_->pubseekpos(pos, mode);
370+
if (n != std::streampos(std::streamoff(-1)))
371+
bytes_ = n;
372+
return n;
373+
}
374+
375+
private:
376+
std::streambuf* buffer_;
377+
size_t bytes_;
378+
};
379+
335380
void
336381
g3_istream_from_path(std::istream &stream, const std::string &path, float timeout,
337382
size_t buffersize)
@@ -363,7 +408,7 @@ g3_istream_from_path(std::istream &stream, const std::string &path, float timeou
363408
// Read buffer
364409
fbuf = new std::vector<char>(buffersize);
365410
file->rdbuf()->pubsetbuf(fbuf->data(), buffersize);
366-
sbuf = file->rdbuf();
411+
sbuf = new InputStreamCounter(file->rdbuf());
367412
}
368413
}
369414

@@ -396,7 +441,7 @@ g3_istream_close(std::istream &stream)
396441
delete fbuf;
397442
stream.pword(2) = nullptr;
398443

399-
if (sbuf && (!file || sbuf != file->rdbuf()))
444+
if (sbuf)
400445
delete sbuf;
401446
stream.pword(1) = nullptr;
402447

0 commit comments

Comments
 (0)