Utils/Logger: Correct newline handling in IOStreamLogger
g0dil [Tue, 30 Oct 2007 10:34:52 +0000 (10:34 +0000)]
Utils/Logger: Completed the target routing and querying API

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@479 270642c3-0616-0410-b53a-bc976706d245

Utils/Logger/IOStreamTarget.cc
Utils/Logger/Target.cc
Utils/Logger/Target.cci
Utils/Logger/Target.cti
Utils/Logger/Target.hh

index f70fdd7..c373a0f 100644 (file)
@@ -28,6 +28,8 @@
 
 // Custom includes
 #include <locale>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/tokenizer.hpp>
 
 //#include "IOStreamTarget.mpp"
 #define prefix_
@@ -41,7 +43,8 @@ prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os)
 {
     std::locale const & loc (stream_.getloc());
     if (!std::has_facet<boost::posix_time::time_facet>(loc))
-        stream_.imbue( std::locale(loc, new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S.%f-0000")) );
+        stream_.imbue( std::locale(
+                           loc, new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S.%f-0000")) );
 }
 
 ////////////////////////////////////////
@@ -52,10 +55,25 @@ prefix_ void senf::log::IOStreamTarget::v_write(boost::posix_time::ptime timesta
                                                 std::string const & area, unsigned level,
                                                 std::string const & message)
 {
-    stream_ << timestamp << " ";
-    if (! area.empty())
-        stream_ << "[" << area << "] ";
-    stream_ << message << std::endl;
+    std::string m (boost::trim_right_copy(message));
+
+    typedef boost::char_separator<char> Separator;
+    typedef boost::tokenizer<Separator> Tokenizer;
+    Separator separator ("\n");
+    Tokenizer tokenizer (m, separator);
+    Tokenizer::iterator i (tokenizer.begin());
+    Tokenizer::iterator const i_end (tokenizer.end());
+
+    char sep (' ');
+
+    for (; i != i_end; ++i) {
+        stream_ << timestamp << sep;
+        if (! area.empty())
+            stream_ << "[" << area << "] ";
+        stream_ << *i << "\n";
+        sep = '-';
+    }
+    stream_ << std::flush;
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index 11142a7..e6fdc0c 100644 (file)
@@ -46,11 +46,89 @@ prefix_ senf::log::Target::~Target()
         // This is terribly slow but simplifies the area cache handling and removing a target should
         // be quite seldom
         RIB::reverse_iterator i (rib_.rbegin());
-        unroute(i->stream, i->area, i->level, i->action);
+        unroute(i->stream_, i->area_, i->level_, i->action_);
     }
     TargetRegistry::instance().unregisterTarget(this);
 }
 
+prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area,
+                                      unsigned level, action_t action, int index)
+{
+    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
+    if (!s)
+        throw InvalidStreamException();
+    detail::AreaBase const * a (0);
+    if (! area.empty()) {
+        a = AreaRegistry::instance().lookup(area);
+        if (!a)
+            throw InvalidAreaException();
+    }
+    route(s, a, level, action, index);
+}
+
+prefix_ void senf::log::Target::unroute(int index)
+{
+    RIB::iterator i;
+    if (index < 0) {
+        if (RIB::size_type(-index) >= rib_.size())
+            i = rib_.begin();
+        else {
+            i = rib_.end();
+            std::advance(i, -index);
+        }
+    } else {
+        if (RIB::size_type(index+1) >= rib_.size()) {
+            i = rib_.end();
+            --i;
+        } else {
+            i = rib_.begin();
+            std::advance(i, index);
+        }
+    }
+    RoutingEntry entry (*i);
+    rib_.erase(i);
+    if (entry.action_ == ACCEPT)
+        updateRoutingCache(entry.stream_, entry.area_);
+}
+
+////////////////////////////////////////
+// private members
+
+prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
+                                      detail::AreaBase const * area, unsigned level,
+                                      action_t action, int index)
+{
+    RIB::iterator i;
+    if (index < 0) {
+        if (RIB::size_type(-index-1) >= rib_.size())
+            i = rib_.begin();
+        else {
+            i = rib_.end();
+            std::advance(i, -index - 1);
+        }
+    } else {
+        if (RIB::size_type(index) >= rib_.size())
+            i = rib_.end();
+        else {
+            i = rib_.begin();
+            std::advance(i, index);
+        }
+    }
+    rib_.insert(i, RoutingEntry(stream, area, level, action));
+    if (action == ACCEPT)
+        updateRoutingCache(stream, area);
+}
+
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+                                        detail::AreaBase const * area, unsigned level, 
+                                        action_t action)
+{
+    RIB::iterator i = std::find(rib_.begin(), rib_.end(), 
+                                RoutingEntry(stream, area, level, action));
+    if (i != rib_.end())
+        unroute(std::distance(rib_.begin(), i));
+}
+
 prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * stream,
                                                    detail::AreaBase const * area)
 {
@@ -72,10 +150,10 @@ prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * st
     RIB::iterator i (rib_.begin());
     RIB::iterator const i_end (rib_.end());
     for(; i != i_end; ++i)
-        if ( (! i->stream || i->stream == stream) &&
-             (! i->area || i->area == area) &&
-             i->action == ACCEPT ) {
-            unsigned l (i->level == NONE::value ? i->stream->defaultRuntimeLimit() : i->level);
+        if ( (! i->stream_ || i->stream_ == stream) &&
+             (! i->area_ || i->area_ == area) &&
+             i->action_ == ACCEPT ) {
+            unsigned l (i->level_ == NONE::value ? i->stream_->defaultRuntimeLimit() : i->level_);
             if (l < limit)
                 limit = l;
         }
@@ -93,10 +171,10 @@ prefix_ void senf::log::Target::write(boost::posix_time::ptime timestamp,
     RIB::iterator i (rib_.begin());
     RIB::iterator const i_end (rib_.end());
     for (; i != i_end; ++i)
-        if ( (! i->stream || i->stream == &stream) &&
-             (! i->area || i->area == &area) &&
-             (i->level == NONE::value ? i->stream->defaultRuntimeLimit() : i->level) <= level ) {
-            if (i->action == ACCEPT)
+        if ( (! i->stream_ || i->stream_ == &stream) &&
+             (! i->area_ || i->area_ == &area) &&
+             (i->level_ == NONE::value ? i->stream_->defaultRuntimeLimit() : i->level_) <= level ) {
+            if (i->action_ == ACCEPT)
                 v_write(timestamp, stream.v_name(), area.v_name(), level, message);
             return;
         }
index f58865e..5261bdb 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // senf::log::Target
 
-prefix_ void senf::log::Target::route(std::string const & stream, action_t action)
+prefix_ iterator senf::log::Target::begin()
+    const
 {
-    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
-    if (!s)
-        throw InvalidStreamException();
-    route(s, 0, NONE::value, action);
+    return rib_.begin();
 }
 
-prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area,
-                                      action_t action)
+prefix_ iterator senf::log::Target::end()
+    const
 {
-    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
-    if (!s)
-        throw InvalidStreamException();
-    detail::AreaBase const * a (AreaRegistry::instance().lookup(area));
-    if (!a)
-        throw InvalidAreaException();
-    route(s, a, NONE::value, action);
-}
-
-prefix_ void senf::log::Target::route(std::string const & stream, unsigned level, action_t action)
-{
-    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
-    if (!s)
-        throw InvalidStreamException();
-    route(s, 0, level, action);
-}
-
-prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area,
-                                      unsigned level, action_t action)
-{
-    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
-    if (!s)
-        throw InvalidStreamException();
-    detail::AreaBase const * a (AreaRegistry::instance().lookup(area));
-    if (!a)
-        throw InvalidAreaException();
-    route(s, a, level, action);
-}
-
-////////////////////////////////////////
-// private members
-
-prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
-                                      detail::AreaBase const * area, unsigned level,
-                                      action_t action)
-{
-    rib_.push_back(RoutingEntry(stream, area, level, action));
-    if (action == ACCEPT)
-        updateRoutingCache(stream, area);
-}
-
-prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
-                                        detail::AreaBase const * area, unsigned level, 
-                                        action_t action)
-{
-    rib_.erase(std::remove(rib_.begin(), rib_.end(), RoutingEntry(stream, area, level, action)),
-               rib_.end());
-    if (action == ACCEPT)
-        updateRoutingCache(stream, area);
+    return rib_.end();
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // senf::log::Target::RoutingEntry
 
-prefix_ senf::log::Target::RoutingEntry::RoutingEntry(detail::StreamBase const * stream_,
-                                                      detail::AreaBase const * area_,
-                                                      unsigned level_, action_t action_)
-    : stream(stream_), area(area_), level(level_), action(action_) 
+prefix_ senf::log::Target::RoutingEntry::RoutingEntry(detail::StreamBase const * stream,
+                                                      detail::AreaBase const * area,
+                                                      unsigned level, action_t action)
+    : stream_(stream), area_(area), level_(level), action_(action) 
 {}
 
 prefix_ senf::log::Target::RoutingEntry::RoutingEntry()
-    : stream(0), area(0), level(0), action(ACCEPT) 
+    : stream_(0), area_(0), level_(0), action_(ACCEPT) 
 {}
 
 prefix_ bool senf::log::Target::RoutingEntry::operator==(RoutingEntry const & other)
 { 
     return 
-        stream == other.stream && 
-        area == other.area && 
-        level == other.level &&
-        action == other.action; 
+        stream_ == other.stream_ && 
+        area_ == other.area_ && 
+        level_ == other.level_ &&
+        action_ == other.action_; 
+}
+
+prefix_ std::string senf::log::Target::RoutingEntry::stream()
+    const
+{
+    return stream_->v_name();
+}
+
+prefix_ std::string senf::log::Target::RoutingEntry::area()
+    const
+{
+    return area_->v_name();
+}
+
+prefix_ unsigned senf::log::Target::RoutingEntry::level()
+    const
+{
+    return level_;
+}
+
+prefix_ senf::log::Target::action_t senf::log::Target::RoutingEntry::action()
+    const
+{
+    return action_;
 }
 
 ///////////////////////////////////////////////////////////////////////////
index a61c703..30a4523 100644 (file)
 // senf::log::Target
 
 template <class Stream>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
 {
-    route(&Stream::instance(), 0, NONE::value, action);
+    route(&Stream::instance(), 0, NONE::value, action, index);
 }
 
 template <class Stream, class Arg>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
 {
-    route<Arg>(&Stream::instance(), static_cast<Arg*>(0), action);
+    route<Arg>(&Stream::instance(), static_cast<Arg*>(0), action, index);
 }
 
 template <class Stream, class Area, class Level>
-prefix_ void senf::log::Target::route(action_t action)
+prefix_ void senf::log::Target::route(action_t action, int index)
 {
-    route(&Stream::instance(), &Area::instance(), Level::value, action);
+    route(&Stream::instance(), &Area::instance(), Level::value, action, index);
+}
+
+template <class Stream>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+    unroute(&Stream::instance(), 0, NONE::value, action);
+}
+
+template <class Stream, class Arg>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+    unroute<Arg>(&Stream::instance(), static_cast<Arg*>(0), action);
+}
+
+template <class Stream, class Area, class Level>
+prefix_ void senf::log::Target::unroute(action_t action)
+{
+    unroute(&Stream::instance(), &Area::instance(), Level::value, action);
 }
 
 ////////////////////////////////////////
