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 
10 namespace{
11  class fbuf final : public std::streambuf{
12  FILE *file;
13  char *buf;
14  constexpr static size_t bufsz = 4096;
15  public:
16  fbuf(FILE *f);
17  ~fbuf() override;
18  protected:
19  std::streambuf *setbuf(char_type *s, std::streamsize n) override;
20  int sync() override;
21  int_type underflow() override;
22  };
23 
24  class cfstream final : public std::istream{
25  fbuf buf;
26  public:
27  cfstream(FILE *f);
28  };
29 }
30 
31 std::unique_ptr<std::istream> reco::exprEvalDetails::popenCPP(const std::string &cmdline){
32  FILE *f = popen(cmdline.c_str(), "r");
33  if(!f)
34  throw cms::Exception("PopenCPP","(\""+cmdline+"\") failed");
35  return std::unique_ptr<std::istream>(new cfstream(f));
36 }
37 
38 
39 fbuf::fbuf(FILE *f)
40  : file(f), buf(new char[bufsz]){
41  this->setg(this->buf, this->buf+bufsz, this->buf+bufsz);
42 }
43 
44 fbuf::~fbuf(){
45  delete [] this->buf;
46  pclose(this->file);
47 }
48 
49 std::streambuf *fbuf::setbuf(char_type *s, std::streamsize n){
50  return nullptr;
51 }
52 
53 int fbuf::sync(){
54  if(fflush(this->file) != 0)
55  return -1;
56  return 0;
57 }
58 
59 fbuf::int_type fbuf::underflow(){
60  if(this->gptr() < this->egptr()){
61  char c = *this->gptr();
62  this->setg(this->eback(), this->gptr()+1, this->egptr());
63  return traits_type::to_int_type(c);
64  }
65  size_t n = fread(this->buf, 1, sizeof(this->buf), this->file);
66  if(n == 0)
67  return traits_type::eof();
68  this->setg(this->buf, this->buf, this->buf+n);
69  return traits_type::to_int_type(*this->gptr());
70 }
71 
72 cfstream::cfstream(FILE *f)
73  : std::istream(&buf), buf(f){
74 }
double f[11][100]
std::unique_ptr< std::istream > popenCPP(const std::string &cmdline)
Definition: popenCPP.cc:31
#define constexpr