1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #ifndef _LOG4CXX_LEVEL_H 19 #define _LOG4CXX_LEVEL_H 20 21 22 #include <log4cxx/logstring.h> 23 #include <limits.h> 24 #include <log4cxx/helpers/objectimpl.h> 25 #include <log4cxx/helpers/objectptr.h> 26 27 #if defined(_MSC_VER) 28 #pragma warning ( push ) 29 #pragma warning ( disable: 4251 ) 30 #endif 31 32 namespace log4cxx 33 { 34 /** 35 * LOG4CXX_PTR_DEF can't be used to get a smart pointer for Level because we need to override 36 * the comparison operator and this doesn't work if the template has alread been initialized, 37 * which is what the macro does on some platforms. The overriding takes place underneath the 38 * definition of Level because we need one of it's methods. 39 * 40 * https://issues.apache.org/jira/browse/LOGCXX-394 41 */ 42 class Level; 43 typedef log4cxx::helpers::ObjectPtrT<Level> LevelPtr; 44 45 /** 46 Defines the minimum set of levels recognized by the system, that is 47 <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>, 48 <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code> and 49 <code>ALL</code>. 50 <p>The <code>Level</code> class may be subclassed to define a larger 51 level set. 52 */ 53 class LOG4CXX_EXPORT Level : public helpers::ObjectImpl 54 { 55 public: 56 class LOG4CXX_EXPORT LevelClass : public helpers::Class 57 { 58 public: LevelClass()59 LevelClass() : helpers::Class() {} 60 getName()61 virtual LogString getName() const 62 { 63 return LOG4CXX_STR("Level"); 64 } 65 toLevel(const LogString & sArg)66 virtual LevelPtr toLevel(const LogString& sArg) const 67 { 68 return Level::toLevelLS(sArg); 69 } 70 toLevel(int val)71 virtual LevelPtr toLevel(int val) const 72 { 73 return Level::toLevel(val); 74 } 75 }; 76 77 DECLARE_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(Level, LevelClass) 78 BEGIN_LOG4CXX_CAST_MAP() 79 LOG4CXX_CAST_ENTRY(Level) 80 END_LOG4CXX_CAST_MAP() 81 82 /** 83 Instantiate a Level object. 84 */ 85 Level(int level, 86 const LogString& name, 87 int syslogEquivalent); 88 89 /** 90 Convert the string passed as argument to a level. If the 91 conversion fails, then this method returns DEBUG. 92 * @param sArg level name. 93 */ 94 static LevelPtr toLevel(const std::string& sArg); 95 /** 96 Convert the string passed as argument to a level. If the 97 conversion fails, then this method returns the value of 98 <code>defaultLevel</code>. 99 * @param sArg level name. 100 * @param defaultLevel level to return if no match. 101 * @return 102 */ 103 static LevelPtr toLevel(const std::string& sArg, 104 const LevelPtr& defaultLevel); 105 /** 106 * Get the name of the level in the current encoding. 107 * @param name buffer to which name is appended. 108 */ 109 void toString(std::string& name) const; 110 111 #if LOG4CXX_WCHAR_T_API 112 /** 113 Convert the string passed as argument to a level. If the 114 conversion fails, then this method returns DEBUG. 115 * @param sArg level name. 116 */ 117 static LevelPtr toLevel(const std::wstring& sArg); 118 /** 119 Convert the string passed as argument to a level. If the 120 conversion fails, then this method returns the value of 121 <code>defaultLevel</code>. 122 * @param sArg level name. 123 * @param defaultLevel level to return if no match. 124 * @return 125 */ 126 static LevelPtr toLevel(const std::wstring& sArg, 127 const LevelPtr& defaultLevel); 128 /** 129 * Get the name of the level. 130 * @param name buffer to which name is appended. 131 */ 132 void toString(std::wstring& name) const; 133 #endif 134 #if LOG4CXX_UNICHAR_API 135 /** 136 Convert the string passed as argument to a level. If the 137 conversion fails, then this method returns DEBUG. 138 * @param sArg level name. 139 */ 140 static LevelPtr toLevel(const std::basic_string<UniChar>& sArg); 141 /** 142 Convert the string passed as argument to a level. If the 143 conversion fails, then this method returns the value of 144 <code>defaultLevel</code>. 145 * @param sArg level name. 146 * @param defaultLevel level to return if no match. 147 * @return 148 */ 149 static LevelPtr toLevel(const std::basic_string<UniChar>& sArg, 150 const LevelPtr& defaultLevel); 151 /** 152 * Get the name of the level. 153 * @param name buffer to which name is appended. 154 */ 155 void toString(std::basic_string<UniChar>& name) const; 156 #endif 157 #if LOG4CXX_CFSTRING_API 158 /** 159 Convert the string passed as argument to a level. If the 160 conversion fails, then this method returns DEBUG. 161 * @param sArg level name. 162 */ 163 static LevelPtr toLevel(const CFStringRef& sArg); 164 /** 165 Convert the string passed as argument to a level. If the 166 conversion fails, then this method returns the value of 167 <code>defaultLevel</code>. 168 * @param sArg level name. 169 * @param defaultLevel level to return if no match. 170 * @return 171 */ 172 static LevelPtr toLevel(const CFStringRef& sArg, 173 const LevelPtr& defaultLevel); 174 /** 175 * Get the name of the level. 176 * @param name buffer to which name is appended. 177 */ 178 void toString(CFStringRef& name) const; 179 #endif 180 /** 181 Convert the string passed as argument to a level. If the 182 conversion fails, then this method returns DEBUG. 183 * @param sArg level name. 184 */ 185 static LevelPtr toLevelLS(const LogString& sArg); 186 /** 187 Convert the string passed as argument to a level. If the 188 conversion fails, then this method returns the value of 189 <code>defaultLevel</code>. 190 * @param sArg level name. 191 * @param defaultLevel level to return if no match. 192 * @return 193 */ 194 static LevelPtr toLevelLS(const LogString& sArg, 195 const LevelPtr& defaultLevel); 196 /** 197 Returns the string representation of this level. 198 * @return level name. 199 */ 200 LogString toString() const; 201 202 /** 203 Convert an integer passed as argument to a level. If the 204 conversion fails, then this method returns DEBUG. 205 */ 206 static LevelPtr toLevel(int val); 207 208 /** 209 Convert an integer passed as argument to a level. If the 210 conversion fails, then this method returns the specified default. 211 */ 212 static LevelPtr toLevel(int val, const LevelPtr& defaultLevel); 213 214 enum 215 { 216 OFF_INT = INT_MAX, 217 FATAL_INT = 50000, 218 ERROR_INT = 40000, 219 WARN_INT = 30000, 220 INFO_INT = 20000, 221 DEBUG_INT = 10000, 222 TRACE_INT = 5000, 223 ALL_INT = INT_MIN 224 }; 225 226 227 static LevelPtr getAll(); 228 static LevelPtr getFatal(); 229 static LevelPtr getError(); 230 static LevelPtr getWarn(); 231 static LevelPtr getInfo(); 232 static LevelPtr getDebug(); 233 static LevelPtr getTrace(); 234 static LevelPtr getOff(); 235 236 237 /** 238 Two levels are equal if their level fields are equal. 239 */ 240 virtual bool equals(const LevelPtr& level) const; 241 242 inline bool operator==(const Level& level1) const 243 { 244 return (this->level == level1.level); 245 } 246 247 inline bool operator!=(const Level& level1) const 248 { 249 return (this->level != level1.level); 250 } 251 252 /** 253 Return the syslog equivalent of this level as an integer. 254 */ getSyslogEquivalent()255 inline int getSyslogEquivalent() const 256 { 257 return syslogEquivalent; 258 } 259 260 261 /** 262 Returns <code>true</code> if this level has a higher or equal 263 level than the level passed as argument, <code>false</code> 264 otherwise. 265 266 <p>You should think twice before overriding the default 267 implementation of <code>isGreaterOrEqual</code> method. 268 269 */ 270 virtual bool isGreaterOrEqual(const LevelPtr& level) const; 271 272 273 /** 274 Returns the integer representation of this level. 275 */ toInt()276 inline int toInt() const 277 { 278 return level; 279 } 280 281 private: 282 int level; 283 LogString name; 284 int syslogEquivalent; 285 Level(const Level&); 286 Level& operator=(const Level&); 287 }; 288 289 /** 290 * We need to double some logic from LOG4CXX_PTR_DEF or else we are unable to override the 291 * comparison operator, which we need to properly fix LOGCXX-394. 292 * 293 * https://issues.apache.org/jira/browse/LOGCXX-394 294 */ 295 namespace helpers 296 { 297 298 /** @class log4cxx::helpers::ObjectPtr */ 299 template<> inline bool LevelPtr::operator==(const LevelPtr& rhs) const 300 { 301 return (*this)->equals(rhs); 302 } 303 template<> inline bool LevelPtr::operator!=(const LevelPtr& rhs) const 304 { 305 return !(*this == rhs); 306 } 307 #if defined(_MSC_VER) && !defined(LOG4CXX_STATIC) && defined(LOG4CXX) 308 template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT<Level>; 309 #elif defined(_MSC_VER) && !defined(LOG4CXX_STATIC) 310 #pragma warning(push) 311 #pragma warning(disable: 4231) 312 extern template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT<Level>; 313 #pragma warning(pop) 314 #endif 315 316 } 317 318 } 319 320 #define DECLARE_LOG4CXX_LEVEL(level)\ 321 public:\ 322 class Class##level : public Level::LevelClass\ 323 {\ 324 public:\ 325 Class##level() : Level::LevelClass() {}\ 326 virtual LogString getName() const { return LOG4CXX_STR(#level); } \ 327 virtual LevelPtr toLevel(const LogString& sArg) const\ 328 { return level::toLevelLS(sArg); }\ 329 virtual LevelPtr toLevel(int val) const\ 330 { return level::toLevel(val); }\ 331 };\ 332 DECLARE_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(level, Class##level) 333 334 #define IMPLEMENT_LOG4CXX_LEVEL(level) \ 335 IMPLEMENT_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(level, Class##level) 336 337 #if defined(_MSC_VER) 338 #pragma warning (pop) 339 #endif 340 341 #endif //_LOG4CXX_LEVEL_H 342