SGL
consolestreambuf.h
1 /*
2  * File: consolestreambuf.h
3  * ------------------------
4  * This file defines the <code>ConsoleStreambuf</code> class, which
5  * represents a stream buffer that reads/writes to the graphical console
6  * using a process pipe to a Java back-end process.
7  *
8  * @version 2021/04/03
9  * - removed dependency on error function
10  * @version 2016/10/04
11  * - initial version
12  */
13 
14 #ifndef _consolestreambuf_h
15 #define _consolestreambuf_h
16 
17 #include <exception>
18 #include <iostream>
19 #include <stdexcept>
20 #include <streambuf>
21 
22 namespace sgl {
23 
24 class ConsoleStreambuf : public std::streambuf {
25 protected:
26  /* Constants */
27  static const int BUFFER_SIZE = 4096;
28 
29  /* Instance variables */
30  char inBuffer[BUFFER_SIZE];
31  char outBuffer[BUFFER_SIZE];
32  int blocked;
33 
34  // to be overridden in subclasses
35  virtual void myEndLineConsole(bool isStderr) = 0;
36 
37  virtual string myGetLineConsole() = 0;
38 
39  virtual void myPutConsole(const string& str, bool isStderr) = 0;
40 
41 public:
42  ConsoleStreambuf() {
43  setg(inBuffer, inBuffer, inBuffer);
44  setp(outBuffer, outBuffer + BUFFER_SIZE);
45  blocked = 0;
46  }
47 
48  ~ConsoleStreambuf() {
49  /* Empty */
50  }
51 
52  virtual bool isBlocked() {
53  return blocked > 0;
54  }
55 
56  virtual int overflow(int ch = EOF) {
57  return overflow(ch, /* isStderr */ false);
58  }
59 
60  virtual int overflow(int ch, bool isStderr) {
61  string line = "";
62  for (char *cp = pbase(); cp < pptr(); cp++) {
63  if (*cp == '\n') {
64  myPutConsole(line, isStderr);
65  myEndLineConsole(isStderr);
66  line = "";
67  } else {
68  line += *cp;
69  }
70  }
71  if (line != "") {
72  myPutConsole(line, isStderr);
73  }
74  setp(outBuffer, outBuffer + BUFFER_SIZE);
75  if (ch != EOF) {
76  outBuffer[0] = ch;
77  pbump(1);
78  }
79  return ch != EOF;
80  }
81 
82  virtual int sync() {
83  return overflow();
84  }
85 
86  virtual int sync(bool isStderr) {
87  return overflow(EOF, isStderr);
88  }
89 
90  virtual int underflow() {
91  // Allow long strings at some point
92  blocked++;
93  string line = myGetLineConsole();
94  blocked--;
95 
96  bool eof = std::cin.eof();
97  fflush(stdout);
98 
99  if (eof) {
100  return EOF;
101  }
102 
103  int n = line.length();
104  if (n + 1 >= BUFFER_SIZE) {
105  throw std::runtime_error("ConsoleStreambuf::underflow: String too long");
106  }
107  for (int i = 0; i < n; i++) {
108  inBuffer[i] = line[i];
109  }
110  inBuffer[n++] = '\n';
111  inBuffer[n] = '\0';
112  setg(inBuffer, inBuffer, inBuffer + n);
113  return inBuffer[0];
114  }
115 };
116 
117 namespace qtgui {
118 
119 extern void endLineConsoleQt(bool isStderr);
120 extern string getLineConsoleQt();
121 extern void putConsoleQt(const string& str, bool isStderr);
122 
123 /*
124  * The following class is an exact copy of the ConsoleStreambuf class above,
125  * except using different Qt-related functions for output.
126  */
127 class ConsoleStreambufQt : public ::sgl::ConsoleStreambuf {
128 public:
129  ConsoleStreambufQt(bool isStderr = false)
130  : ConsoleStreambuf(),
131  _isStderr(isStderr) {
132  // empty
133  }
134 
135  ~ConsoleStreambufQt() {
136  /* Empty */
137  }
138 
139 protected:
140  virtual void myEndLineConsole(bool /* isStderr */) {
141  endLineConsoleQt(_isStderr);
142  }
143 
144  virtual string myGetLineConsole() {
145  return getLineConsoleQt();
146  }
147 
148  virtual void myPutConsole(const string& str, bool /* isStderr */) {
149  return putConsoleQt(str, _isStderr);
150  }
151 
152 private:
153  bool _isStderr;
154 };
155 
156 } // namespace qtgui
157 
158 } // namespace sgl
159 
160 #endif // _consolestreambuf_h
string getLineConsoleQt()
Definition: gconsolewindow.cpp:1443
Definition: console.h:293
void putConsoleQt(string str, bool isStderr)
Definition: gconsolewindow.cpp:1447
void endLineConsoleQt(bool isStderr)
Definition: gconsolewindow.cpp:1439