diff --git a/core/src/G3Reader.cxx b/core/src/G3Reader.cxx index 9daf36fc..b7c817c3 100644 --- a/core/src/G3Reader.cxx +++ b/core/src/G3Reader.cxx @@ -110,6 +110,8 @@ void G3Reader::Process(G3FramePtr frame, std::deque &out) } off_t G3Reader::Seek(off_t offset) { + if (stream_.peek() == EOF && offset != Tell()) + log_fatal("Cannot seek %s; stream closed at EOF.", cur_file_.c_str()); return boost::iostreams::seek(stream_, offset, std::ios_base::beg); } @@ -138,8 +140,11 @@ PYBINDINGS("core") { arg("n_frames_to_read")=0,arg("timeout")=-1.,arg("track_filename")=false))) .def(init, int, float, bool>((arg("filename"), arg("n_frames_to_read")=0, arg("timeout")=-1.,arg("track_filename")=false))) - .def("tell", &G3Reader::Tell) - .def("seek", &G3Reader::Seek) + .def("tell", &G3Reader::Tell, + "Return the current byte offset from start of stream.") + .def("seek", &G3Reader::Seek, + "Position the stream read pointer at specific byte offset. " + "Note that once EOF is reached, seek does not work anymore.") .def_readonly("__g3module__", true) ; } diff --git a/core/tests/fileio.py b/core/tests/fileio.py index c8b073dc..a4b1fcb5 100755 --- a/core/tests/fileio.py +++ b/core/tests/fileio.py @@ -113,3 +113,19 @@ def __call__(self, frame): pipe.Run() assert cached.pos is None, "Missing wiring frame" + +# check EOF handling +while cached.reader(None): + pass + +# can seek to EOF if at EOF +pos = cached.reader.tell() +cached.reader.seek(pos) + +# can't seek backward once at EOF +try: + cached.reader.seek(0) +except: + pass +else: + assert False, "Expected RuntimeError seeking back from EOF"