blob: 29c3bcfaeee96d8b366e609d2745f1d36d5f5e3f [file] [log] [blame]
/*
* 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