Fix build error with GCC6
[profile/ivi/log4cxx.git] / src / main / cpp / loggingevent.cpp
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 #include <log4cxx/spi/loggingevent.h>
19 #include <log4cxx/ndc.h>
20
21 #include <log4cxx/level.h>
22 #include <log4cxx/helpers/loglog.h>
23 #include <log4cxx/helpers/system.h>
24 #include <log4cxx/helpers/socket.h>
25 #if !defined(LOG4CXX)
26 #define LOG4CXX 1
27 #endif
28 #include <log4cxx/helpers/aprinitializer.h>
29 #include <log4cxx/helpers/threadspecificdata.h>
30 #include <log4cxx/helpers/transcoder.h>
31
32 #include <apr_time.h>
33 #include <apr_portable.h>
34 #include <apr_strings.h>
35 #include <log4cxx/helpers/stringhelper.h>
36 #include <log4cxx/helpers/objectoutputstream.h>
37 #include <log4cxx/helpers/bytebuffer.h>
38 #include <log4cxx/logger.h>
39 #include <log4cxx/private/log4cxx_private.h>
40
41 using namespace log4cxx;
42 using namespace log4cxx::spi;
43 using namespace log4cxx::helpers;
44
45 IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
46
47
48 //
49 //   Accessor for start time.
50 //
51 log4cxx_time_t LoggingEvent::getStartTime() {
52   return log4cxx::helpers::APRInitializer::initialize();
53 }
54
55 LoggingEvent::LoggingEvent() :
56    ndc(0),
57    mdcCopy(0),
58    properties(0),
59    ndcLookupRequired(true),
60    mdcCopyLookupRequired(true),
61    timeStamp(0),
62    locationInfo() {
63 }
64
65 LoggingEvent::LoggingEvent(
66         const LogString& logger1, const LevelPtr& level1,
67         const LogString& message1, const LocationInfo& locationInfo1) :
68    logger(logger1),
69    level(level1),
70    ndc(0),
71    mdcCopy(0),
72    properties(0),
73    ndcLookupRequired(true),
74    mdcCopyLookupRequired(true),
75    message(message1),
76    timeStamp(apr_time_now()),
77    locationInfo(locationInfo1),
78    threadName(getCurrentThreadName()) {
79 }
80
81 LoggingEvent::~LoggingEvent()
82 {
83         delete ndc;
84         delete mdcCopy;
85         delete properties;
86 }
87
88 bool LoggingEvent::getNDC(LogString& dest) const
89 {
90         if(ndcLookupRequired)
91         {
92                 ndcLookupRequired = false;
93                 LogString val;
94                 if(NDC::get(val)) {
95                      ndc = new LogString(val);
96                 }
97         }
98         if (ndc) {
99             dest.append(*ndc);
100             return true;
101         }
102         return false;
103 }
104
105 bool LoggingEvent::getMDC(const LogString& key, LogString& dest) const
106 {
107    // Note the mdcCopy is used if it exists. Otherwise we use the MDC
108     // that is associated with the thread.
109     if (mdcCopy != 0 && !mdcCopy->empty())
110         {
111                 MDC::Map::const_iterator it = mdcCopy->find(key);
112
113                 if (it != mdcCopy->end())
114                 {
115                         if (!it->second.empty())
116                         {
117                                 dest.append(it->second);
118                                 return true;
119                         }
120                 }
121     }
122
123     return MDC::get(key, dest);
124
125 }
126
127 LoggingEvent::KeySet LoggingEvent::getMDCKeySet() const
128 {
129         LoggingEvent::KeySet set;
130
131         if (mdcCopy != 0 && !mdcCopy->empty())
132         {
133                 MDC::Map::const_iterator it;
134                 for (it = mdcCopy->begin(); it != mdcCopy->end(); it++)
135                 {
136                         set.push_back(it->first);
137
138                 }
139         }
140         else
141         {
142                 ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
143                 if (data != 0) {
144                     MDC::Map& m = data->getMap();
145
146                     for(MDC::Map::const_iterator it = m.begin(); it != m.end(); it++) {
147                         set.push_back(it->first);
148                     }
149                 }
150         }
151
152         return set;
153 }
154
155 void LoggingEvent::getMDCCopy() const
156 {
157         if(mdcCopyLookupRequired)
158         {
159                 mdcCopyLookupRequired = false;
160                 // the clone call is required for asynchronous logging.
161                 ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
162                 if (data != 0) {
163                     mdcCopy = new MDC::Map(data->getMap());
164                 } else {
165                     mdcCopy = new MDC::Map();
166                 }
167        }
168 }
169
170 bool LoggingEvent::getProperty(const LogString& key, LogString& dest) const
171 {
172         if (properties == 0)
173         {
174                 return false;
175         }
176
177         std::map<LogString, LogString>::const_iterator  it = properties->find(key);
178
179         if (it != properties->end())
180         {
181                 dest.append(it->second);
182                 return true;
183         }
184
185         return false;
186 }
187
188 LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() const
189 {
190         LoggingEvent::KeySet set;
191
192         if (properties != 0)
193         {
194                 std::map<LogString, LogString>::const_iterator it;
195                 for (it = properties->begin(); it != properties->end(); it++)
196                 {
197                         set.push_back(it->first);
198                 }
199         }
200
201         return set;
202 }
203
204
205 const LogString LoggingEvent::getCurrentThreadName() {
206 #if APR_HAS_THREADS
207 #if defined(_WIN32)
208    char result[20];
209    DWORD threadId = GetCurrentThreadId();
210    apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC, threadId);
211 #else
212    // apr_os_thread_t encoded in HEX takes needs as many characters
213    // as two times the size of the type, plus an additional null byte.
214    char result[sizeof(apr_os_thread_t) * 3 + 10];
215    apr_os_thread_t threadId = apr_os_thread_current();
216    apr_snprintf(result, sizeof(result), LOG4CXX_APR_THREAD_FMTSPEC, (void*) &threadId);
217 #endif
218    LOG4CXX_DECODE_CHAR(str, (const char*) result);
219    return str;
220 #else
221    return LOG4CXX_STR("0x00000000");
222 #endif
223 }
224
225
226 void LoggingEvent::setProperty(const LogString& key, const LogString& value)
227 {
228         if (properties == 0)
229         {
230                 properties = new std::map<LogString, LogString>;
231         }
232
233         (*properties)[key] = value;
234 }
235
236
237
238 void LoggingEvent::writeProlog(ObjectOutputStream& os, Pool& p)  {
239      unsigned char classDesc[] = {
240         0x72, 0x00, 0x21, 
241         0x6F, 0x72, 0x67, 0x2E, 0x61, 0x70, 0x61, 0x63, 
242         0x68, 0x65, 0x2E, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 
243         0x2E, 0x73, 0x70, 0x69, 0x2E, 0x4C, 0x6F, 0x67, 
244         0x67, 0x69, 0x6E, 0x67, 0x45, 0x76, 0x65, 0x6E, 
245         0x74, 0xF3, 0xF2, 0xB9, 0x23, 0x74, 0x0B, 0xB5, 
246         0x3F, 0x03, 0x00, 0x0A, 0x5A, 0x00, 0x15, 0x6D, 
247         0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x4C, 0x6F, 
248         0x6F, 0x6B, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 
249         0x69, 0x72, 0x65, 0x64, 0x5A, 0x00, 0x11, 0x6E, 
250         0x64, 0x63, 0x4C, 0x6F, 0x6F, 0x6B, 0x75, 0x70, 
251         0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 
252         0x4A, 0x00, 0x09, 0x74, 0x69, 0x6D, 0x65, 0x53, 
253         0x74, 0x61, 0x6D, 0x70, 0x4C, 0x00, 0x0C, 0x63, 
254         0x61, 0x74, 0x65, 0x67, 0x6F, 0x72, 0x79, 0x4E, 
255         0x61, 0x6D, 0x65, 0x74, 0x00, 0x12, 0x4C, 0x6A, 
256         0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
257         0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 
258         0x4C, 0x00, 0x0C, 0x6C, 0x6F, 0x63, 0x61, 0x74, 
259         0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x74, 
260         0x00, 0x23, 0x4C, 0x6F, 0x72, 0x67, 0x2F, 0x61, 
261         0x70, 0x61, 0x63, 0x68, 0x65, 0x2F, 0x6C, 0x6F, 
262         0x67, 0x34, 0x6A, 0x2F, 0x73, 0x70, 0x69, 0x2F, 
263         0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 
264         0x49, 0x6E, 0x66, 0x6F, 0x3B, 0x4C, 0x00, 0x07, 
265         0x6D, 0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x74, 
266         0x00, 0x15, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 
267         0x75, 0x74, 0x69, 0x6C, 0x2F, 0x48, 0x61, 0x73, 
268         0x68, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x3B, 0x4C, 
269         0x00, 0x03, 0x6E, 0x64, 0x63, 
270         0x74, 0x00, 0x12, 0x4C, 0x6A, 
271         0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
272         0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
273         0x4C, 0x00, 0x0F, 0x72, 0x65, 0x6E, 
274         0x64, 0x65, 0x72, 0x65, 0x64, 0x4D, 0x65, 0x73, 
275         0x73, 0x61, 0x67, 0x65, 
276         0x74, 0x00, 0x12, 0x4C, 0x6A, 
277         0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
278         0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
279         0x4C, 0x00, 0x0A, 0x74, 0x68, 0x72, 0x65, 
280         0x61, 0x64, 0x4E, 0x61, 0x6D, 0x65, 
281         0x74, 0x00, 0x12, 0x4C, 0x6A, 
282         0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
283         0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
284         0x4C, 0x00, 0x0D, 0x74, 0x68, 
285         0x72, 0x6F, 0x77, 0x61, 0x62, 0x6C, 0x65, 0x49, 
286         0x6E, 0x66, 0x6F, 0x74, 0x00, 0x2B, 0x4C, 0x6F, 
287         0x72, 0x67, 0x2F, 0x61, 0x70, 0x61, 0x63, 0x68, 
288         0x65, 0x2F, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 0x2F, 
289         0x73, 0x70, 0x69, 0x2F, 0x54, 0x68, 0x72, 0x6F, 
290         0x77, 0x61, 0x62, 0x6C, 0x65, 0x49, 0x6E, 0x66, 
291         0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 
292         0x3B, 0x78, 0x70 }; 
293
294      os.writeProlog("org.apache.log4j.spi.LoggingEvent", 
295         8, (char *) classDesc, sizeof(classDesc), p);
296 }
297
298 void LoggingEvent::write(helpers::ObjectOutputStream& os, Pool& p) const {
299       writeProlog(os, p);
300       // mdc and ndc lookup required should always be false
301       char lookupsRequired[] = { 0, 0 };
302       os.writeBytes(lookupsRequired, sizeof(lookupsRequired), p);
303       os.writeLong(timeStamp/1000, p);
304       os.writeObject(logger, p);
305       locationInfo.write(os, p);
306       if (mdcCopy == 0 || mdcCopy->size() == 0) {
307           os.writeNull(p);
308       } else {
309           os.writeObject(*mdcCopy, p);
310       }
311       if (ndc == 0) {
312           os.writeNull(p);
313       } else {
314           os.writeObject(*ndc, p);
315       }
316       os.writeObject(message, p);
317       os.writeObject(threadName, p);
318       //  throwable
319       os.writeNull(p);
320       os.writeByte(ObjectOutputStream::TC_BLOCKDATA, p);
321       os.writeByte(0x04, p);
322       os.writeInt(level->toInt(), p);
323       os.writeNull(p);
324       os.writeByte(ObjectOutputStream::TC_ENDBLOCKDATA, p);
325 }
326