File size: 7,509 Bytes
8efb4bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#ifndef _DebugStream_h
#define _DebugStream_h

#include <iostream>
#include <fstream>
#include <cstdio>
#include <iomanip>
#include "Timer.h"

/*

CLASS

  DebugStream



  Defines a class for printing logs and debug information. User may determine

  the extent of the debugging information actually printed by setting the debug

  level.



KEYWORDS

  debug



AUTHORS

  Meir Fuchs. (meirfux@math.tau.ac.il)



  Copyright: SAMBA group, Tel-Aviv Univ. Israel, 1997.



CHANGES LOG

<UL>

<LI> Defining a streamer operator that supports printing endl

16/02/04 Oranit Dror

</LI>

<LI> Using unitbuf flag of Stream for autoflash instead of keeping our own flag

15/02/04 Dina Duhovny and Oranit Dror

</LI>

<LI> Added two functions that allows the usage of percision both regular and

in fixed floating point output

30/8/99 Zipi Fligelman

</LI>

<LI> Added the mode of the DebugStream owning it's ostream. This enables the

 user to construct the DebugStream with a file name and open/close the file

with the DebugStream object liveness.

5/9/99  Ram Nathaniel

<LI> Added the possibility to autoFlush - to make sure that debug messages are

not stuck in the buffers when the program crushes.

5/9/99 Ram Nathaniel

</UL



GOALS

  The DebugStream class was written for the purpose of debugging and generating

  run-time logs. The extent of the information actually printed by the stream

  is controlled by the debug level parameter. A level is attached to each

  message passed to the stream. If this level is smaller then the debug level

  the message is printed.



USAGE

  Using the DebugStream is quite straight-forward. The DebugStream use is

  similar to a regular output stream with a minor difference. A message level

  must be attached to each message. The message level is set by using

  operator() before commencing a sequence of operator<<.



  The following program will output all messages of level 10 and under.

  EXAMPLE

    DebugStream log(cout);

    log.setDebugLevel(10);

    log(10) << "This is a level " << 10 << " message";

    log << " and so is this";

    log(15) << "But this is a level" << 15 << " message and will not be shown";

            << " because the DebugLevel is lower";

    log() << "This is a level" << 0 << " message. You should definitely see it";

  END



  The debug stream can also be initialized by a file name. In this case the

  DebugStream will open the file when created and close it when done.



  The DebugStream class allows the user to control the format of the stream

  output. The user may choose to output the user time, a new-line after every

  message or the message level itself.



  If you wish the DebugStream not to use writing buffers use the autoFlush.

  This option may make the DebugStream work a little slower but will ensure

  that the data was written to the file before the next command was preformed.

*/
class DebugStream

{
public:
  enum{ADJUSTMENT_LEFT, ADJUSTMENT_RIGHT};

  //// Contructor: Intialize the DebugStream class with a true output stream
  // output that the DebugStream decides should be printed will be forwarded
  // to this output stream.
  explicit DebugStream(std::ostream& outStream = std::cout);

  //// Constructor: Initialize the DebugStream class with the name of the
  // output file. This way the class can be initilized when declared as a
  // global varialb. If file is unavailable DebugStream will use cerr and
  // will notify to the problem.
  explicit DebugStream(const char *filename);

  ////destructor: mainly closes the file if ownStream is true.
  ~DebugStream();

  //// Set the debug level controlling the extent of the debugging messages
  // seen. The higher the level the more messages the user will actually see.
  // This parameter may be read from a prameters file controlling the extent
  // of information actually shown during run-time.
  void setDebugLevel(const unsigned int debugLevel);

  //// In line function returning the debug level
  // for logging purposes
  inline unsigned getDebugLevel() const;

  //// flushing mechanism like that of the ostream type
  inline void flush();
  //// Set the new-lines option. If true, starting a new message with
  // operator() causes a new-line to be printed.
  void newLines(const bool print = true);

  //// Set the message levels option. If true, for each mesasage the message
  // level is shown at the beginning. Set to false by default.
  void messageLevels(const bool print = true);

  //// Set the timer option. If true the time of each message is shown at the
  // head of the message. The time show is the system's user time and not the
  // real clocked time.
  void messageTimes(const bool print = true);

  //// Set the indent option. If true log messages are indented according to
  // message levels. 2 spaces per 10 debug levels.
  void indent(const bool print = true);

  //// Resets timer to 0.
  void resetTimer();

  //// Useful Function for working with a specific floating point percision
  void setFloatPrecision(unsigned int prec);

  //// another useful funciton for indenting
  void setWidth(unsigned int prec);

  ////
  // A function for indentation:
  // Params: numOfChars - Sets the width of the filed
  //         adjustment - Defines the adjustment of the charecters
  //         within the field (possible options: left or right)
  void setWidth(unsigned int numOfChars, unsigned int adjustment);

  //// Set the automaticFlush on so that each writing to the stream will be
  // automatially accompanied by a flush.
  void autoFlush(const bool autoflush = true);

  //// Starts a new message specifying the messages level. If no message level
  // is given then a default message level of 0 is assumed and the message is
  // always shown.
  DebugStream& operator()(unsigned int newMsgLevel = 0);

  //// Output operator. If message was started with a low enough message level
  // then data will be passed on to the output stream with which DebugStream
  // was intialized.
  template<class T>
  DebugStream& operator<<(T& data);

  template<class T>
  DebugStream& operator<<(const T& data);

  // Zipi added to previos version since having problems
  //template<class T*>
  //DebugStream& operator<<(const T*& data);

  // Special overload to const char * const
  DebugStream& operator<<(const char* const data);

  DebugStream& operator<<(std::ostream& (*__pf)(std::ostream&));

private:
  // can't be a reference since it can be an ofstream or an ostream
  //according to the constructor used.
  std::ostream *out;
  unsigned int dbgLevel;
  bool withTimer;
  bool withNewLine;
  bool withLevel;
  bool withIndent;
  Timer timer;
  bool active;

  bool ownStream; //for use if constructed with a file name.
};
/**************************************

 *  Inline Function Implementation    *

 **************************************/
unsigned DebugStream::getDebugLevel() const
{
  return dbgLevel;
}

void DebugStream::flush()
{
  out->flush();
}

/**************************************

 *  Template Function Implementation  *

 **************************************/
template<class T>
DebugStream& DebugStream::operator<<(T& data)
{
  if (active)
    *out << data;

  return *this;
}

template<class T>
DebugStream& DebugStream::operator<<(const T& data)
{
  if (active)
    *out << data;

  return *this;
}


#endif