Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:16

0001 // original code by the Minima Authors under the MIT license. See AUTHORS for the list of authors.
0002 
0003 #include "popenCPP.h"
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 #include <cstdio>
0006 #include <string>
0007 #include <istream>
0008 
0009 namespace {
0010   class fbuf final : public std::streambuf {
0011     FILE *file;
0012     char *buf;
0013     constexpr static size_t bufsz = 4096;
0014 
0015   public:
0016     fbuf(FILE *f);
0017     ~fbuf() override;
0018 
0019   protected:
0020     std::streambuf *setbuf(char_type *s, std::streamsize n) override;
0021     int sync() override;
0022     int_type underflow() override;
0023   };
0024 
0025   class cfstream final : public std::istream {
0026     fbuf buf;
0027 
0028   public:
0029     cfstream(FILE *f);
0030   };
0031 }  // namespace
0032 
0033 std::unique_ptr<std::istream> reco::exprEvalDetails::popenCPP(const std::string &cmdline) {
0034   FILE *f = popen(cmdline.c_str(), "r");
0035   if (!f)
0036     throw cms::Exception("PopenCPP", "(\"" + cmdline + "\") failed");
0037   return std::unique_ptr<std::istream>(new cfstream(f));
0038 }
0039 
0040 fbuf::fbuf(FILE *f) : file(f), buf(new char[bufsz]) { this->setg(this->buf, this->buf + bufsz, this->buf + bufsz); }
0041 
0042 fbuf::~fbuf() {
0043   delete[] this->buf;
0044   pclose(this->file);
0045 }
0046 
0047 std::streambuf *fbuf::setbuf(char_type *s, std::streamsize n) { return nullptr; }
0048 
0049 int fbuf::sync() {
0050   if (fflush(this->file) != 0)
0051     return -1;
0052   return 0;
0053 }
0054 
0055 fbuf::int_type fbuf::underflow() {
0056   if (this->gptr() < this->egptr()) {
0057     char c = *this->gptr();
0058     this->setg(this->eback(), this->gptr() + 1, this->egptr());
0059     return traits_type::to_int_type(c);
0060   }
0061   size_t n = fread(this->buf, 1, sizeof(this->buf), this->file);
0062   if (n == 0)
0063     return traits_type::eof();
0064   this->setg(this->buf, this->buf, this->buf + n);
0065   return traits_type::to_int_type(*this->gptr());
0066 }
0067 
0068 cfstream::cfstream(FILE *f) : std::istream(&buf), buf(f) {}