| /* |
| * 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. |
| */ |
| |
| #ifndef _LOG4CXX_STREAM_H |
| #define _LOG4CXX_STREAM_H |
| |
| #include <log4cxx/logger.h> |
| #include <sstream> |
| #include <log4cxx/spi/location/locationinfo.h> |
| |
| namespace log4cxx |
| { |
| |
| /** |
| * Base class for the basic_logstream template which attempts |
| * to emulate std::basic_ostream but attempts to short-circuit |
| * unnecessary operations. |
| * |
| * The logstream has a logger and level that are used for logging |
| * requests. The level of the stream is compared against the |
| * current level of the logger to determine if the request should be processed. |
| */ |
| class LOG4CXX_EXPORT logstream_base |
| { |
| public: |
| /** |
| * Create new instance. |
| * @param logger logger logger used in log requests. |
| * @param level indicates level that will be used in log requests. Can |
| * be modified later by inserting a level or calling setLevel. |
| */ |
| logstream_base(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level); |
| /** |
| * Destructor. |
| */ |
| virtual ~logstream_base(); |
| /** |
| * Insertion operator for std::fixed and similar manipulators. |
| */ |
| void insert(std::ios_base & (*manip)(std::ios_base&)); |
| |
| /** |
| * get precision. |
| */ |
| int precision(); |
| /** |
| * get width. |
| */ |
| int width(); |
| /** |
| * set precision. This should be used in preference to inserting an std::setprecision(n) |
| * since the other requires construction of an STL stream which may be expensive. |
| */ |
| int precision(int newval); |
| /** |
| * set width. This should be used in preference to inserting an std::setw(n) |
| * since the other requires construction of an STL stream which may be expensive. |
| */ |
| int width(int newval); |
| /** |
| * Get fill character. |
| */ |
| int fill(); |
| /** |
| * Set fill character. |
| */ |
| int fill(int newval); |
| |
| /** |
| * Set flags. see std::ios_base. |
| */ |
| std::ios_base::fmtflags flags(std::ios_base::fmtflags newflags); |
| /** |
| * Set flags. see std::ios_base. |
| */ |
| std::ios_base::fmtflags setf(std::ios_base::fmtflags newflags, std::ios_base::fmtflags mask); |
| /** |
| * Set flags. see std::ios_base. |
| */ |
| std::ios_base::fmtflags setf(std::ios_base::fmtflags newflags); |
| |
| |
| /** |
| * end of message manipulator, triggers logging. |
| */ |
| static logstream_base& endmsg(logstream_base&); |
| |
| /** |
| * no-operation manipulator, Used to avoid ambiguity with VC6. |
| */ |
| static logstream_base& nop(logstream_base&); |
| |
| /** |
| * end of message action. |
| */ |
| void end_message(); |
| |
| |
| |
| /** |
| * Set the level. |
| * @param level level |
| */ |
| void setLevel(const LevelPtr& level); |
| /** |
| * Returns true if the current level is the same or high as the |
| * level of logger at time of construction or last setLevel. |
| */ |
| inline bool isEnabled() const |
| { |
| return enabled; |
| } |
| |
| /** |
| * Returns if logger is currently enabled for the specified level. |
| */ |
| bool isEnabledFor(const LevelPtr& level) const; |
| |
| /** |
| * Sets the location for subsequent log requests. |
| */ |
| void setLocation(const log4cxx::spi::LocationInfo& location); |
| |
| /** |
| * Sets the state of the embedded stream (if any) |
| * to the state of the formatting info. |
| * @param os stream to receive formatting info. |
| * @param fillchar receives fill charater. |
| * @return true if fill character was specified. |
| */ |
| bool set_stream_state(std::ios_base& os, int& fillchar); |
| |
| protected: |
| /** |
| * Dispatches the pending log request. |
| */ |
| virtual void log(LoggerPtr& logger, |
| const LevelPtr& level, |
| const log4cxx::spi::LocationInfo& location) = 0; |
| /** |
| * Erase any content in the message construction buffer. |
| */ |
| virtual void erase() = 0; |
| /** |
| * Copy state of embedded stream (if any) |
| * to value and mask instances of std::ios_base |
| * and return fill character value. |
| */ |
| virtual void get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const = 0; |
| virtual void refresh_stream_state() = 0; |
| |
| private: |
| /** |
| * prevent copy constructor. |
| */ |
| logstream_base(logstream_base&); |
| /** |
| * prevent copy operatpr. |
| */ |
| logstream_base& operator=(logstream_base&); |
| /** |
| * Minimal extension of std::ios_base to allow creation |
| * of embedded IO states. |
| */ |
| class LOG4CXX_EXPORT logstream_ios_base : public std::ios_base |
| { |
| public: |
| logstream_ios_base(std::ios_base::fmtflags initval, |
| int initsize); |
| } initset, initclear; |
| /** |
| * fill character. |
| */ |
| int fillchar; |
| /** |
| * true if fill character is set. |
| */ |
| bool fillset; |
| /** |
| * true if assigned level was same or higher than level of associated logger. |
| */ |
| bool enabled; |
| /** |
| * associated logger. |
| */ |
| log4cxx::LoggerPtr logger; |
| /** |
| * associated level. |
| */ |
| log4cxx::LevelPtr level; |
| /** |
| * associated level. |
| */ |
| log4cxx::spi::LocationInfo location; |
| }; |
| |
| typedef logstream_base& (*logstream_manipulator)(logstream_base&); |
| |
| /** |
| * An STL-like stream API for log4cxx using char as the character type. |
| *. Instances of log4cxx::logstream |
| * are not designedfor use by multiple threads and in general should be short-lived |
| * function scoped objects. Using log4cxx::basic_logstream as a class member or |
| * static instance should be avoided in the same manner as you would avoid placing a std::ostringstream |
| * in those locations. Insertion operations are generally short-circuited if the |
| * level for the stream is not the same of higher that the level of the associated logger. |
| */ |
| class LOG4CXX_EXPORT logstream : public logstream_base |
| { |
| typedef char Ch; |
| public: |
| /** |
| * Constructor. |
| */ |
| logstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level); |
| |
| /** |
| * Constructor. |
| */ |
| logstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level); |
| |
| /** |
| * Constructor. |
| */ |
| logstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level); |
| |
| ~logstream(); |
| |
| /** |
| * Insertion operator for std::fixed and similar manipulators. |
| */ |
| logstream& operator<<(std::ios_base & (*manip)(std::ios_base&)); |
| |
| /** |
| * Insertion operator for logstream_base::endmsg. |
| */ |
| logstream& operator<<(logstream_manipulator manip); |
| |
| /** |
| * Insertion operator for level. |
| */ |
| logstream& operator<<(const log4cxx::LevelPtr& level); |
| /** |
| * Insertion operator for location. |
| */ |
| logstream& operator<<(const log4cxx::spi::LocationInfo& location); |
| |
| /** |
| * Alias for insertion operator for location. Kludge to avoid |
| * inappropriate compiler ambiguity. |
| */ |
| logstream& operator>>(const log4cxx::spi::LocationInfo& location); |
| |
| /** |
| * Cast operator to provide access to embedded std::basic_ostream. |
| */ |
| operator std::basic_ostream<Ch>& (); |
| |
| #if !(LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE) |
| /** |
| * Template to allow any class with an std::basic_ostream inserter |
| * to be applied to this class. |
| */ |
| template <class V> |
| inline log4cxx::logstream& operator<<(const V& val) |
| { |
| if (LOG4CXX_UNLIKELY(isEnabled())) |
| { |
| ((std::basic_ostream<char>&) *this) << val; |
| } |
| |
| return *this; |
| } |
| #endif |
| |
| |
| protected: |
| virtual void log(LoggerPtr& logger, |
| const LevelPtr& level, |
| const log4cxx::spi::LocationInfo& location); |
| |
| virtual void erase(); |
| |
| virtual void get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const; |
| virtual void refresh_stream_state(); |
| |
| |
| private: |
| logstream(const logstream&); |
| logstream& operator=(const logstream&); |
| std::basic_stringstream<Ch>* stream; |
| |
| }; |
| |
| #if LOG4CXX_WCHAR_T_API |
| /** |
| * An STL-like stream API for log4cxx using wchar_t as the character type. |
| *. Instances of log4cxx::logstream |
| * are not designedfor use by multiple threads and in general should be short-lived |
| * function scoped objects. Using log4cxx::basic_logstream as a class member or |
| * static instance should be avoided in the same manner as you would avoid placing a std::ostringstream |
| * in those locations. Insertion operations are generally short-circuited if the |
| * level for the stream is not the same of higher that the level of the associated logger. |
| */ |
| class LOG4CXX_EXPORT wlogstream : public logstream_base |
| { |
| typedef wchar_t Ch; |
| public: |
| /** |
| * Constructor. |
| */ |
| wlogstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level); |
| |
| /** |
| * Constructor. |
| */ |
| wlogstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level); |
| |
| /** |
| * Constructor. |
| */ |
| wlogstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level); |
| |
| ~wlogstream(); |
| |
| /** |
| * Insertion operator for std::fixed and similar manipulators. |
| */ |
| wlogstream& operator<<(std::ios_base & (*manip)(std::ios_base&)); |
| |
| /** |
| * Insertion operator for logstream_base::endmsg. |
| */ |
| wlogstream& operator<<(logstream_manipulator manip); |
| |
| /** |
| * Insertion operator for level. |
| */ |
| wlogstream& operator<<(const log4cxx::LevelPtr& level); |
| /** |
| * Insertion operator for location. |
| */ |
| wlogstream& operator<<(const log4cxx::spi::LocationInfo& location); |
| |
| /** |
| * Alias for insertion operator for location. Kludge to avoid |
| * inappropriate compiler ambiguity. |
| */ |
| wlogstream& operator>>(const log4cxx::spi::LocationInfo& location); |
| |
| |
| /** |
| * Cast operator to provide access to embedded std::basic_ostream. |
| */ |
| operator std::basic_ostream<Ch>& (); |
| |
| #if !(LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE) |
| /** |
| * Template to allow any class with an std::basic_ostream inserter |
| * to be applied to this class. |
| */ |
| template <class V> |
| inline log4cxx::wlogstream& operator<<(const V& val) |
| { |
| if (LOG4CXX_UNLIKELY(isEnabled())) |
| { |
| ((std::basic_ostream<wchar_t>&) *this) << val; |
| } |
| |
| return *this; |
| } |
| #endif |
| |
| protected: |
| virtual void log(LoggerPtr& logger, |
| const LevelPtr& level, |
| const log4cxx::spi::LocationInfo& location); |
| |
| virtual void erase(); |
| |
| virtual void get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const; |
| virtual void refresh_stream_state(); |
| |
| |
| private: |
| wlogstream(const wlogstream&); |
| wlogstream& operator=(const wlogstream&); |
| std::basic_stringstream<Ch>* stream; |
| |
| }; |
| #endif |
| |
| #if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API |
| /** |
| * An STL-like stream API for log4cxx using UniChar as the character type. |
| *. Instances of log4cxx::logstream |
| * are not designedfor use by multiple threads and in general should be short-lived |
| * function scoped objects. Using log4cxx::basic_logstream as a class member or |
| * static instance should be avoided in the same manner as you would avoid placing a std::ostringstream |
| * in those locations. Insertion operations are generally short-circuited if the |
| * level for the stream is not the same of higher that the level of the associated logger. |
| */ |
| class LOG4CXX_EXPORT ulogstream : public logstream_base |
| { |
| typedef UniChar Ch; |
| public: |
| /** |
| * Constructor. |
| */ |
| ulogstream(const log4cxx::LoggerPtr& logger, |
| const log4cxx::LevelPtr& level); |
| |
| #if LOG4CXX_UNICHAR_API |
| /** |
| * Constructor. |
| */ |
| ulogstream(const Ch* loggerName, |
| const log4cxx::LevelPtr& level); |
| |
| /** |
| * Constructor. |
| */ |
| ulogstream(const std::basic_string<Ch>& loggerName, |
| const log4cxx::LevelPtr& level); |
| #endif |
| |
| #if LOG4CXX_CFSTRING_API |
| ulogstream(const CFStringRef& loggerName, |
| const log4cxx::LevelPtr& level); |
| #endif |
| |
| ~ulogstream(); |
| |
| /** |
| * Insertion operator for std::fixed and similar manipulators. |
| */ |
| ulogstream& operator<<(std::ios_base & (*manip)(std::ios_base&)); |
| |
| /** |
| * Insertion operator for logstream_base::endmsg. |
| */ |
| ulogstream& operator<<(logstream_manipulator manip); |
| |
| /** |
| * Insertion operator for level. |
| */ |
| ulogstream& operator<<(const log4cxx::LevelPtr& level); |
| /** |
| * Insertion operator for location. |
| */ |
| ulogstream& operator<<(const log4cxx::spi::LocationInfo& location); |
| |
| /** |
| * Alias for insertion operator for location. Kludge to avoid |
| * inappropriate compiler ambiguity. |
| */ |
| ulogstream& operator>>(const log4cxx::spi::LocationInfo& location); |
| |
| |
| /** |
| * Cast operator to provide access to embedded std::basic_ostream. |
| */ |
| operator std::basic_ostream<Ch>& (); |
| |
| #if !(LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE) |
| /** |
| * Template to allow any class with an std::basic_ostream inserter |
| * to be applied to this class. |
| */ |
| template <class V> |
| inline ulogstream& operator<<(const V& val) |
| { |
| if (LOG4CXX_UNLIKELY(isEnabled())) |
| { |
| ((std::basic_ostream<Ch>&) *this) << val; |
| } |
| |
| return *this; |
| } |
| #endif |
| |
| protected: |
| virtual void log(LoggerPtr& logger, |
| const LevelPtr& level, |
| const log4cxx::spi::LocationInfo& location); |
| |
| virtual void erase(); |
| |
| virtual void get_stream_state(std::ios_base& base, |
| std::ios_base& mask, |
| int& fill, |
| bool& fillSet) const; |
| virtual void refresh_stream_state(); |
| |
| |
| private: |
| ulogstream(const ulogstream&); |
| ulogstream& operator=(const ulogstream&); |
| std::basic_stringstream<Ch>* stream; |
| |
| }; |
| #endif |
| |
| |
| } // namespace log4cxx |
| |
| |
| #if LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE |
| // |
| // VC6 will fail to compile if class-scope templates |
| // are used to handle arbitrary insertion operations. |
| // However, using global namespace insertion operations |
| // run into LOGCXX-150. |
| |
| /** |
| * Template to allow any class with an std::basic_ostream inserter |
| * to be applied to this class. |
| */ |
| template <class V> |
| inline log4cxx::logstream& operator<<(log4cxx::logstream& os, const V& val) |
| { |
| if (LOG4CXX_UNLIKELY(os.isEnabled())) |
| { |
| ((std::basic_ostream<char>&) os) << val; |
| } |
| |
| return os; |
| } |
| |
| #if LOG4CXX_WCHAR_T_API |
| /** |
| * Template to allow any class with an std::basic_ostream inserter |
| * to be applied to this class. |
| */ |
| template <class V> |
| inline log4cxx::wlogstream& operator<<(log4cxx::wlogstream& os, const V& val) |
| { |
| if (LOG4CXX_UNLIKELY(os.isEnabled())) |
| { |
| ((std::basic_ostream<wchar_t>&) os) << val; |
| } |
| |
| return os; |
| } |
| #endif |
| #endif |
| |
| #if !defined(LOG4CXX_ENDMSG) |
| #if LOG4CXX_LOGSTREAM_ADD_NOP |
| #define LOG4CXX_ENDMSG (log4cxx::logstream_manipulator) log4cxx::logstream_base::nop >> LOG4CXX_LOCATION << (log4cxx::logstream_manipulator) log4cxx::logstream_base::endmsg |
| #else |
| #define LOG4CXX_ENDMSG LOG4CXX_LOCATION << (log4cxx::logstream_manipulator) log4cxx::logstream_base::endmsg |
| #endif |
| #endif |
| |
| |
| #endif //_LOG4CXX_STREAM_H |