@@ -57,16 +75,30 @@ prefix_ void senf::log::Target::route(action_t action)
 
 template <class Area>
 prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
-                                      detail::AreaBase const *, action_t action)
+                                      detail::AreaBase const *, action_t action, int index)
 {
-    route(stream, &Area::instance(), NONE::value, action);
+    route(stream, &Area::instance(), NONE::value, action, index);
 }
 
 template <class Level>
 prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
-                                      detail::LevelBase const *, action_t action)
+                                      detail::LevelBase const *, action_t action, int index)
+{
+    route(stream, 0, Level::value, action, index);
+}
+
+template <class Area>
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+                                        detail::AreaBase const *, action_t action)
+{
+    unroute(stream, &Area::instance(), NONE::value, action);
+}
+
+template <class Level>
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+                                        detail::LevelBase const *, action_t action)
 {
-    route(stream, 0, Level::value, action);
+    unroute(stream, 0, Level::value, action);
 }
 
 ///////////////////////////////////////////////////////////////////////////
index 56cf519..777e546 100644 (file)
@@ -62,6 +62,34 @@ namespace log {
 
         enum action_t { ACCEPT, REJECT };
 
+        struct RoutingEntry 
+        {
+            RoutingEntry();
+            bool operator==(RoutingEntry const & other);
+
+            std::string stream() const;
+            std::string area() const;
+            unsigned level() const;
+            action_t action() const;
+            
+        private:
+            RoutingEntry(detail::StreamBase const * stream, detail::AreaBase const * area, 
+                         unsigned level, action_t action);
+
+            detail::StreamBase const * stream_;
+            detail::AreaBase const * area_;
+            unsigned level_;
+            action_t action_;
+            
+            friend class Target;
+        };
+
+    private:
+        typedef std::vector<RoutingEntry> RIB;
+
+    public:
+        typedef RIB::const_iterator iterator;
+
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
@@ -71,45 +99,48 @@ namespace log {
 
         ///@}
 
-        template <class Stream>
-        void route(action_t action=ACCEPT);
+        template <class Stream> void route(action_t action = ACCEPT, int index = -1);
+        template <class Stream, class Arg> void route(action_t action = ACCEPT, int index = -1);
+        template <class Stream, class Area, class Level> void route(action_t action = ACCEPT, 
+                                                                    int index = -1);
 
-        template <class Stream, class Arg>
-        void route(action_t action=ACCEPT);
+        void route(std::string const & stream, std::string const & area = "", 
+                   unsigned level = NONE::value, action_t action = ACCEPT, int index = -1);
 
-        template <class Stream, class Area, class Level>
-        void route(action_t action=ACCEPT);
+        template <class Stream> void unroute(action_t action = ACCEPT);
+        template <class Stream, class Arg> void unroute(action_t action = ACCEPT);
+        template <class Stream, class Area, class Level> void unroute(action_t action = ACCEPT);
 
-        void route(std::string const & stream, action_t action=ACCEPT);
-        void route(std::string const & stream, std::string const & area, action_t action=ACCEPT);
-        void route(std::string const & stream, unsigned level, action_t action=ACCEPT);
-        void route(std::string const & stream, std::string const & area, unsigned level, 
-                   action_t action=ACCEPT);
+        void unroute(std::string const & stream, std::string const & area = "", 
+                     unsigned level = NONE::value, action_t action = ACCEPT);
+        void unroute(int index);
 
         struct InvalidStreamException : public std::exception
         { virtual char const * what() const throw() 
                 { return "senf::log::Target::InvalidStreamException"; } };
-
+        
         struct InvalidAreaException : public std::exception
         { virtual char const * what() const throw() 
                 { return "senf::log::Target::InvalidAreaException"; } };
-        
-    protected:
-
-        std::string timestamp();
 
+        iterator begin() const;
+        iterator end() const;
+        
     private:
-
         void route(detail::StreamBase const * stream, detail::AreaBase const * area, 
-                   unsigned level, action_t action);
+                   unsigned level, action_t action, int index);
         void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, 
                      unsigned level, action_t action);
 
