- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# XMLLogPrinter.h

Go to the documentation of this file.

    00001
    00015 #pragma once
    00016
    00017 #include "GenericLogPrinter.h"
    00018 #include "LogContentsPrinter.h"
    00019 #include "Loggable.h"
    00020 #include "CompositeLoggable.h"
    00021 #include "LogInfo.h"
    00022 #include "RegistryKey.h"
    00023
    00024 #include "TStd.h"
    00025 #include "TBoostFormat.h"
    00026
    00027 #include <boost/utility.hpp>
    00028
    00029 #define LOGGING_KEYNAME_MAX_PRINTING_DEPTH _T("MaxPrintingDepth")
    00030
    00031 namespace Nvidia {
    00032 namespace Logging {
    00033
    00037 class XMLNode
    00038 {
    00039 private:
    00041     std::tstring m_name;
    00042
    00044     std::vector<XMLNode> m_subNodes;
    00045
    00047     std::vector<std::pair<std::tstring, std::tstring> > m_attributes;
    00048
    00049 public:
    00051     XMLNode(const std::tstring& name);
    00052
    00054     XMLNode& AddSubNode(const std::tstring& name);
    00055
    00057     void AddAttribute(const std::tstring& name, const std::tstring& value);
    00058
    00066     void PrintOn(std::tostringstream& stream, unsigned int indentLevel = 0);
    00067 };
    00068
    00073 class XMLContentsPrinter : public LogContentsPrinter, private boost::noncopyable
    00074 {
    00075 private:
    00077     std::vector<XMLNode*> m_xmlNodeStack;
    00079     unsigned int m_maxPrintingDepth;
    00080
    00081 public:
    00083     XMLContentsPrinter(unsigned int maxPrintingDepth);
    00084
    00091     void LogContentInternal(const std::tstring& name, const SimpleLoggable& loggable);
    00092
    00100     void LogContentInternal(const std::tstring& name, const CompositeLoggable& loggable);
    00101
    00103     void SetRootXMLNode(XMLNode& node);
    00104 };
    00105
    00133 class XMLLogPrinter : public GenericLogPrinter<std::tstring>
    00134 {
    00135 private:
    00136     XMLContentsPrinter m_xmlContentsPrinter;
    00137
    00138 public:
    00140     XMLLogPrinter();
    00141
    00145     XMLLogPrinter(const RegistryKey& key);
    00146
    00147 private:
    00153     std::tstring DoFormatMessage(const LogInfo& logInfo, const CompositeLoggable& message);
    00154 };
    00155
    00156 inline XMLNode::XMLNode(const std::tstring& name) :
    00157     m_name(name) {}
    00158
    00159 inline XMLNode& XMLNode::AddSubNode(const std::tstring& name)
    00160 {
    00161     m_subNodes.push_back(XMLNode(name));
    00162     return m_subNodes.back();
    00163 }
    00164
    00165 inline void XMLNode::AddAttribute(const std::tstring& name, const std::tstring& value)
    00166 {
    00167     m_attributes.push_back(std::make_pair(name, value));
    00168 }
    00169
    00170 inline void XMLNode::PrintOn(std::tostringstream& stream, unsigned int indentLevel)
    00171 {
    00172     for ( unsigned int i = 0 ; i < indentLevel ; i++ )
    00173         stream << _T("    ");
    00174
    00175     stream << _T("<") << m_name;
    00176     std::pair<std::tstring, std::tstring> attribute;
    00177
    00178     BOOST_FOREACH(attribute, m_attributes)
    00179     {
    00180         stream << _T(" ") << attribute.first << _T("=\"") << attribute.second << _T("\"") ;
    00181     }
    00182
    00183     if ( m_subNodes.size() == 0 )
    00184     {
    00185         stream << _T("/>");
    00186     }
    00187     else
    00188     {
    00189         stream << _T(">") << std::endl;
    00190
    00191         // We need to operate on references to XMLNode%s to avoid excessive copying
    00192         for ( size_t i = 0 ; i < m_subNodes.size() ; i++ )
    00193         {
    00194             m_subNodes[i].PrintOn(stream, indentLevel + 1);
    00195         }
    00196
    00197         for ( unsigned int i = 0 ; i < indentLevel ; i++ )
    00198             stream << _T("    ");
    00199
    00200         stream << _T("</") << m_name << _T(">");
    00201     }
    00202
    00203     if ( indentLevel > 0 )
    00204         stream << std::endl;
    00205 }
    00206
    00207 inline XMLContentsPrinter::XMLContentsPrinter(unsigned int maxPrintingDepth) :
    00208     m_maxPrintingDepth(maxPrintingDepth) {}
    00209
    00210 inline void XMLContentsPrinter::LogContentInternal(const std::tstring& name, const SimpleLoggable& loggable)
    00211 {
    00212     if ( name == _T("id") )
    00213     {
    00214         m_xmlNodeStack.back()->AddAttribute(name, loggable.GetStringValue());
    00215     }
    00216     else
    00217     {
    00218         XMLNode& currentNode = m_xmlNodeStack.back()->AddSubNode(loggable.GetHumanReadableTypeName());
    00219         if ( name.length() > 0 )
    00220             currentNode.AddAttribute(_T("field"), name);
    00221         currentNode.AddAttribute(_T("value"), loggable.GetStringValue());
    00222     }
    00223 }
    00224
    00225 inline void XMLContentsPrinter::LogContentInternal(const std::tstring& name, const CompositeLoggable& loggable)
    00226 {
    00227     XMLNode& currentNode = m_xmlNodeStack.back()->AddSubNode(loggable.GetHumanReadableTypeName());
    00228     if ( name.length() > 0 )
    00229         currentNode.AddAttribute(_T("field"), name);
    00230
    00231     m_xmlNodeStack.push_back(&currentNode);
    00232     if ( m_xmlNodeStack.size() <= m_maxPrintingDepth )
    00233         loggable.LogContentsOn(*this);
    00234     m_xmlNodeStack.pop_back();
    00235 }
    00236
    00237 inline void XMLContentsPrinter::SetRootXMLNode(XMLNode& node)
    00238 {
    00239     m_xmlNodeStack.clear();
    00240     m_xmlNodeStack.push_back(&node);
    00241 }
    00242
    00243 inline XMLLogPrinter::XMLLogPrinter() : m_xmlContentsPrinter(5) {}
    00244
    00245 inline XMLLogPrinter::XMLLogPrinter(const RegistryKey& key) :
    00246     m_xmlContentsPrinter(key.GetDWORDValue(LOGGING_KEYNAME_MAX_PRINTING_DEPTH)) {}
    00247
    00248 inline std::tstring XMLLogPrinter::DoFormatMessage(const LogInfo& logInfo, const CompositeLoggable& message)
    00249 {
    00250     XMLNode messageNode(boost::lexical_cast<std::tstring>(logInfo.GetLevel()));
    00251
    00252     messageNode.AddAttribute(_T("timestamp"), boost::lexical_cast<std::tstring>(logInfo.GetAbsoluteTimestamp()));
    00253     messageNode.AddAttribute(_T("msg"), message.GetStringValue());
    00254     messageNode.AddAttribute(_T("origin"), logInfo.GetScopeLoggerName());
    00255     messageNode.AddAttribute(_T("function"), logInfo.GetFunctionName());
    00256     messageNode.AddAttribute(_T("file"), logInfo.GetFileName());
    00257     messageNode.AddAttribute(_T("line"), boost::lexical_cast<std::tstring>(logInfo.GetLineNumber()));
    00258
    00259     m_xmlContentsPrinter.SetRootXMLNode(messageNode);
    00260     message.LogContentsOn(m_xmlContentsPrinter);
    00261
    00262     std::tostringstream stream;
    00263     messageNode.PrintOn(stream);
    00264     return stream.str();
    00265 }
    00266
    00267
    00268 }
    00269 }