FACT++  1.0
WindowLog.cc
Go to the documentation of this file.
1 // **************************************************************************
15 // **************************************************************************
16 #include "WindowLog.h"
17 
18 #include <sstream>
19 #include <iostream>
20 #include <algorithm>
21 
22 #include <curses.h>
23 
24 #include "tools.h"
25 
26 using namespace std;
27 
28 // --------------------------------------------------------------------------
29 //
31 //
33 {
34  fMuxBacklog.lock();
35  fBacklog.clear();
36  fMuxBacklog.unlock();
37 }
38 
39 // --------------------------------------------------------------------------
40 //
45 //
46 void WindowLog::Display(bool empty)
47 {
48  if (!fWindow)
49  {
50  fMuxBacklog.lock();
51  fMuxCout.lock();
52 
53  cout.write(fBacklog.data(), fBacklog.size());
54  cout.flush();
55 
56  if (empty)
57  fBacklog.clear();
58 
59  fMuxCout.unlock();
60  fMuxBacklog.unlock();
61  return;
62  }
63 
64  const int w = getmaxx(fWindow);
65 
66  fMuxBacklog.lock();
67  fMuxWindow.lock();
68  //vector<char>::iterator p0 = fBacklog.begin();
69 
70  int lines = 0;
71  int x = 0;
72 
73  for (unsigned int i=0; i<fBacklog.size(); i++)
74  {
75  if (fAttributes.find(i)!=fAttributes.end())
76  fAttributes[i]==-1 ? wattrset(fWindow, 0) : wattron(fWindow, fAttributes[i]);
77 
78  if (fBacklog[i]=='\n')
79  {
80  // The attribute is added to the backlog in WriteBuffer
81  //wattrset(fWindow, 0);
82  lines += x/w + 1;
83  x=0;
84  }
85  wprintw(fWindow, "%c", fBacklog[i]);
86  x++;
87  }
88 
89  if (empty)
90  fBacklog.clear();
91 
92  fMuxWindow.unlock();
93  fMuxBacklog.unlock();
94 
95  lines += x/w;
96 }
97 
98 // --------------------------------------------------------------------------
99 //
110 //
111 bool WindowLog::OpenLogFile(const string &filename, bool append)
112 {
113  fMuxFile.lock();
114  flush();
115 
116  if (fLogFile.is_open())
117  fLogFile.close();
118 
119  fLogFile.open(filename, append ? ios::app|ios::out : ios::out);
120  if (append)
121  fLogFile << '\n';
122 
123  fMuxFile.unlock();
124 
125  return fLogFile.is_open();
126 }
127 
128 // --------------------------------------------------------------------------
129 //
131 //
133 {
134  fMuxFile.lock();
135  fLogFile.close();
136  fMuxFile.unlock();
137 }
138 
139 bool WindowLog::WriteFile(const string &sout)
140 {
141  fMuxFile.lock();
142  fLogFile << sout;
143  fLogFile.flush();
144  fMuxFile.unlock();
145 
146  return true;
147 }
148 
149 // --------------------------------------------------------------------------
150 //
164 //
166 {
167  // Store the number of characters in the buffer which should be flushed
168  const int len = fPPtr - fBase;
169 
170  // restart writing to the buffer at its first char
171  fPPtr = fBase;
172 
173  // If the is nothing to output, we are done
174  if (len<=0)
175  return;
176 
177  // FIXME: Truncate backlog!
178 
179  // If fWindow is set, output everything to the window, otherwise
180  // to cout
181  if (!fIsNull)
182  {
183  if (fWindow)
184  {
185  fMuxWindow.lock();
186  if (!fIsNull)
187  {
188  const string sout = string(fBase, len);
189  wprintw(fWindow, "%s", sout.c_str());
190  }
191  // If the stream got flushed due to a line break
192  // reset all attributes
193  if (fBase[len-1]=='\n')
194  wattrset(fWindow, 0);
195  fMuxWindow.unlock();
196  }
197  else
198  {
199  fMuxCout.lock();
200  cout.write(fBase, len);// << sout;
201  // If the stream got flushed due to a line break
202  // reset all attributes
203  if (fBase[len-1]=='\n')
204  cout << "\033[0m";
205  cout.flush();
206  fMuxCout.unlock();
207  }
208  }
209 
210  // Add the buffer to the backlog
211  if (fEnableBacklog)
212  {
213  fMuxBacklog.lock();
214  fBacklog.insert(fBacklog.end(), fBase, fBase+len);
215 
216  // If the stream got flushed due to a line break
217  // add the reset of all attributes to the backlog
218  if (fBase[len-1]=='\n')
219  {
220  if (!fWindow)
221  {
222  const char *reset = "\033[0m";
223  fBacklog.insert(fBacklog.end(), reset, reset+4);
224 
225  }
226  else
227  fAttributes[fBacklog.size()] = -1;
228  }
229  fMuxBacklog.unlock();
230  }
231 
232  fQueueFile.emplace(fBase, len);
233  /*
234  // Output everything also to the log-file
235  fMuxFile.lock();
236  fLogFile << sout;
237  //fLogFile.flush();
238  fMuxFile.unlock();
239  */
240  // If we are flushing because of an EOL, we reset also all attributes
241 }
242 
243 // --------------------------------------------------------------------------
244 //
246 //
248 {
249  WriteBuffer();
250  return 0;
251 }
252 
253 // --------------------------------------------------------------------------
254 //
260 //
261 int WindowLog::overflow(int i) // i=EOF means not a real overflow
262 {
263  *fPPtr++ = (char)i;
264 
265  if (fPPtr == fEPtr)
266  WriteBuffer();
267 
268  return 0;
269 }
270 
271 // --------------------------------------------------------------------------
272 //
277 //
278 string WindowLog::GetSizeStr() const
279 {
280  int s = GetSizeBacklog()/1000;
281  if (s==0)
282  return "0";
283 
284  char u = 'k';
285  if (s>999)
286  {
287  s/=1000;
288  u = 'M';
289  }
290 
291  ostringstream str;
292  str << s << u;
293  return str.str();
294 }
295 
296 // --------------------------------------------------------------------------
297 //
300 //
302 {
303  if (m==kReset || m==kDefault)
304  return "\033[0m";
305 
306  string rc;
307 
308  if ((m&COLOR_PAIR(kRed) )==COLOR_PAIR(kRed) ) rc += "\033[31m";
309  if ((m&COLOR_PAIR(kGreen) )==COLOR_PAIR(kGreen) ) rc += "\033[32m";
310  if ((m&COLOR_PAIR(kYellow) )==COLOR_PAIR(kYellow) ) rc += "\033[33m";
311  if ((m&COLOR_PAIR(kBlue) )==COLOR_PAIR(kBlue) ) rc += "\033[34m";
312  if ((m&COLOR_PAIR(kMagenta))==COLOR_PAIR(kMagenta)) rc += "\033[35m";
313  if ((m&COLOR_PAIR(kCyan) )==COLOR_PAIR(kCyan) ) rc += "\033[36m";
314  if ((m&COLOR_PAIR(kWhite) )==COLOR_PAIR(kWhite) ) rc += "\033[0m\033[1m";
315 
316  if ((m&kBold )==kBold ) rc += "\033[1m";
317  if ((m&kDim )==kDim ) rc += "\033[2m";
318  if ((m&kUnderline)==kUnderline) rc += "\033[4m";
319  if ((m&kBlink )==kBlink ) rc += "\033[5m";
320 
321  return rc;
322 }
323 
324 // --------------------------------------------------------------------------
325 //
331 //
333 {
334  const int col = COLOR_PAIR(m);
335 
336  if (!fWindow)
337  // We don't have to flush here, because the attributes are simply
338  // part of the stream
339  *this << GetAnsiAttr(col);
340  else
341  {
342  // Before we change the attributes we have to flush the screen
343  // otherwise we would have to buffer them until we flush the
344  // contents
345  flush();
346  wattron(fWindow, col);
347  }
348 
349  fMuxBacklog.lock();
350  fAttributes[fBacklog.size()] |= col;
351  fMuxBacklog.unlock();
352 }
353 
354 // --------------------------------------------------------------------------
355 //
361 //
363 {
364  if (!fWindow)
365  // We don't have to flush here, because the attributes are simply
366  // part of the stream
367  *this << GetAnsiAttr(m);
368  else
369  {
370  // Before we change the attributes we have to flush the screen
371  // otherwise we would have to buffer them until we flush the
372  // contents
373  flush();
374  m==kReset ? wattrset(fWindow, 0) : wattron(fWindow, m);
375  }
376 
377  fMuxBacklog.lock();
378  m==kReset ?
379  fAttributes[fBacklog.size()] = -1 :
380  fAttributes[fBacklog.size()] |= m;
381  fMuxBacklog.unlock();
382 }
383 
384 // --------------------------------------------------------------------------
385 //
387 //
388 std::ostream &operator<<(std::ostream &lout, WindowLogColor m)
389 {
390  WindowLog *log=dynamic_cast<WindowLog*>(lout.rdbuf());
391  if (log)
392  log->AddColor(m);
393  return lout;
394 }
395 
396 // --------------------------------------------------------------------------
397 //
399 //
400 std::ostream &operator<<(std::ostream &lout, WindowLogAttrs m)
401 {
402  WindowLog *log=dynamic_cast<WindowLog*>(lout.rdbuf());
403  if (log)
404  log->AddAttr(m);
405  return lout;
406 }
bool WriteFile(const std::string &)
Definition: WindowLog.cc:139
Set color Cyan.
Definition: WindowLog.h:22
Set color White.
Definition: WindowLog.h:23
static std::string GetAnsiAttr(int m)
Definition: WindowLog.cc:301
void CloseLogFile()
Close a log-file.
Definition: WindowLog.cc:132
int i
Definition: db_dim_client.c:21
Set color Green.
Definition: WindowLog.h:18
char str[80]
Definition: test_client.c:7
A C++ ostream to an ncurses window supporting attributes and colors.
Definition: WindowLog.h:50
Set color Yellow.
Definition: WindowLog.h:19
Set attribute Blink.
Definition: WindowLog.h:34
Set color Red.
Definition: WindowLog.h:17
Set default colors.
Definition: WindowLog.h:16
STL namespace.
void EmptyBacklog()
Empty backlog.
Definition: WindowLog.cc:32
WindowLogColor
Stream manipulators to change the color of a WindowLog stream.
Definition: WindowLog.h:14
Set attribute Underline.
Definition: WindowLog.h:32
std::ostream & operator<<(std::ostream &lout, WindowLogColor m)
Definition: WindowLog.cc:388
int sync()
This is called to flush the buffer of the streaming devices.
Definition: WindowLog.cc:247
std::string GetSizeStr() const
Definition: WindowLog.cc:278
void AddColor(int m)
Definition: WindowLog.cc:332
Set color Magenta.
Definition: WindowLog.h:21
void AddAttr(int m)
Definition: WindowLog.cc:362
Set color Blue.
Definition: WindowLog.h:20
Set attribute Dim.
Definition: WindowLog.h:35
void WriteBuffer()
Definition: WindowLog.cc:165
void Display(bool empty=false)
Display backlog.
Definition: WindowLog.cc:46
WindowLogAttrs
Stream manipulators to change the attributes of a WindowLog stream.
Definition: WindowLog.h:27
void reset(S &s)
Definition: ByteOrder.h:13
int overflow(int i)
Definition: WindowLog.cc:261
bool OpenLogFile(const std::string &filename, bool append=false)
Open a log-file.
Definition: WindowLog.cc:111
Reset all attributes.
Definition: WindowLog.h:29
Set attribute Bold.
Definition: WindowLog.h:36