| /* |
| * 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 <log4cxx/logstring.h> |
| #include <log4cxx/stream.h> |
| #include <log4cxx/helpers/transcoder.h> |
| #if !defined(LOG4CXX) |
| #define LOG4CXX 1 |
| #endif |
| #include <log4cxx/private/log4cxx_private.h> |
| |
| using namespace log4cxx; |
| |
| logstream_base::logstream_ios_base::logstream_ios_base(std::ios_base::fmtflags initval, |
| int initsize) |
| { |
| #if LOG4CXX_MEMSET_IOS_BASE |
| // |
| // the destructor for std::ios_base in the MSVC STL |
| // releases a pointer that was not initialized in the constructor. |
| // |
| memset(this, 0, sizeof(*this)); |
| #endif |
| #if LOG4CXX_INIT_IOS_BASE |
| init(NULL); |
| #endif |
| flags(initval); |
| precision(initsize); |
| width(initsize); |
| |
| } |
| |
| |
| logstream_base::logstream_base(const LoggerPtr& log, |
| const LevelPtr& lvl) : initset((std::ios_base::fmtflags) - 1, 1), |
| initclear((std::ios_base::fmtflags) 0, 0), fillchar(0), fillset(false), logger(log), level(lvl), location() |
| { |
| enabled = logger->isEnabledFor(level); |
| } |
| |
| logstream_base::~logstream_base() |
| { |
| } |
| |
| void logstream_base::insert(std::ios_base & (*manip)(std::ios_base&)) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| (*manip)(initset); |
| (*manip)(initclear); |
| refresh_stream_state(); |
| } |
| |
| bool logstream_base::set_stream_state(std::ios_base& dest, int& dstchar) |
| { |
| std::ios_base::fmtflags setval = initset.flags(); |
| std::ios_base::fmtflags clrval = initclear.flags(); |
| std::ios_base::fmtflags mask = setval ^ (~clrval); |
| dest.setf(clrval, mask); |
| |
| if (initset.precision() == initclear.precision()) |
| { |
| dest.precision(initset.precision()); |
| } |
| |
| if (initset.width() == initclear.width()) |
| { |
| dest.width(initset.width()); |
| } |
| |
| dstchar = fillchar; |
| return fillset; |
| } |
| |
| logstream_base& logstream_base::endmsg(logstream_base& stream) |
| { |
| stream.end_message(); |
| return stream; |
| } |
| |
| logstream_base& logstream_base::nop(logstream_base& stream) |
| { |
| return stream; |
| } |
| |
| void logstream_base::end_message() |
| { |
| if (isEnabled()) |
| { |
| log(logger, level, location); |
| } |
| |
| erase(); |
| } |
| |
| |
| |
| int log4cxx::logstream_base::precision(int p) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| initset.precision(p); |
| int oldVal = (int)initclear.precision(p); |
| refresh_stream_state(); |
| return oldVal; |
| } |
| |
| int log4cxx::logstream_base::precision() |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| return (int)initclear.precision(); |
| } |
| |
| int log4cxx::logstream_base::width(int w) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| initset.width(w); |
| int oldVal = (int)initclear.width(w); |
| refresh_stream_state(); |
| return oldVal; |
| } |
| |
| int log4cxx::logstream_base::width() |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| return (int)initclear.width(); |
| } |
| |
| int log4cxx::logstream_base::fill(int newfill) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| int oldfill = fillchar; |
| fillchar = newfill; |
| fillset = true; |
| refresh_stream_state(); |
| return oldfill; |
| } |
| |
| int logstream_base::fill() |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| return fillchar; |
| } |
| |
| std::ios_base::fmtflags logstream_base::flags(std::ios_base::fmtflags newflags) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| initset.flags(newflags); |
| std::ios_base::fmtflags oldVal = initclear.flags(newflags); |
| refresh_stream_state(); |
| return oldVal; |
| } |
| |
| std::ios_base::fmtflags logstream_base::setf(std::ios_base::fmtflags newflags, std::ios_base::fmtflags mask) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| initset.setf(newflags, mask); |
| std::ios_base::fmtflags oldVal = initclear.setf(newflags, mask); |
| refresh_stream_state(); |
| return oldVal; |
| } |
| |
| std::ios_base::fmtflags logstream_base::setf(std::ios_base::fmtflags newflags) |
| { |
| get_stream_state(initclear, initset, fillchar, fillset); |
| initset.setf(newflags); |
| std::ios_base::fmtflags oldVal = initclear.setf(newflags); |
| refresh_stream_state(); |
| return oldVal; |
| } |
| |
| |
| |
| void logstream_base::setLevel(const ::log4cxx::LevelPtr& newlevel) |
| { |
| level = newlevel; |
| bool oldLevel = enabled; |
| enabled = logger->isEnabledFor(level); |
| |
| if (oldLevel != enabled) |
| { |
| erase(); |
| } |
| } |
| |
| bool logstream_base::isEnabledFor(const ::log4cxx::LevelPtr& l) const |
| { |
| return logger->isEnabledFor(l); |
| } |
| |
| |
| void logstream_base::setLocation(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| if (LOG4CXX_UNLIKELY(enabled)) |
| { |
| location = newlocation; |
| } |
| } |
| |
| |
| logstream::logstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0) |
| { |
| } |
| |
| logstream::logstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level) |
| : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| |
| logstream::logstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| logstream::~logstream() |
| { |
| delete stream; |
| } |
| |
| logstream& logstream::operator<<(logstream_base & (*manip)(logstream_base&)) |
| { |
| (*manip)(*this); |
| return *this; |
| } |
| |
| logstream& logstream::operator<<(const LevelPtr& l) |
| { |
| setLevel(l); |
| return *this; |
| } |
| |
| logstream& logstream::operator<<(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| logstream& logstream::operator>>(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| logstream& logstream::operator<<(std::ios_base & (*manip)(std::ios_base&)) |
| { |
| logstream_base::insert(manip); |
| return *this; |
| } |
| |
| logstream::operator std::basic_ostream<char>& () |
| { |
| if (stream == 0) |
| { |
| stream = new std::basic_stringstream<Ch>(); |
| refresh_stream_state(); |
| } |
| |
| return *stream; |
| } |
| |
| void logstream::log(LoggerPtr& log, |
| const LevelPtr& lev, |
| const log4cxx::spi::LocationInfo& loc) |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> msg = stream->str(); |
| |
| if (!msg.empty()) |
| { |
| log->log(lev, msg, loc); |
| } |
| } |
| } |
| |
| |
| void logstream::erase() |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> emptyStr; |
| stream->str(emptyStr); |
| } |
| } |
| |
| |
| void logstream::get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const |
| { |
| if (stream != 0) |
| { |
| std::ios_base::fmtflags flags = stream->flags(); |
| base.flags(flags); |
| mask.flags(flags); |
| int width = (int)stream->width(); |
| base.width(width); |
| mask.width(width); |
| int precision = (int)stream->precision(); |
| base.precision(precision); |
| mask.precision(precision); |
| fill = stream->fill(); |
| fillSet = true; |
| } |
| } |
| |
| void logstream::refresh_stream_state() |
| { |
| if (stream != 0) |
| { |
| int ch; |
| |
| if (logstream_base::set_stream_state(*stream, ch)) |
| { |
| stream->fill(ch); |
| } |
| } |
| } |
| |
| |
| #if LOG4CXX_WCHAR_T_API |
| |
| wlogstream::wlogstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0) |
| { |
| } |
| |
| wlogstream::wlogstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level) |
| : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| |
| wlogstream::wlogstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| wlogstream::~wlogstream() |
| { |
| delete stream; |
| } |
| |
| wlogstream& wlogstream::operator<<(logstream_base & (*manip)(logstream_base&)) |
| { |
| (*manip)(*this); |
| return *this; |
| } |
| |
| wlogstream& wlogstream::operator<<(const LevelPtr& l) |
| { |
| setLevel(l); |
| return *this; |
| } |
| |
| wlogstream& wlogstream::operator<<(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| wlogstream& wlogstream::operator>>(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| |
| |
| |
| wlogstream& wlogstream::operator<<(std::ios_base & (*manip)(std::ios_base&)) |
| { |
| logstream_base::insert(manip); |
| return *this; |
| } |
| |
| wlogstream::operator std::basic_ostream<wchar_t>& () |
| { |
| if (stream == 0) |
| { |
| stream = new std::basic_stringstream<Ch>(); |
| refresh_stream_state(); |
| } |
| |
| return *stream; |
| } |
| |
| void wlogstream::log(LoggerPtr& log, |
| const LevelPtr& lev, |
| const log4cxx::spi::LocationInfo& loc) |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> msg = stream->str(); |
| |
| if (!msg.empty()) |
| { |
| log->log(lev, msg, loc); |
| } |
| } |
| } |
| |
| |
| void wlogstream::erase() |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> emptyStr; |
| stream->str(emptyStr); |
| } |
| } |
| |
| |
| void wlogstream::get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const |
| { |
| if (stream != 0) |
| { |
| std::ios_base::fmtflags flags = stream->flags(); |
| base.flags(flags); |
| mask.flags(flags); |
| int width = (int)stream->width(); |
| base.width(width); |
| mask.width(width); |
| int precision = (int)stream->precision(); |
| base.precision(precision); |
| mask.precision(precision); |
| fill = stream->fill(); |
| fillSet = true; |
| } |
| } |
| |
| void wlogstream::refresh_stream_state() |
| { |
| if (stream != 0) |
| { |
| int ch; |
| |
| if (logstream_base::set_stream_state(*stream, ch)) |
| { |
| stream->fill(ch); |
| } |
| } |
| } |
| #endif |
| |
| #if LOG4CXX_UNICHAR_API |
| ulogstream::ulogstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level) |
| : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| |
| ulogstream::ulogstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| #endif |
| |
| #if LOG4CXX_CFSTRING_API |
| ulogstream::ulogstream(const CFStringRef& loggerName, |
| const log4cxx::LevelPtr& level) |
| : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) |
| { |
| } |
| |
| #endif |
| |
| |
| #if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API |
| |
| ulogstream::ulogstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0) |
| { |
| } |
| |
| |
| |
| ulogstream::~ulogstream() |
| { |
| delete stream; |
| } |
| |
| ulogstream& ulogstream::operator<<(logstream_base & (*manip)(logstream_base&)) |
| { |
| (*manip)(*this); |
| return *this; |
| } |
| |
| ulogstream& ulogstream::operator<<(const LevelPtr& level) |
| { |
| setLevel(level); |
| return *this; |
| } |
| |
| ulogstream& ulogstream::operator<<(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| ulogstream& ulogstream::operator>>(const log4cxx::spi::LocationInfo& newlocation) |
| { |
| setLocation(newlocation); |
| return *this; |
| } |
| |
| |
| |
| |
| ulogstream& ulogstream::operator<<(std::ios_base & (*manip)(std::ios_base&)) |
| { |
| logstream_base::insert(manip); |
| return *this; |
| } |
| |
| ulogstream::operator std::basic_ostream<UniChar>& () |
| { |
| if (stream == 0) |
| { |
| stream = new std::basic_stringstream<Ch>(); |
| refresh_stream_state(); |
| } |
| |
| return *stream; |
| } |
| |
| void ulogstream::log(LoggerPtr& logger, |
| const LevelPtr& level, |
| const log4cxx::spi::LocationInfo& location) |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> msg = stream->str(); |
| |
| if (!msg.empty() && logger->isEnabledFor(level)) |
| { |
| LOG4CXX_DECODE_UNICHAR(lsmsg, msg); |
| logger->forcedLogLS(level, lsmsg, location); |
| } |
| } |
| } |
| |
| |
| void ulogstream::erase() |
| { |
| if (stream != 0) |
| { |
| std::basic_string<Ch> emptyStr; |
| stream->str(emptyStr); |
| } |
| } |
| |
| |
| void ulogstream::get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const |
| { |
| if (stream != 0) |
| { |
| std::ios_base::fmtflags flags = stream->flags(); |
| base.flags(flags); |
| mask.flags(flags); |
| int width = stream->width(); |
| base.width(width); |
| mask.width(width); |
| int precision = stream->precision(); |
| base.precision(precision); |
| mask.precision(precision); |
| fill = stream->fill(); |
| fillSet = true; |
| } |
| } |
| |
| void ulogstream::refresh_stream_state() |
| { |
| if (stream != 0) |
| { |
| int fillchar; |
| |
| if (logstream_base::set_stream_state(*stream, fillchar)) |
| { |
| stream->fill(fillchar); |
| } |
| } |
| } |
| #endif |
| |
| |