Socket/Protocols/Raw: EUI64 documentation
[senf.git] / Utils / Logger / Target.ih
index ed208de..4b81e2e 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
-// Copyright (C) 2007 
-// Fraunhofer Institute for Open Communication Systems (FOKUS) 
-// Competence Center NETwork research (NET), St. Augustin, GERMANY 
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 /** \file
     \brief Target internal header */
 
-#ifndef IH_Target_
-#define IH_Target_ 1
+#ifndef IH_SENF_Utils_Logger_Target_
+#define IH_SENF_Utils_Logger_Target_ 1
 
 // Custom includes
 #include <memory>
-#include <boost/scoped_ptr.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
+#include "../Console/LazyDirectory.hh"
+#include "../Console/Parse.hh"
 
 ///////////////////////////////ih.p////////////////////////////////////////
 
 namespace senf {
+
+    namespace console { class DirectoryNode; }
+
 namespace log {
 namespace detail {
 
+    struct LogParameters {
+        StreamBase const * stream;
+        AreaBase const * area;
+        unsigned level;
+        void clear();
+        void setDefaults();
+        static LogParameters defaultParameters();
+    };
+
+    std::ostream & operator<<(std::ostream & os, LogParameters const & pm);
+
+    void senf_console_parse_argument(console::ParseCommandInfo::TokensRange const & tokens, 
+                                     LogParameters & out);
+
     /** \brief Internal: Target registry */
     class TargetRegistry
         : public senf::singleton<TargetRegistry>
     {
     public:
+        enum Level { 
+            VERBOSE = senf::log::VERBOSE::value, 
+            NOTICE = senf::log::NOTICE::value, 
+            MESSAGE = senf::log::MESSAGE::value, 
+            IMPORTANT = senf::log::IMPORTANT::value, 
+            CRITICAL = senf::log::CRITICAL::value, 
+            FATAL = senf::log::FATAL::value
+        };
+
         using senf::singleton<TargetRegistry>::instance;
 
         void write(StreamBase const & stream, AreaBase const & area, unsigned level, 
-                   std::string msg);
-
-        void timeSource(std::auto_ptr<TimeSource> source);
+                   std::string const & msg);
 
         void routed();
         bool fallbackRouting();
 
+        senf::console::ScopedDirectory<> & consoleDir();
+
+        void dynamicTarget(std::auto_ptr<Target> target);
+
     private:
         TargetRegistry();
+        ~TargetRegistry();
         
-        void registerTarget(Target * target);
+        void registerTarget(Target * target, std::string const & name);
         void unregisterTarget(Target * target);
 
+        void consoleAreas(std::ostream & os);
+        void consoleStreams(std::ostream & os);
+        void consoleWrite(LogParameters parameters, std::string const & msg);
+        void consoleRemoveTarget(Target * target);
+        boost::shared_ptr<senf::console::DirectoryNode> consoleSelf(std::ostream & os);
+
         typedef std::set<Target *> Targets;
         Targets targets_;
-        boost::scoped_ptr<TimeSource> timeSource_;
 
         bool fallbackRouting_;
+
+        console::LazyDirectory consoleDir_;
+
+        Targets dynamicTargets_;
         
         friend class senf::log::Target;
         friend class senf::singleton<TargetRegistry>;
@@ -69,7 +111,92 @@ namespace detail {
 
     /** \brief Internal: Write log message */
     template <class Stream, class Area, class Level>
-    void write(std::string msg);
+    void write(std::string const & msg);
+
+#ifndef DOXYGEN
+
+    // This code takes the routing target template arguments in any order and sorts them 
+    // by type (Stream, Area and Level).
+
+    senf::mpl::rv<0u> RouteParameterCheck_(...);
+    senf::mpl::rv<1u> RouteParameterCheck_(StreamBase *);
+    senf::mpl::rv<2u> RouteParameterCheck_(AreaBase *);
+    template <class T> senf::mpl::rv<3u> RouteParameterCheck_(T*, typename T::SENFLogArea * = 0);
+    senf::mpl::rv<4u> RouteParameterCheck_(LevelBase *);
+
+    // For g++ 4.0 (at least) we need to provide the fully scoped name for this default value.
+    // no idea why. It works without the scope in 4.1
+    template < class T, class A2, class A1,
+               unsigned type = SENF_MPL_RV( senf::log::detail::RouteParameterCheck_(static_cast<T*>(0)) ) >
+    struct RouteParameters
+    {};
+
+    template <class A2, class A1>
+    struct RouteParameters<mpl::nil,A2,A1,0u>
+        : public RouteParameters<A2,A1,mpl::nil>
+    {};
+
+    struct NilLevel {
+        static unsigned const value = NONE::value;
+    };
+
+    template <>
+    struct RouteParameters<mpl::nil,mpl::nil,mpl::nil,0u>
+    {
+        typedef mpl::nil Stream;
+        typedef mpl::nil Area;
+        typedef NilLevel Level;
+    };
+
+    template <class T, class A2, class A1>
+    struct RouteParameters<T,A2,A1,1u>
+        : public RouteParameters<A2,A1,mpl::nil>
+    {
+        typedef RouteParameters<A2,A1,mpl::nil> base;
+        BOOST_STATIC_ASSERT(( boost::is_same<typename base::Stream, mpl::nil>::value ));
+        typedef T Stream;
+    };
+
+    template <class T, class A2, class A1>
+    struct RouteParameters<T,A2,A1,2u>
+        : public RouteParameters<A2,A1,mpl::nil>
+    {
+        typedef RouteParameters<A2,A1,mpl::nil> base;
+        BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
+        typedef T Area;
+    };
+
+    template <class T, class A2, class A1>
+    struct RouteParameters<T,A2,A1,3u>
+        : public RouteParameters<A2,A1,mpl::nil>
+    {
+        typedef RouteParameters<A2,A1,mpl::nil> base;
+        BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
+        typedef typename T::SENFLogArea Area;
+    };
+
+    template <class T, class A2, class A1>
+    struct RouteParameters<T,A2,A1,4u>
+        : public RouteParameters<A2,A1,mpl::nil>
+    {
+        typedef RouteParameters<A2,A1,mpl::nil> base;
+        BOOST_STATIC_ASSERT(( boost::is_same<typename base::Level, NilLevel>::value ));
+        typedef T Level;
+    };
+
+    template <class T, class RV>
+    struct InstanceP
+    {
+        static RV * value() { return & T::instance(); }
+    };
+
+    template <class RV>
+    struct InstanceP<mpl::nil, RV>
+    {
+        static RV * value() { return 0; }
+    };
+
+#endif
 
 }}}