File indexing completed on 2024-04-06 12:01:20
0001
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 }
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) {}