You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2004/10/25 06:37:33 UTC

cvs commit: logging-log4cxx/include/log4cxx stream.h

carnold     2004/10/24 21:37:33

  Modified:    include/log4cxx stream.h
  Log:
  LOGCXX-18: Reworked as std::ios_base to reduce overhead when disabled
  
  Revision  Changes    Path
  1.3       +119 -202  logging-log4cxx/include/log4cxx/stream.h
  
  Index: stream.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/stream.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- stream.h	8 Oct 2004 04:10:59 -0000	1.2
  +++ stream.h	25 Oct 2004 04:37:33 -0000	1.3
  @@ -23,171 +23,111 @@
   
   namespace log4cxx
   {
  -	/**
  -	 * Implements an STL streambuf for use by logging streams.
  -	 */
  -	template <class Elem, class Tr = ::std::char_traits<Elem> >
  -	   class basic_logstreambuf : public ::std::basic_stringbuf<Elem, Tr> {
  -	   public:
  -	   /**
  -	    * Constructor.
  -	    *
  -	    */
  -	   basic_logstreambuf(const ::log4cxx::LoggerPtr& logger,
  -	                   const ::log4cxx::LevelPtr& level) :
  -	                   ::std::basic_stringbuf<Elem, Tr>(::std::ios_base::out),
  -	                   logger(logger),
  -	                   level(level)  {
  -	        enabled = logger->isEnabledFor(level);
  -	   }
  -
  -       /**
  -        * Gets whether logger is currently enabled for the specified level.
  -        * @returns true if enabled
  -        */
  -	   inline bool isEnabled() const {
  -	   	  return enabled;
  -	   }
  -
  -	   /**
  -	    * Sets the call site location.
  -	    * @param location call site location
  -	    */
  -	   void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
  -	   	   this->location = location;
  -	   }
  -
  -	   /**
  -	    * Sets the level.
  -	    * @param level level
  -	    */
  -	   void setLevel(const ::log4cxx::LevelPtr& level) {
  -	   	  bool newState = logger->isEnabledFor(level);
  -	   	  //
  -	   	  //    if not previously enabled but soon to be enabled then
  -	   	  //       reset the buffer to clear any previously inserted content
  -	   	  if (newState && !enabled) {
  -	   	     //
  -	   	     //   reset the stream buffer
  -	   	     seekoff(0, ::std::ios_base::beg, ::std::ios_base::out);
  -	   	  }
  -	   	  this->level = level;
  -	   	  enabled = newState;
  -	   }
  -
  -       protected:
  -       /**
  -        * Synchronizes the stream and logger.
  -        *
  -        */
  -	   int sync() {
  -	   	  //
  -	   	  //  if previously enabled
  -	   	  if (enabled) {
  -	   	  	 //  check (and cache) whether it is still enabled
  -	   	     enabled = logger->isEnabledFor(level);
  -	   	     //  log message if still enabled
  -	   	     if (enabled) {
  -	   	          logger->forcedLog(level,
  -	   	              str(),
  -	   	              location.getFileName(),
  -	   	              location.getLineNumber());
  -	   	     }
  -	   	  }
  -	   	  //  clear call site information
  -          location.clear();
  -	   	  //
  -	   	  //   reset the stream buffer
  -	   	  seekoff(0, ::std::ios_base::beg, ::std::ios_base::out);
  -	   	  return 0;
  -	   }
  -
  -       bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
  -       	   return logger.isEnabledFor(level);
  -       }
  -
  -	   private:
  -	   /**
  -	    * logger.
  -	    */
  -	   ::log4cxx::LoggerPtr logger;
  -	   /**
  -	    * level.
  -	    */
  -	   ::log4cxx::LevelPtr level;
  -	   /**
  -	    * location.
  -	    */
  -	   ::log4cxx::spi::location::LocationInfo location;
  -
  -       /**
  -        * State of logger at last sync or level changes.
  -        */
  -       bool enabled;
  -
  -	};
  -
  -	/**
  -	 * This template provides an stream interface layer to
  -	 * log4cxx.
  -	 */
  -	template <class Elem, class Tr = ::std::char_traits<Elem> >
  -	   class basic_logstream : public ::std::basic_ostream<Elem, Tr> {
  -
  -	   public:
  -	   /**
  -	    * Constructor.
  -	    */
  -	   basic_logstream(const ::log4cxx::LoggerPtr& logger,
  -	                const ::log4cxx::LevelPtr& level) :
  -	                ::std::basic_ostream<Elem, Tr>(&buffer),
  -	                buffer(logger, level) {
  -	   }
  -
  -          /**
  -           * Constructor.
  -           */
  -           basic_logstream(const char* logName,
  -             ::log4cxx::LevelPtr& level) :
  -             ::std::basic_ostream<Elem, Tr>(&buffer),
  -             buffer(::log4cxx::Logger::getLogger(logName), level) {
  -            }
  -
  -
  -          /**
  -           * Sets the call site location.
  -           * @param location call site location
  -           */
  -	   void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
  -	   	   buffer.setLocation(location);
  -	   }
  -
  -
  -	   /**
  -	    * Set the level.
  -	    * @param level level
  -	    */
  -	   void setLevel(const ::log4cxx::LevelPtr& level) {
  -	   	  buffer.setLevel(level);
  -	   }
  -
  -       inline bool isEnabled() const {
  -           return buffer.isEnabled();
  -       }
  -       
  -       bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
  -       	   return buffer.isEnabledFor(level);
  -       }
  -
  -
  -	   private:
  -	   basic_logstreambuf<Elem, Tr> buffer;
  -	};
  +        /**
  +         * This template acts as a proxy for base_logstreamimpl
  +         * and defers the potentially expensive construction
  +         * of basic_stream until needed.
  +         */
  +        template <class Elem, class Tr = ::std::char_traits<Elem> >
  +           class basic_logstream : public ::std::ios_base {
  +             public:
  +             /**
  +              * Constructor.
  +              */
  +             basic_logstream(const ::log4cxx::LoggerPtr& loggr,
  +                          const ::log4cxx::LevelPtr& level) :
  +                          logger(loggr),
  +                          currentLevel(level),
  +                          impl(0),
  +                          enabled(loggr->isEnabledFor(level)) {
  +             }
  +
  +            /**
  +             * Constructor.
  +             */
  +             basic_logstream(const char* logName,
  +               ::log4cxx::LevelPtr& level) :
  +               logger(::log4cxx::Logger::getLogger(logName)),
  +               currentLevel(level),
  +               impl(0),
  +               enabled(logger->isEnabledFor(level)) {
  +              }
  +
  +              ~basic_logstream() {
  +                  delete impl;
  +              }
  +
  +
  +
  +             /**
  +              * Set the level.
  +              * @param level level
  +              */
  +              void setLevel(const ::log4cxx::LevelPtr& level) {
  +                  currentLevel = level;
  +                  enabled = logger->isEnabledFor(currentLevel);
  +              }
  +
  +              inline bool isEnabled() const {
  +                 return enabled;
  +              }
  +
  +              bool isEnabledFor(const ::log4cxx::LevelPtr& level) const {
  +                 return logger.isEnabledFor(level);
  +              }
  +
  +
  +              void setLocation(const ::log4cxx::spi::location::LocationInfo& location) {
  +                 if (LOG4CXX_UNLIKELY(enabled)) {
  +                    currentLocation = location;
  +                 }
  +              }
  +
  +
  +
  +             void flush(const ::log4cxx::spi::location::LocationInfo& location) {
  +                 if (LOG4CXX_UNLIKELY(enabled && 0 != impl)) {
  +                    ::std::basic_string<Elem, Tr> msg(impl->str());
  +                    logger->log(currentLevel,
  +                       msg,
  +                       location.getFileName(),
  +                       location.getLineNumber());
  +                    msg.clear();
  +                    impl->str(msg);
  +                }
  +             }
  +
  +             inline void flush() {
  +                flush(currentLocation);
  +             }
  +
  +
  +             ::std::basic_ostream<Elem, Tr>& getStream() {
  +                if (0 == impl) {
  +                  impl = new ::std::basic_ostringstream<Elem, Tr>();
  +                }
  +                impl->precision(precision());
  +                impl->width(width());
  +                impl->flags(flags());
  +                return *impl;
  +             }
  +
  +             private:
  +             LevelPtr currentLevel;
  +             LoggerPtr logger;
  +             ::log4cxx::spi::location::LocationInfo currentLocation;
  +             bool enabled;
  +             ::std::basic_ostringstream<Elem, Tr>* impl;
  +
  +        };
   
   	typedef basic_logstream<char> logstream;
   	typedef basic_logstream<wchar_t> wlogstream;
   }  // namespace log4cxx
   
  +
  +
  +
   /**
   * Insertion operator for LocationInfo.
   *
  @@ -196,9 +136,7 @@
   ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
      ::log4cxx::basic_logstream<Elem, Tr>& lhs,
      const ::log4cxx::spi::location::LocationInfo& rhs) {
  -   if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
  -      lhs.setLocation(rhs);
  -   }
  +   lhs.setLocation(rhs);
      return lhs;
   }
   
  @@ -210,16 +148,13 @@
   ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
      ::log4cxx::basic_logstream<Elem, Tr>& lhs,
      const ::log4cxx::spi::location::LocationFlush& rhs) {
  -   if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
  -   	  lhs.setLocation(rhs);
  -   	  lhs.flush();
  -   }
  +   lhs.flush(rhs);
      return lhs;
   }
   
   
   /**
  -* Insertion operator for LocationInfo.
  +* Insertion operator for Level.
   *
   */
   template<class Elem, class Tr>
  @@ -231,50 +166,32 @@
   }
   
   
  -#define LOG4CXX_STREAM_DEFINE_INSERTION(InsType)           \
  -template<class Elem, class Tr>                             \
  -::log4cxx::basic_logstream<Elem, Tr>& operator<<(          \
  -   ::log4cxx::basic_logstream<Elem, Tr>& lhs,              \
  -   InsType rhs) {                                          \
  -   if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {                \
  -      ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs;      \
  -   }                                                       \
  -   return lhs;                                             \
  +//
  +//
  +//   template for manipulators (std::scientific et al)
  +//
  +template<class Elem, class Tr>
  +::log4cxx::basic_logstream<Elem, Tr>& operator<<(
  +   ::log4cxx::basic_logstream<Elem, Tr>& lhs,
  +   ::std::ios_base& (*manip)(::std::ios_base&)) {
  +     (*manip)(lhs);
  +   return lhs;
   }
   
   
   
  -/*
  -* Insertion operators for common types.
  -* Can't use template or would get ambiguities.
  -* If attempting to insert a type without a matching
  -* logstream specific insertion operator, the type
  -* will be formatted, but may get discarded.
  -*
  -*/
  -LOG4CXX_STREAM_DEFINE_INSERTION(bool)
  -LOG4CXX_STREAM_DEFINE_INSERTION(signed char)
  -LOG4CXX_STREAM_DEFINE_INSERTION(unsigned char)
  -LOG4CXX_STREAM_DEFINE_INSERTION(signed short)
  -LOG4CXX_STREAM_DEFINE_INSERTION(unsigned short)
  -LOG4CXX_STREAM_DEFINE_INSERTION(signed int)
  -LOG4CXX_STREAM_DEFINE_INSERTION(unsigned int)
  -LOG4CXX_STREAM_DEFINE_INSERTION(signed long)
  -LOG4CXX_STREAM_DEFINE_INSERTION(unsigned long)
  -LOG4CXX_STREAM_DEFINE_INSERTION(float)
  -LOG4CXX_STREAM_DEFINE_INSERTION(double)
  -LOG4CXX_STREAM_DEFINE_INSERTION(const Elem*)
  -
  -template<class Elem, class Tr>
  +//
  +//   template for all other insertion operators
  +//
  +template<class Elem, class Tr, class ArbitraryType>
   ::log4cxx::basic_logstream<Elem, Tr>& operator<<(
      ::log4cxx::basic_logstream<Elem, Tr>& lhs,
  -   const ::std::basic_string<Elem, Tr>& rhs) {
  +   const ArbitraryType& rhs) {
      if (LOG4CXX_UNLIKELY(lhs.isEnabled())) {
  -      ((::std::basic_ostream<Elem, Tr>&) lhs) << rhs;
  +       lhs.getStream() << rhs;
      }
      return lhs;
   }
  -
   
   #if !defined(LOG4CXX_ENDMSG)
   #define LOG4CXX_ENDMSG LOG4CXX_LOCATION_FLUSH