Skip to content

Commit ad73d31

Browse files
authored
Hide boost::iostreams implementation behind smart pointers (#187)
This allows eventually rewriting the file IO ABI while ensuring STL iostream compatibility.
1 parent 356151b commit ad73d31

File tree

9 files changed

+132
-103
lines changed

9 files changed

+132
-103
lines changed

core/include/core/G3Reader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <string>
55
#include <vector>
6-
#include <dataio.h>
6+
#include <iostream>
77

88
#include <G3Module.h>
99

@@ -25,7 +25,7 @@ class G3Reader : public G3Module {
2525
bool prefix_file_;
2626
std::string cur_file_;
2727
std::deque<std::string> filename_;
28-
g3_istream stream_;
28+
std::shared_ptr<std::istream> stream_;
2929
int n_frames_to_read_;
3030
int n_frames_read_;
3131
int n_frames_cur_;

core/include/core/G3Writer.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define _G3_ARCWRITER_H
33

44
#include <string>
5-
#include <dataio.h>
5+
#include <iostream>
66

77
#include <G3Module.h>
88

@@ -13,12 +13,11 @@ class G3Writer : public G3Module {
1313
// Writes to file <filename> all frames with types in <streams>.
1414
// If <streams> is empty (default), writes all frames.
1515

16-
virtual ~G3Writer();
1716
void Process(G3FramePtr frame, std::deque<G3FramePtr> &out);
1817
void Flush();
1918
private:
2019
std::string filename_;
21-
g3_ostream stream_;
20+
std::shared_ptr<std::ostream> stream_;
2221
std::vector<G3Frame::FrameType> streams_;
2322

2423
SET_LOGGER("G3Writer");

core/include/core/dataio.h

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@
22
#define _G3_DATAIO_H
33

44
#include <string>
5-
#include <vector>
6-
#include <boost/iostreams/filtering_stream.hpp>
7-
8-
typedef boost::iostreams::filtering_istream g3_istream;
9-
typedef boost::iostreams::filtering_ostream g3_ostream;
5+
#include <memory>
6+
#include <iostream>
107

118
/**
129
* Configure a filtering stream for G3Frame decompression from a local or remote
1310
* file source.
1411
*
15-
* @param stream A reference to the filtering istream that will be configured
16-
* by this function. Must be instantiated prior to this
17-
* function.
1812
* @param path A valid filename on disk, or a TCP socket address. If a
1913
* filename, the compression scheme is determined from the file
2014
* extension. Supported compression schemes are gzip or bzip2.
@@ -25,36 +19,52 @@ typedef boost::iostreams::filtering_ostream g3_ostream;
2519
* read until EOF.
2620
* @param timeout Timeout in seconds for socket connections.
2721
* @param buffersize Advisory buffer size in bytes for aggregating reads
28-
* @return File descriptor for socket connections, or -1 for file input.
22+
* @return stream The input stream configured by this function.
23+
*/
24+
std::shared_ptr<std::istream>
25+
g3_istream_from_path(const std::string &path, float timeout=-1.0,
26+
size_t buffersize=1024*1024);
27+
28+
/**
29+
* Return the file descriptor handle for socket connections.
30+
*
31+
* @param stream A reference to the input stream, as configured by
32+
* g3_istream_from_path.
33+
* @return fd The socket file descriptor.
2934
*/
30-
int g3_istream_from_path(g3_istream &stream, const std::string &path,
31-
float timeout=-1.0, size_t buffersize=1024*1024);
35+
int g3_istream_handle(std::shared_ptr<std::istream> &stream);
3236

3337
/**
3438
* Configure a filtering stream for G3Frame compression to a local file.
3539
*
36-
* @param stream A reference to the filtering ostream that will be configured
37-
* by this function. Must be instantiated prior to this
38-
* function.
3940
* @param path A valid filename on disk. If a filename, the compression
4041
* scheme is determined from the file extension. Supported
4142
* compression schemes are gzip or bzip2.
4243
* @param append If true, append to an existing file on disk. Otherwise,
4344
* Create a new file or overwrite an existing file.
4445
* @param counter If true, add a counter filter to the stream configuration,
4546
* for use by the g3_ostream_count function.
47+
* @return stream The output stream configured by this function.
4648
*/
47-
void g3_ostream_to_path(g3_ostream &stream, const std::string &path,
48-
bool append=false, bool counter=false);
49+
std::shared_ptr<std::ostream>
50+
g3_ostream_to_path(const std::string &path, bool append=false, bool counter=false);
4951

5052
/**
5153
* Count the number of bytes written to the output file stream.
5254
*
53-
* @param stream A reference to the filtering ostream, as configured by
55+
* @param stream A reference to the output stream, as configured by
5456
* g3_ostream_to_path with the counter argument set to true.
5557
* @return Number of bytes written to disk.
5658
*/
57-
size_t g3_ostream_count(g3_ostream &stream);
59+
size_t g3_ostream_count(std::shared_ptr<std::ostream> &stream);
60+
61+
/**
62+
* Flush the output file stream.
63+
*
64+
* @param stream A reference to the output stream, as configured by
65+
* g3_ostream_to_path.
66+
*/
67+
void g3_ostream_flush(std::shared_ptr<std::ostream> &stream);
5868

5969
/**
6070
* Check that the input filename is a valid filename on disk.

core/src/G3Frame.cxx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <G3Quat.h>
44
#include <serialization.h>
55
#include <pybindings.h>
6-
#include <dataio.h>
76

87
#include <stdlib.h>
98
#include <cxxabi.h>
@@ -382,12 +381,12 @@ void G3Frame::blob_encode(struct blob_container &blob)
382381
item_os.flush();
383382
}
384383

385-
template void G3Frame::loads(g3_istream &);
384+
template <> void G3Frame::loads(std::shared_ptr<std::istream> &is) { loads(*is); }
386385
template void G3Frame::loads(G3BufferInputStream &);
387386
template void G3Frame::loads(std::istream &);
388387
template void G3Frame::loads(std::istringstream &);
389388

390-
template void G3Frame::saves(g3_ostream &) const;
389+
template <> void G3Frame::saves(std::shared_ptr<std::ostream> &os) const { saves(*os); }
391390
template void G3Frame::saves(G3BufferOutputStream &) const;
392391
template void G3Frame::saves(std::ostream &) const;
393392
template void G3Frame::saves(std::ostringstream &) const;

core/src/G3MultiFileWriter.cxx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class G3MultiFileWriter : public G3Module {
99
G3MultiFileWriter(boost::python::object filename,
1010
size_t size_limit,
1111
boost::python::object divide_on = boost::python::object());
12-
virtual ~G3MultiFileWriter();
1312
void Process(G3FramePtr frame, std::deque<G3FramePtr> &out);
1413
std::string CurrentFile() { return current_filename_; }
1514
private:
@@ -23,7 +22,7 @@ class G3MultiFileWriter : public G3Module {
2322
std::vector<G3Frame::FrameType> always_break_on_;
2423
boost::python::object newfile_callback_;
2524

26-
g3_ostream stream_;
25+
std::shared_ptr<std::ostream> stream_;
2726
std::vector<G3FramePtr> metadata_cache_;
2827
int seqno;
2928

@@ -78,7 +77,7 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
7877
{
7978
// If we are already saving data, check file size. Otherwise, open
8079
// a new file unconditionally.
81-
if (!stream_.empty()) {
80+
if (stream_ != nullptr) {
8281
bool start_new_ = false;
8382

8483
if (g3_ostream_count(stream_) > size_limit_)
@@ -117,19 +116,14 @@ G3MultiFileWriter::CheckNewFile(G3FramePtr frame)
117116
}
118117

119118
current_filename_ = filename;
120-
g3_ostream_to_path(stream_, filename, false, true);
119+
stream_ = g3_ostream_to_path(filename, false, true);
121120

122121
for (auto i = metadata_cache_.begin(); i != metadata_cache_.end(); i++)
123122
(*i)->saves(stream_);
124123

125124
return true;
126125
}
127126

128-
G3MultiFileWriter::~G3MultiFileWriter()
129-
{
130-
stream_.reset();
131-
}
132-
133127
void G3MultiFileWriter::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
134128
{
135129
bool new_file(false), meta_cached(false);

core/src/G3Reader.cxx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void G3Reader::StartFile(std::string path)
3434
log_info("Starting file %s\n", path.c_str());
3535
cur_file_ = path;
3636
n_frames_cur_ = 0;
37-
(void) g3_istream_from_path(stream_, path, timeout_, buffersize_);
37+
stream_ = g3_istream_from_path(path, timeout_, buffersize_);
3838
}
3939

4040
void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
@@ -71,7 +71,7 @@ void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
7171
// function reacquire the lock, if it was released.
7272
G3PythonContext ctx("G3Reader", false);
7373

74-
while (stream_.peek() == EOF) {
74+
while (stream_->peek() == EOF) {
7575
if (n_frames_cur_ == 0)
7676
log_error("Empty file %s", cur_file_.c_str());
7777
if (filename_.size() > 0) {
@@ -100,14 +100,14 @@ void G3Reader::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
100100
}
101101

102102
off_t G3Reader::Seek(off_t offset) {
103-
if (stream_.peek() == EOF && offset != Tell())
103+
if (stream_->peek() == EOF && offset != Tell())
104104
log_fatal("Cannot seek %s; stream closed at EOF.", cur_file_.c_str());
105-
stream_.seekg(offset, std::ios_base::beg);
105+
stream_->seekg(offset, std::ios_base::beg);
106106
return offset;
107107
}
108108

109109
off_t G3Reader::Tell() {
110-
return stream_.tellg();
110+
return stream_->tellg();
111111
}
112112

113113
PYBINDINGS("core") {

core/src/G3Writer.cxx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ G3Writer::G3Writer(std::string filename,
88
filename_(filename), streams_(streams)
99
{
1010
g3_check_output_path(filename);
11-
g3_ostream_to_path(stream_, filename, append);
12-
}
13-
14-
G3Writer::~G3Writer()
15-
{
16-
stream_.reset();
11+
stream_ = g3_ostream_to_path(filename, append);
1712
}
1813

1914
void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
@@ -38,9 +33,10 @@ void G3Writer::Process(G3FramePtr frame, std::deque<G3FramePtr> &out)
3833

3934
void G3Writer::Flush()
4035
{
41-
if (!stream_.strict_sync()){
42-
printf("There was a problem flushing the stream...\n");
43-
}
36+
try {
37+
g3_ostream_flush(stream_);
38+
} catch (...) {
39+
}
4440
}
4541

4642
PYBINDINGS("core") {

0 commit comments

Comments
 (0)