Merge pull request #67 from tripzero/trip
[profile/ivi/automotive-message-broker.git] / lib / debugout.h
1 /*
2 Copyright (C) 2012 Intel Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #ifndef DEBUGOUT__H__
20 #define DEBUGOUT__H__
21
22 #include <string>
23 #include <iostream>
24 #include <fstream>
25 #include <sstream>
26 #include <stdexcept>
27 #include "timestamp.h"
28
29 using namespace std;
30
31 void debugOut(const string &message);
32
33 /*! \addtogroup libamb
34  *  @{
35  */
36
37 /*!
38  * \file debugout.h
39  * \brief The DebugOut class represents a class used for outputing debug information
40  * The specified debug level will only be outputed if the debug level is => the debug threshhold
41  * Here's a simple example:
42  * \code
43  * DebugOut::setDebugThreshhold(3);
44  * DebugOut(DebugOut::Warning) << "This is a warning" << std::endl;
45  * DebugOut(3) << "This will only show if the threshhold is 3 or lower." << std::endl;
46  *
47  * /// Start logging to a file:
48  * ofstream logfile;
49  * logfile.open("amb.log", ios::out | ios::trunc);
50  * DebugOut::setOutput(logfile)
51  *
52  * /// Throw exception on warning or error:
53  * DebugOut::setThrowErr(true);
54  * DebugOut::setThrowWarn(true);
55  * DebugOut(DebugOut::Error) << "This will throw an exception." << std::endl;
56  *
57  * /// Log to stderr:
58  * DebugOut::setOutput(std::cerr);
59  * DebugOut() << "This will log to stderr." << std::endl;
60  * \endcode
61  */
62
63 namespace amb
64 {
65 /*!
66  * \brief deprecateMethod prints warning if method is used.  Throws if version >= PROJECT_SERIES
67  * \param methodName name of method being deprecated.
68  * \param version version in which this method will no longer function in.
69  */
70 void deprecateMethod(const string &methodName, const std::string & version);
71 }
72
73 class DebugOut
74 {
75 public:
76
77         /*!
78          * \brief Error use when essential functionality is blocked
79          */
80         static const int Error;
81
82         /*!
83          * \brief Warning use when non-essential functionality is bocked, or when workarounds exist.
84          */
85         static const int Warning;
86
87         DebugOut(int debugLevel = 4)
88         {
89                 mDebugLevel = debugLevel;
90
91                 if(mDebugLevel <= debugThreshhold || mDebugLevel == Error || mDebugLevel == Warning)
92                 {
93                         ostream out(buf);
94                         out.precision(15);
95                         out<<bufferTime(amb::currentTime())<<" | ";
96
97                         if(mDebugLevel == Error)
98                                 out<<"ERROR ";
99                         if(mDebugLevel == Warning)
100                                 out<<"WARNING ";
101                 }
102         }
103
104         DebugOut(const std::string & toLog, int debugLevel = 4)
105                 :DebugOut(debugLevel)
106         {
107                 (*this) << toLog << endl;
108         }
109
110         DebugOut const& operator << (const string &message) const
111         {
112                 if(mDebugLevel <= debugThreshhold || mDebugLevel == Error || mDebugLevel == Warning)
113                 {
114                         ostream out(buf);
115                         out.precision(15);
116                         out<<message;
117                 }
118                 return *this;
119         }
120
121         DebugOut const& operator << (ostream & (*manip)(std::ostream&)) const
122         {
123                 if(mDebugLevel <= debugThreshhold || mDebugLevel == Error || mDebugLevel == Warning)
124                 {
125                         ostream out(buf);
126                         out.precision(15);
127                         out<<endl;
128
129                         if((mDebugLevel == Error && throwErr))
130                         {
131                                 throw std::runtime_error("Abort on Error is set");
132                         }
133                         else if ((mDebugLevel == Warning && throwWarn))
134                         {
135                                 throw std::runtime_error("Abort on Warning is set");
136                         }
137                 }
138                 return *this;
139         }
140
141         DebugOut const & operator << (double val) const
142         {
143                 if(mDebugLevel <= debugThreshhold || mDebugLevel == Error || mDebugLevel == Warning)
144                 {
145                         ostream out(buf);
146                         out.precision(15);
147                         out<<val;
148                 }
149                 return *this;
150         }
151
152         static void setDebugThreshhold(int th)
153         {
154                 debugThreshhold = th;
155         }
156
157         static void setOutput(ostream &o)
158         {
159                 buf = o.rdbuf();
160         }
161
162         static void setThrowWarn(bool v)
163         {
164                 throwWarn = v;
165         }
166
167         static void setThrowErr(bool v)
168         {
169                 throwErr = v;
170         }
171
172         static const int getDebugThreshhold()
173         {
174                 return debugThreshhold;
175         }
176
177 private:
178
179         std::string bufferTime(double time)
180         {
181                 ostringstream f;
182
183                 f.precision(15);
184
185                 f<<time;
186
187                 while(f.str().length() <= 15)
188                 {
189                         f<<" ";
190                 }
191
192                 return f.str();
193         }
194
195         static int debugThreshhold;
196         static std::streambuf *buf;
197         static bool throwWarn;
198         static bool throwErr;
199         int mDebugLevel;
200 };
201
202 #endif
203
204 /** @} */