From ebb2a1fe6f77fad9eff6653b28d2866c54d8e3ac Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 20:14:47 -0500 Subject: [PATCH] Bug 958596 - Add support a tree logging utility. r=Bas --- gfx/2d/Logging.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 8eae4937386d..07326e3cbf24 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -91,9 +91,19 @@ class Log public: Log(LogOptions aOptions = LogOptions(0)) : mOptions(aOptions) {} ~Log() { - if (!(int(mOptions) & int(LogOptions::NoNewline))) + Flush(); + } + + void Flush() { + if (!(int(mOptions) & int(LogOptions::NoNewline))) { mMessage << '\n'; - WriteLog(mMessage.str()); + } + std::string str = mMessage.str(); + if (!str.empty()) { + WriteLog(str); + } + mMessage.str(""); + mMessage.clear(); } Log &operator <<(char aChar) { mMessage << aChar; return *this; } @@ -143,6 +153,72 @@ typedef Log WarningLog; #define gfxWarning if (1) ; else NoLog #endif +const int INDENT_PER_LEVEL = 2; + +class TreeLog +{ +public: + TreeLog(const std::string& aPrefix = "") + : mLog(LogOptions::NoNewline), + mPrefix(aPrefix), + mDepth(0), + mStartOfLine(true) {} + + template + TreeLog& operator<<(const T& aObject) { + if (mStartOfLine) { + mLog << '[' << mPrefix << "] " << std::string(mDepth * INDENT_PER_LEVEL, ' '); + mStartOfLine = false; + } + mLog << aObject; + if (EndsInNewline(aObject)) { + // Don't indent right here as the user may change the indent + // between now and the first output to the next line. + mLog.Flush(); + mStartOfLine = true; + } + return *this; + } + + void IncreaseIndent() { ++mDepth; } + void DecreaseIndent() { --mDepth; } +private: + Log mLog; + std::string mPrefix; + uint32_t mDepth; + bool mStartOfLine; + + template + static bool EndsInNewline(const T& aObject) { + return false; + } + + static bool EndsInNewline(const std::string& aString) { + return !aString.empty() && aString[aString.length() - 1] == '\n'; + } + + static bool EndsInNewline(char aChar) { + return aChar == '\n'; + } + + static bool EndsInNewline(const char* aString) { + return EndsInNewline(std::string(aString)); + } +}; + +class TreeAutoIndent +{ +public: + TreeAutoIndent(TreeLog& aTreeLog) : mTreeLog(aTreeLog) { + mTreeLog.IncreaseIndent(); + } + ~TreeAutoIndent() { + mTreeLog.DecreaseIndent(); + } +private: + TreeLog& mTreeLog; +}; + } }