From 0ba1351d7a52df00b735b8ced7c4769371d8f0d1 Mon Sep 17 00:00:00 2001 From: Alexandra Rahlin Date: Fri, 29 Mar 2024 11:22:47 -0500 Subject: [PATCH] Do not allow seek after EOF in G3Reader (#153) Upstream merge of simonsobs/so3g#172 --- core/src/G3Reader.cxx | 9 +++++++-- core/tests/fileio.py | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) 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"