1 // Module:  Log4CPLUS
2 // File:    loglevel.cxx
3 // Created: 6/2001
4 // Author:  Tad E. Smith
5 //
6 //
7 // Copyright 2001-2010 Tad E. Smith
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 //
13 //     http://www.apache.org/licenses/LICENSE-2.0
14 //
15 // Unless required by applicable law or agreed to in writing, software
16 // distributed under the License is distributed on an "AS IS" BASIS,
17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 // See the License for the specific language governing permissions and
19 // limitations under the License.
20 
21 #include "dcmtk/oflog/loglevel.h"
22 #include "dcmtk/oflog/helpers/loglog.h"
23 #include "dcmtk/oflog/helpers/strhelp.h"
24 #include "dcmtk/oflog/internal/internal.h"
25 #include <algorithm>
26 
27 
28 namespace dcmtk
29 {
30 namespace log4cplus
31 {
32 
33 
34 namespace
35 {
36 
37 static tstring const ALL_STRING (DCMTK_LOG4CPLUS_TEXT("ALL"));
38 static tstring const TRACE_STRING (DCMTK_LOG4CPLUS_TEXT("TRACE"));
39 static tstring const DEBUG_STRING (DCMTK_LOG4CPLUS_TEXT("DEBUG"));
40 static tstring const INFO_STRING (DCMTK_LOG4CPLUS_TEXT("INFO"));
41 static tstring const WARN_STRING (DCMTK_LOG4CPLUS_TEXT("WARN"));
42 static tstring const ERROR_STRING (DCMTK_LOG4CPLUS_TEXT("ERROR"));
43 static tstring const FATAL_STRING (DCMTK_LOG4CPLUS_TEXT("FATAL"));
44 static tstring const OFF_STRING (DCMTK_LOG4CPLUS_TEXT("OFF"));
45 static tstring const NOTSET_STRING (DCMTK_LOG4CPLUS_TEXT("NOTSET"));
46 static tstring const UNKNOWN_STRING (DCMTK_LOG4CPLUS_TEXT("UNKNOWN"));
47 
48 
49 struct log_levels_table_rec
50 {
51     LogLevel ll;
52     tstring const * str;
53 };
54 
55 
56 #define DEF_LLTAB_REC(x) { x ## _LOG_LEVEL, &(x ## _STRING) }
57 
58 static log_levels_table_rec const log_levels_table[8] = {
59     DEF_LLTAB_REC (OFF),
60     DEF_LLTAB_REC (FATAL),
61     DEF_LLTAB_REC (ERROR),
62     DEF_LLTAB_REC (WARN),
63     DEF_LLTAB_REC (INFO),
64     DEF_LLTAB_REC (DEBUG),
65     DEF_LLTAB_REC (TRACE),
66     DEF_LLTAB_REC (ALL),
67 };
68 
69 #undef DEF_LLTAB_REC
70 
71 
72 static
73 tstring const &
defaultLogLevelToStringMethod(LogLevel ll)74 defaultLogLevelToStringMethod(LogLevel ll)
75 {
76     switch(ll) {
77         case OFF_LOG_LEVEL:     return OFF_STRING;
78         case FATAL_LOG_LEVEL:   return FATAL_STRING;
79         case ERROR_LOG_LEVEL:   return ERROR_STRING;
80         case WARN_LOG_LEVEL:    return WARN_STRING;
81         case INFO_LOG_LEVEL:    return INFO_STRING;
82         case DEBUG_LOG_LEVEL:   return DEBUG_STRING;
83         case TRACE_LOG_LEVEL:   return TRACE_STRING;
84         //case ALL_LOG_LEVEL:     return ALL_STRING;
85         case NOT_SET_LOG_LEVEL: return NOTSET_STRING;
86     };
87 
88     return internal::empty_str;
89 }
90 
91 
92 static
93 LogLevel
defaultStringToLogLevelMethod(const tstring & s)94 defaultStringToLogLevelMethod(const tstring& s)
95 {
96     size_t const tbl_size
97         = sizeof (log_levels_table) / sizeof (log_levels_table[0]);
98 
99     for (log_levels_table_rec const * it = log_levels_table;
100         it != log_levels_table + tbl_size; ++it)
101     {
102         if (*it->str == s)
103             return it->ll;
104     }
105 
106     return NOT_SET_LOG_LEVEL;
107 }
108 
109 } // namespace
110 
111 
112 
113 //////////////////////////////////////////////////////////////////////////////
114 // LogLevelManager ctors and dtor
115 //////////////////////////////////////////////////////////////////////////////
116 
LogLevelManager()117 LogLevelManager::LogLevelManager()
118     : toStringMethods(),
119       fromStringMethods()
120 {
121     LogLevelToStringMethodRec rec;
122     rec.func = defaultLogLevelToStringMethod;
123     rec.use_1_0 = false;
124     toStringMethods.push_back (rec);
125 
126     fromStringMethods.push_back (&defaultStringToLogLevelMethod);
127 }
128 
129 
~LogLevelManager()130 LogLevelManager::~LogLevelManager()
131 { }
132 
133 
134 
135 //////////////////////////////////////////////////////////////////////////////
136 // LogLevelManager public methods
137 //////////////////////////////////////////////////////////////////////////////
138 
139 tstring const &
toString(LogLevel ll) const140 LogLevelManager::toString(LogLevel ll) const
141 {
142     tstring const * ret;
143     for (LogLevelToStringMethodList::const_iterator it
144         = toStringMethods.begin (); it != toStringMethods.end (); ++it)
145     {
146         LogLevelToStringMethodRec const & rec = *it;
147         if (rec.use_1_0)
148         {
149             // Use TLS to store the result to allow us to return
150             // a reference.
151             tstring & ll_str = internal::get_ptd ()->ll_str;
152             rec.func_1_0 (ll).swap (ll_str);
153             ret = &ll_str;
154         }
155         else
156             ret = &rec.func (ll);
157 
158         if (! ret->empty ())
159             return *ret;
160     }
161 
162     return UNKNOWN_STRING;
163 }
164 
165 
166 LogLevel
fromString(const tstring & arg) const167 LogLevelManager::fromString(const tstring& arg) const
168 {
169     tstring s = helpers::toUpper(arg);
170 
171     for (StringToLogLevelMethodList::const_iterator it
172         = fromStringMethods.begin (); it != fromStringMethods.end (); ++it)
173     {
174         LogLevel ret = (*it) (s);
175         if (ret != NOT_SET_LOG_LEVEL)
176             return ret;
177     }
178 
179     return NOT_SET_LOG_LEVEL;
180 }
181 
182 
183 void
pushToStringMethod(LogLevelToStringMethod newToString)184 LogLevelManager::pushToStringMethod(LogLevelToStringMethod newToString)
185 {
186     LogLevelToStringMethodRec rec;
187     rec.func = newToString;
188     rec.use_1_0 = false;
189     toStringMethods.push_back (rec);
190 }
191 
192 
193 void
pushToStringMethod(LogLevelToStringMethod_1_0 newToString)194 LogLevelManager::pushToStringMethod(LogLevelToStringMethod_1_0 newToString)
195 {
196     LogLevelToStringMethodRec rec;
197     rec.func_1_0 = newToString;
198     rec.use_1_0 = true;
199     toStringMethods.push_back (rec);
200 }
201 
202 
203 void
pushFromStringMethod(StringToLogLevelMethod newFromString)204 LogLevelManager::pushFromStringMethod(StringToLogLevelMethod newFromString)
205 {
206     fromStringMethods.push_back (newFromString);
207 }
208 
209 
210 } // namespace log4cplus
211 } // end namespace dcmtk
212