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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
24 using namespace ::log4cxx::spi;
25 using namespace log4cxx::helpers;
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 = "?::?";
34 const LocationInfo& LocationInfo::getLocationUnavailable() {
35 static const LocationInfo unavailable;
41 * @remarks Used by LOG4CXX_LOCATION to generate
42 * location info for current code site
44 LocationInfo::LocationInfo( const char * const fileName1,
45 const char * const methodName1,
47 : lineNumber( lineNumber1 ),
48 fileName( fileName1 ),
49 methodName( methodName1 ) {
53 * Default constructor.
55 LocationInfo::LocationInfo()
57 fileName(LocationInfo::NA),
58 methodName(LocationInfo::NA_METHOD) {
63 * @param src source location
65 LocationInfo::LocationInfo( const LocationInfo & src )
66 : lineNumber( src.lineNumber ),
67 fileName( src.fileName ),
68 methodName( src.methodName ) {
72 * Assignment operator.
73 * @param src source location
75 LocationInfo & LocationInfo::operator = ( const LocationInfo & src )
77 fileName = src.fileName;
78 methodName = src.methodName;
79 lineNumber = src.lineNumber;
84 * Resets location info to default state.
86 void LocationInfo::clear() {
88 methodName = NA_METHOD;
94 * Return the file name of the caller.
95 * @returns file name, may be null.
97 const char * LocationInfo::getFileName() const
103 * Returns the line number of the caller.
104 * @returns line number, -1 if not available.
106 int LocationInfo::getLineNumber() const
111 /** Returns the method name of the caller. */
112 const std::string LocationInfo::getMethodName() const
114 std::string tmp(methodName);
115 size_t colonPos = tmp.find("::");
116 if (colonPos != std::string::npos) {
117 tmp.erase(0, colonPos + 2);
119 size_t spacePos = tmp.find(' ');
120 if (spacePos != std::string::npos) {
121 tmp.erase(0, spacePos + 1);
124 size_t parenPos = tmp.find('(');
125 if (parenPos != std::string::npos) {
132 const std::string LocationInfo::getClassName() const {
133 std::string tmp(methodName);
134 size_t colonPos = tmp.find("::");
135 if (colonPos != std::string::npos) {
137 size_t spacePos = tmp.find_last_of(' ');
138 if (spacePos != std::string::npos) {
139 tmp.erase(0, spacePos + 1);
143 tmp.erase(0, tmp.length() );
147 void LocationInfo::write(ObjectOutputStream& os, Pool& p) const {
148 if (lineNumber == -1 && fileName == NA && methodName == NA_METHOD) {
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,
160 0x74, 0x00, 0x12, 0x4C, 0x6A,
161 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67,
162 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
164 os.writeProlog("org.apache.log4j.spi.LocationInfo", 2, (char *)prolog, sizeof(prolog), p);
165 char* line = p.itoa(lineNumber);
167 // construct Java-like fullInfo (replace "::" with ".")
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);
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, ".");
183 fullInfo.insert(0, ".");
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);