/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "apr_pools.h" #include "apr_strings.h" using namespace ::log4cxx::spi; using namespace log4cxx::helpers; /** When location information is not available the constant NA is returned. Current value of this string constant is ?. */ const char* const LocationInfo::NA = "?"; const char* const LocationInfo::NA_METHOD = "?::?"; const LocationInfo& LocationInfo::getLocationUnavailable() { static const LocationInfo unavailable; return unavailable; } /** * Constructor. * @remarks Used by LOG4CXX_LOCATION to generate * location info for current code site */ LocationInfo::LocationInfo( const char * const fileName1, const char * const methodName1, int lineNumber1 ) : lineNumber( lineNumber1 ), fileName( fileName1 ), methodName( methodName1 ) { } /** * Default constructor. */ LocationInfo::LocationInfo() : lineNumber( -1 ), fileName(LocationInfo::NA), methodName(LocationInfo::NA_METHOD) { } /** * Copy constructor. * @param src source location */ LocationInfo::LocationInfo( const LocationInfo & src ) : lineNumber( src.lineNumber ), fileName( src.fileName ), methodName( src.methodName ) { } /** * Assignment operator. * @param src source location */ LocationInfo & LocationInfo::operator = ( const LocationInfo & src ) { fileName = src.fileName; methodName = src.methodName; lineNumber = src.lineNumber; return * this; } /** * Resets location info to default state. */ void LocationInfo::clear() { fileName = NA; methodName = NA_METHOD; lineNumber = -1; } /** * Return the file name of the caller. * @returns file name, may be null. */ const char * LocationInfo::getFileName() const { return fileName; } /** * Returns the line number of the caller. * @returns line number, -1 if not available. */ int LocationInfo::getLineNumber() const { return lineNumber; } /** Returns the method name of the caller. */ const std::string LocationInfo::getMethodName() const { std::string tmp(methodName); size_t parenPos = tmp.find('('); if (parenPos != std::string::npos) { tmp.erase(parenPos); } size_t colonPos = tmp.rfind("::"); if (colonPos != std::string::npos) { tmp.erase(0, colonPos + 2); } else { size_t spacePos = tmp.find(' '); if (spacePos != std::string::npos) { tmp.erase(0, spacePos + 1); } } return tmp; } const std::string LocationInfo::getClassName() const { std::string tmp(methodName); size_t parenPos = tmp.find('('); if (parenPos != std::string::npos) { tmp.erase(parenPos); } size_t colonPos = tmp.rfind("::"); if (colonPos != std::string::npos) { tmp.erase(colonPos); size_t spacePos = tmp.find_last_of(' '); if (spacePos != std::string::npos) { tmp.erase(0, spacePos + 1); } return tmp; } tmp.erase(0, tmp.length() ); return tmp; } void LocationInfo::write(ObjectOutputStream& os, Pool& p) const { if (lineNumber == -1 && fileName == NA && methodName == NA_METHOD) { os.writeNull(p); } else { unsigned char prolog[] = { 0x72, 0x00, 0x21, 0x6F, 0x72, 0x67, 0x2E, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2E, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 0x2E, 0x73, 0x70, 0x69, 0x2E, 0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0xED, 0x99, 0xBB, 0xE1, 0x4A, 0x91, 0xA5, 0x7C, 0x02, 0x00, 0x01, 0x4C, 0x00, 0x08, 0x66, 0x75, 0x6C, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x74, 0x00, 0x12, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x78, 0x70 }; os.writeProlog("org.apache.log4j.spi.LocationInfo", 2, (char*) prolog, sizeof(prolog), p); char* line = p.itoa(lineNumber); // // construct Java-like fullInfo (replace "::" with ".") // std::string fullInfo(methodName); size_t openParen = fullInfo.find('('); if (openParen != std::string::npos) { size_t space = fullInfo.find(' '); if (space != std::string::npos && space < openParen) { fullInfo.erase(0, space + 1); } } openParen = fullInfo.find('('); if (openParen != std::string::npos) { size_t classSep = fullInfo.rfind("::", openParen); if (classSep != std::string::npos) { fullInfo.replace(classSep, 2, "."); } else { fullInfo.insert(0, "."); } } fullInfo.append(1, '('); fullInfo.append(fileName); fullInfo.append(1, ':'); fullInfo.append(line); fullInfo.append(1, ')'); os.writeUTFString(fullInfo, p); } }