-        template <class Area>
-        void route(detail::StreamBase const * stream, detail::AreaBase const *, action_t action);
+        template <class Area> void route(detail::StreamBase const * stream, 
+                                         detail::AreaBase const *, action_t action, int index);
+        template <class Level> void route(detail::StreamBase const * stream, 
+                                          detail::LevelBase const *, action_t action, int index);
 
-        template <class Level>
-        void route(detail::StreamBase const * stream, detail::LevelBase const *, action_t action);
+        template <class Area> void unroute(detail::StreamBase const * stream, 
+                                           detail::AreaBase const *, action_t action);
+        template <class Level> void unroute(detail::StreamBase const * stream, 
+                                          detail::LevelBase const *, action_t action);
         
         void updateRoutingCache(detail::StreamBase const * stream, detail::AreaBase const * area);
 
@@ -128,21 +159,6 @@ namespace log {
     private:
 #   endif
 
-        struct RoutingEntry 
-        {
-            RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_, 
-                         unsigned level_, action_t action_);
-            RoutingEntry();
-
-            bool operator==(RoutingEntry const & other);
-
-            detail::StreamBase const * stream;
-            detail::AreaBase const * area;
-            unsigned level;            action_t action;
-        };
-
-        typedef std::vector<RoutingEntry> RIB;
-
         RIB rib_;
         
         friend class detail::AreaBase;