Fix build error with GCC6
[profile/ivi/log4cxx.git] / src / main / cpp / locationinfo.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/location/locationinfo.h>
19 #include <log4cxx/helpers/objectoutputstream.h>
20 #include <log4cxx/helpers/pool.h>
21 #include "apr_pools.h"
22 #include "apr_strings.h"
23
24 using namespace ::log4cxx::spi;
25 using namespace log4cxx::helpers;
26
27    /**
28      When location information is not available the constant
29      <code>NA</code> is returned. Current value of this string
30      constant is <b>?</b>.  */
31  const char* const LocationInfo::NA = "?";
32  const char* const LocationInfo::NA_METHOD = "?::?";
33
34  const LocationInfo& LocationInfo::getLocationUnavailable() {
35    static const LocationInfo unavailable;
36    return unavailable;
37  }
38
39 /**
40 *   Constructor.
41 *   @remarks Used by LOG4CXX_LOCATION to generate
42 *       location info for current code site
43 */
44  LocationInfo::LocationInfo( const char * const fileName1,
45               const char * const methodName1,
46               int lineNumber1 )
47      :  lineNumber( lineNumber1 ),
48         fileName( fileName1 ),
49         methodName( methodName1 ) {
50 }
51
52 /**
53 *   Default constructor.
54 */
55  LocationInfo::LocationInfo()
56    : lineNumber( -1 ),
57      fileName(LocationInfo::NA),
58      methodName(LocationInfo::NA_METHOD) {
59 }
60
61 /**
62 *   Copy constructor.
63 *   @param src source location
64 */
65  LocationInfo::LocationInfo( const LocationInfo & src )
66      :  lineNumber( src.lineNumber ),
67         fileName( src.fileName ),
68         methodName( src.methodName ) {
69 }
70
71 /**
72 *  Assignment operator.
73 * @param src source location
74 */
75  LocationInfo & LocationInfo::operator = ( const LocationInfo & src )
76 {
77   fileName = src.fileName;
78   methodName = src.methodName;
79   lineNumber = src.lineNumber;
80   return * this;
81 }
82
83 /**
84  *   Resets location info to default state.
85  */
86  void LocationInfo::clear() {
87   fileName = NA;
88   methodName = NA_METHOD;
89   lineNumber = -1;
90 }
91
92
93 /**
94  *   Return the file name of the caller.
95  *   @returns file name, may be null.
96  */
97  const char * LocationInfo::getFileName() const
98 {
99   return fileName;
100 }
101
102 /**
103   *   Returns the line number of the caller.
104   * @returns line number, -1 if not available.
105   */
106  int LocationInfo::getLineNumber() const
107 {
108   return lineNumber;
109 }
110
111 /** Returns the method name of the caller. */
112  const std::string LocationInfo::getMethodName() const
113 {
114     std::string tmp(methodName);
115     size_t colonPos = tmp.find("::");
116     if (colonPos != std::string::npos) {
117       tmp.erase(0, colonPos + 2);
118     } else {
119       size_t spacePos = tmp.find(' ');
120       if (spacePos != std::string::npos) {
121         tmp.erase(0, spacePos + 1);
122       }
123     }
124     size_t parenPos = tmp.find('(');
125     if (parenPos != std::string::npos) {
126       tmp.erase(parenPos);
127     }
128     return tmp;
129 }
130
131
132 const std::string LocationInfo::getClassName() const {
133         std::string tmp(methodName);
134         size_t colonPos = tmp.find("::");
135         if (colonPos != std::string::npos) {
136            tmp.erase(colonPos);
137            size_t spacePos = tmp.find_last_of(' ');
138            if (spacePos != std::string::npos) {
139                tmp.erase(0, spacePos + 1);
140            }
141            return tmp;
142         }
143         tmp.erase(0, tmp.length() );
144         return tmp;
145 }
146
147 void LocationInfo::write(ObjectOutputStream& os, Pool& p) const {
148     if (lineNumber == -1 && fileName == NA && methodName == NA_METHOD) {
149          os.writeNull(p);
150     } else {
151         unsigned char prolog[] = {
152          0x72, 0x00, 0x21, 0x6F, 0x72, 0x67, 0x2E, 
153          0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2E, 0x6C, 
154          0x6F, 0x67, 0x34, 0x6A, 0x2E, 0x73, 0x70, 0x69, 
155          0x2E, 0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 
156          0x6E, 0x49, 0x6E, 0x66, 0x6F, 0xED, 0x99, 0xBB, 
157          0xE1, 0x4A, 0x91, 0xA5, 0x7C, 0x02, 0x00, 0x01, 
158          0x4C, 0x00, 0x08, 0x66, 0x75, 0x6C, 0x6C, 0x49, 
159          0x6E, 0x66, 0x6F, 
160             0x74, 0x00, 0x12, 0x4C, 0x6A, 
161                 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
162                 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
163          0x78, 0x70 };
164       os.writeProlog("org.apache.log4j.spi.LocationInfo", 2, (char *)prolog, sizeof(prolog), p);
165         char* line = p.itoa(lineNumber);
166         //
167         //   construct Java-like fullInfo (replace "::" with ".")
168         //
169         std::string fullInfo(methodName);
170         size_t openParen = fullInfo.find('(');
171         if (openParen != std::string::npos) {
172             size_t space = fullInfo.find(' ');
173             if (space != std::string::npos && space < openParen) {
174                 fullInfo.erase(0, space + 1);
175             }
176         }
177         openParen = fullInfo.find('(');
178         if (openParen != std::string::npos) {
179             size_t classSep = fullInfo.rfind("::", openParen);
180             if (classSep != std::string::npos) {
181                 fullInfo.replace(classSep, 2, ".");
182             } else {
183                 fullInfo.insert(0, ".");
184             }
185         }
186         fullInfo.append(1, '(');
187         fullInfo.append(fileName);
188         fullInfo.append(1, ':');
189         fullInfo.append(line);
190         fullInfo.append(1, ')');
191         os.writeUTFString(fullInfo, p);
192     }
193 }
194
195