gfx/2d/Logging.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef MOZILLA_GFX_LOGGING_H_
michael@0 7 #define MOZILLA_GFX_LOGGING_H_
michael@0 8
michael@0 9 #include <string>
michael@0 10 #include <sstream>
michael@0 11 #include <stdio.h>
michael@0 12
michael@0 13 #include "nsDebug.h"
michael@0 14 #include "Point.h"
michael@0 15 #include "BaseRect.h"
michael@0 16 #include "Matrix.h"
michael@0 17 #include "mozilla/TypedEnum.h"
michael@0 18
michael@0 19 #ifdef WIN32
michael@0 20 // This file gets included from nsGlobalWindow.cpp, which doesn't like
michael@0 21 // having windows.h included in it. Since OutputDebugStringA is the only
michael@0 22 // thing we need from windows.h, we just declare it here directly.
michael@0 23 // Note: the function's documented signature is
michael@0 24 // WINBASEAPI void WINAPI OutputDebugStringA(LPCSTR lpOutputString)
michael@0 25 // but if we don't include windows.h, the macros WINBASEAPI, WINAPI, and
michael@0 26 // LPCSTR are not defined, so we need to replace them with their expansions.
michael@0 27 extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
michael@0 28 #endif
michael@0 29
michael@0 30 #if defined(DEBUG) || defined(PR_LOGGING)
michael@0 31 #include <prlog.h>
michael@0 32
michael@0 33 extern GFX2D_API PRLogModuleInfo *GetGFX2DLog();
michael@0 34 #endif
michael@0 35
michael@0 36 namespace mozilla {
michael@0 37 namespace gfx {
michael@0 38
michael@0 39 const int LOG_DEBUG = 1;
michael@0 40 const int LOG_WARNING = 2;
michael@0 41
michael@0 42 #if defined(DEBUG) || defined(PR_LOGGING)
michael@0 43
michael@0 44 inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) {
michael@0 45 switch (aLevel) {
michael@0 46 case LOG_DEBUG:
michael@0 47 return PR_LOG_DEBUG;
michael@0 48 case LOG_WARNING:
michael@0 49 return PR_LOG_WARNING;
michael@0 50 }
michael@0 51 return PR_LOG_DEBUG;
michael@0 52 }
michael@0 53
michael@0 54 #endif
michael@0 55
michael@0 56 extern GFX2D_API int sGfxLogLevel;
michael@0 57
michael@0 58 static inline void OutputMessage(const std::string &aString, int aLevel) {
michael@0 59 #if defined(WIN32) && !defined(PR_LOGGING)
michael@0 60 if (aLevel >= sGfxLogLevel) {
michael@0 61 ::OutputDebugStringA(aString.c_str());
michael@0 62 }
michael@0 63 #elif defined(PR_LOGGING) && !(defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID))
michael@0 64 if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) {
michael@0 65 PR_LogPrint(aString.c_str());
michael@0 66 }
michael@0 67 #else
michael@0 68 if (aLevel >= sGfxLogLevel) {
michael@0 69 printf_stderr("%s", aString.c_str());
michael@0 70 }
michael@0 71 #endif
michael@0 72 }
michael@0 73
michael@0 74 class NoLog
michael@0 75 {
michael@0 76 public:
michael@0 77 NoLog() {}
michael@0 78 ~NoLog() {}
michael@0 79
michael@0 80 template<typename T>
michael@0 81 NoLog &operator <<(const T &aLogText) { return *this; }
michael@0 82 };
michael@0 83
michael@0 84 MOZ_BEGIN_ENUM_CLASS(LogOptions, int)
michael@0 85 NoNewline = 0x01
michael@0 86 MOZ_END_ENUM_CLASS(LogOptions)
michael@0 87
michael@0 88 template<int L>
michael@0 89 class Log
michael@0 90 {
michael@0 91 public:
michael@0 92 Log(LogOptions aOptions = LogOptions(0)) : mOptions(aOptions) {}
michael@0 93 ~Log() {
michael@0 94 Flush();
michael@0 95 }
michael@0 96
michael@0 97 void Flush() {
michael@0 98 if (!(int(mOptions) & int(LogOptions::NoNewline))) {
michael@0 99 mMessage << '\n';
michael@0 100 }
michael@0 101 std::string str = mMessage.str();
michael@0 102 if (!str.empty()) {
michael@0 103 WriteLog(str);
michael@0 104 }
michael@0 105 mMessage.str("");
michael@0 106 mMessage.clear();
michael@0 107 }
michael@0 108
michael@0 109 Log &operator <<(char aChar) { mMessage << aChar; return *this; }
michael@0 110 Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; }
michael@0 111 Log &operator <<(const char aStr[]) { mMessage << static_cast<const char*>(aStr); return *this; }
michael@0 112 Log &operator <<(bool aBool) { mMessage << (aBool ? "true" : "false"); return *this; }
michael@0 113 Log &operator <<(int aInt) { mMessage << aInt; return *this; }
michael@0 114 Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; }
michael@0 115 Log &operator <<(long aLong) { mMessage << aLong; return *this; }
michael@0 116 Log &operator <<(unsigned long aLong) { mMessage << aLong; return *this; }
michael@0 117 Log &operator <<(long long aLong) { mMessage << aLong; return *this; }
michael@0 118 Log &operator <<(unsigned long long aLong) { mMessage << aLong; return *this; }
michael@0 119 Log &operator <<(Float aFloat) { mMessage << aFloat; return *this; }
michael@0 120 Log &operator <<(double aDouble) { mMessage << aDouble; return *this; }
michael@0 121 template <typename T, typename Sub>
michael@0 122 Log &operator <<(const BasePoint<T, Sub>& aPoint)
michael@0 123 { mMessage << "Point(" << aPoint.x << "," << aPoint.y << ")"; return *this; }
michael@0 124 template <typename T, typename Sub>
michael@0 125 Log &operator <<(const BaseSize<T, Sub>& aSize)
michael@0 126 { mMessage << "Size(" << aSize.width << "," << aSize.height << ")"; return *this; }
michael@0 127 template <typename T, typename Sub, typename Point, typename SizeT, typename Margin>
michael@0 128 Log &operator <<(const BaseRect<T, Sub, Point, SizeT, Margin>& aRect)
michael@0 129 { mMessage << "Rect(" << aRect.x << "," << aRect.y << "," << aRect.width << "," << aRect.height << ")"; return *this; }
michael@0 130 Log &operator<<(const Matrix& aMatrix)
michael@0 131 { mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")"; return *this; }
michael@0 132
michael@0 133
michael@0 134 private:
michael@0 135
michael@0 136 void WriteLog(const std::string &aString) {
michael@0 137 OutputMessage(aString, L);
michael@0 138 }
michael@0 139
michael@0 140 std::stringstream mMessage;
michael@0 141 LogOptions mOptions;
michael@0 142 };
michael@0 143
michael@0 144 typedef Log<LOG_DEBUG> DebugLog;
michael@0 145 typedef Log<LOG_WARNING> WarningLog;
michael@0 146
michael@0 147 #ifdef GFX_LOG_DEBUG
michael@0 148 #define gfxDebug DebugLog
michael@0 149 #else
michael@0 150 #define gfxDebug if (1) ; else NoLog
michael@0 151 #endif
michael@0 152 #ifdef GFX_LOG_WARNING
michael@0 153 #define gfxWarning WarningLog
michael@0 154 #else
michael@0 155 #define gfxWarning if (1) ; else NoLog
michael@0 156 #endif
michael@0 157
michael@0 158 const int INDENT_PER_LEVEL = 2;
michael@0 159
michael@0 160 class TreeLog
michael@0 161 {
michael@0 162 public:
michael@0 163 TreeLog(const std::string& aPrefix = "")
michael@0 164 : mLog(LogOptions::NoNewline),
michael@0 165 mPrefix(aPrefix),
michael@0 166 mDepth(0),
michael@0 167 mStartOfLine(true),
michael@0 168 mConditionedOnPref(false),
michael@0 169 mPref(nullptr) {}
michael@0 170
michael@0 171 template <typename T>
michael@0 172 TreeLog& operator<<(const T& aObject) {
michael@0 173 if (mConditionedOnPref && !*mPref) {
michael@0 174 return *this;
michael@0 175 }
michael@0 176 if (mStartOfLine) {
michael@0 177 mLog << '[' << mPrefix << "] " << std::string(mDepth * INDENT_PER_LEVEL, ' ');
michael@0 178 mStartOfLine = false;
michael@0 179 }
michael@0 180 mLog << aObject;
michael@0 181 if (EndsInNewline(aObject)) {
michael@0 182 // Don't indent right here as the user may change the indent
michael@0 183 // between now and the first output to the next line.
michael@0 184 mLog.Flush();
michael@0 185 mStartOfLine = true;
michael@0 186 }
michael@0 187 return *this;
michael@0 188 }
michael@0 189
michael@0 190 void IncreaseIndent() { ++mDepth; }
michael@0 191 void DecreaseIndent() { --mDepth; }
michael@0 192
michael@0 193 void ConditionOnPref(bool* aPref) {
michael@0 194 mConditionedOnPref = true;
michael@0 195 mPref = aPref;
michael@0 196 }
michael@0 197 private:
michael@0 198 Log<LOG_DEBUG> mLog;
michael@0 199 std::string mPrefix;
michael@0 200 uint32_t mDepth;
michael@0 201 bool mStartOfLine;
michael@0 202 bool mConditionedOnPref;
michael@0 203 bool* mPref;
michael@0 204
michael@0 205 template <typename T>
michael@0 206 static bool EndsInNewline(const T& aObject) {
michael@0 207 return false;
michael@0 208 }
michael@0 209
michael@0 210 static bool EndsInNewline(const std::string& aString) {
michael@0 211 return !aString.empty() && aString[aString.length() - 1] == '\n';
michael@0 212 }
michael@0 213
michael@0 214 static bool EndsInNewline(char aChar) {
michael@0 215 return aChar == '\n';
michael@0 216 }
michael@0 217
michael@0 218 static bool EndsInNewline(const char* aString) {
michael@0 219 return EndsInNewline(std::string(aString));
michael@0 220 }
michael@0 221 };
michael@0 222
michael@0 223 class TreeAutoIndent
michael@0 224 {
michael@0 225 public:
michael@0 226 TreeAutoIndent(TreeLog& aTreeLog) : mTreeLog(aTreeLog) {
michael@0 227 mTreeLog.IncreaseIndent();
michael@0 228 }
michael@0 229 ~TreeAutoIndent() {
michael@0 230 mTreeLog.DecreaseIndent();
michael@0 231 }
michael@0 232 private:
michael@0 233 TreeLog& mTreeLog;
michael@0 234 };
michael@0 235
michael@0 236 }
michael@0 237 }
michael@0 238
michael@0 239 #endif /* MOZILLA_GFX_LOGGING_H_ */

mercurial