CMS 3D CMS Logo

popenCPP.cc
Go to the documentation of this file.
1 // original code by the Minima Authors under the MIT license. See AUTHORS for the list of authors.
2 
3 #include "popenCPP.h"
5 #include <cstdio>
6 #include <string>
7 #include <istream>
8 
9 namespace {
10  class fbuf final : public std::streambuf {
11  FILE *file;
12  char *buf;
13  constexpr static size_t bufsz = 4096;
14 
15  public:
16  fbuf(FILE *f);
17  ~fbuf() override;
18 
19  protected:
20  std::streambuf *setbuf(char_type *s, std::streamsize n) override;
21  int sync() override;
22  int_type underflow() override;
23  };
24 
25  class cfstream final : public std::istream {
26  fbuf buf;
27 
28  public:
29  cfstream(FILE *f);
30  };
31 } // namespace
32 
33 std::unique_ptr<std::istream> reco::exprEvalDetails::popenCPP(const std::string &cmdline) {
34  FILE *f = popen(cmdline.c_str(), "r");
35  if (!f)
36  throw cms::Exception("PopenCPP", "(\"" + cmdline + "\") failed");
37  return std::unique_ptr<std::istream>(new cfstream(f));
38 }
39 
40 fbuf::fbuf(FILE *f) : file(f), buf(new char[bufsz]) { this->setg(this->buf, this->buf + bufsz, this->buf + bufsz); }
41 
42 fbuf::~fbuf() {
43  delete[] this->buf;
44  pclose(this->file);
45 }
46 
47 std::streambuf *fbuf::setbuf(char_type *s, std::streamsize n) { return nullptr; }
48 
49 int fbuf::sync() {
50  if (fflush(this->file) != 0)
51  return -1;
52  return 0;
53 }
54 
55 fbuf::int_type fbuf::underflow() {
56  if (this->gptr() < this->egptr()) {
57  char c = *this->gptr();
58  this->setg(this->eback(), this->gptr() + 1, this->egptr());
59  return traits_type::to_int_type(c);
60  }
61  size_t n = fread(this->buf, 1, sizeof(this->buf), this->file);
62  if (n == 0)
63  return traits_type::eof();
64  this->setg(this->buf, this->buf, this->buf + n);
65  return traits_type::to_int_type(*this->gptr());
66 }
67 
68 cfstream::cfstream(FILE *f) : std::istream(&buf), buf(f) {}
double f[11][100]
std::unique_ptr< std::istream > popenCPP(const std::string &cmdline)
Definition: popenCPP.cc:33