1 // Created on: 2007-06-28 2 // Created by: OCC Team 3 // Copyright (c) 2007-2014 OPEN CASCADE SAS 4 // 5 // This file is part of Open CASCADE Technology software library. 6 // 7 // This library is free software; you can redistribute it and/or modify it under 8 // the terms of the GNU Lesser General Public License version 2.1 as published 9 // by the Free Software Foundation, with special exception defined in the file 10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 11 // distribution for complete text of the license and disclaimer of any warranty. 12 // 13 // Alternatively, this file may be used under the terms of Open CASCADE 14 // commercial license or contractual agreement. 15 16 #ifndef _Message_Messenger_HeaderFile 17 #define _Message_Messenger_HeaderFile 18 19 #include <Message_Gravity.hxx> 20 #include <Message_SequenceOfPrinters.hxx> 21 22 #include <TCollection_HAsciiString.hxx> 23 #include <TCollection_HExtendedString.hxx> 24 25 class Message_Printer; 26 27 // resolve name collisions with WinAPI headers 28 #ifdef AddPrinter 29 #undef AddPrinter 30 #endif 31 32 class Message_Messenger; 33 DEFINE_STANDARD_HANDLE(Message_Messenger, Standard_Transient) 34 35 //! Messenger is API class providing general-purpose interface for 36 //! libraries that may issue text messages without knowledge 37 //! of how these messages will be further processed. 38 //! 39 //! The messenger contains a sequence of "printers" which can be 40 //! customized by the application, and dispatches every received 41 //! message to all the printers. 42 //! 43 //! For convenience, a set of methods Send...() returning a string 44 //! stream buffer is defined for use of stream-like syntax with operator << 45 //! 46 //! Example: 47 //! ~~~~~ 48 //! Messenger->SendFail() << " Unknown fail at line " << aLineNo << " in file " << aFile; 49 //! ~~~~~ 50 //! 51 //! The message is sent to messenger on destruction of the stream buffer, 52 //! call to Flush(), or passing manipulator std::ends, std::endl, or std::flush. 53 //! Empty messages are not sent except if manipulator is used. 54 class Message_Messenger : public Standard_Transient 55 { 56 DEFINE_STANDARD_RTTIEXT(Message_Messenger, Standard_Transient) 57 public: 58 //! Auxiliary class wrapping std::stringstream thus allowing constructing 59 //! message via stream interface, and putting result into its creator 60 //! Message_Messenger within destructor. 61 //! 62 //! It is intended to be used either as temporary object or as local 63 //! variable, note that content will be lost if it is copied. 64 class StreamBuffer 65 { 66 public: 67 68 //! Destructor flushing constructed message. ~StreamBuffer()69 ~StreamBuffer() { Flush(); } 70 71 //! Flush collected string to messenger Flush(Standard_Boolean doForce=Standard_False)72 void Flush(Standard_Boolean doForce = Standard_False) 73 { 74 myStream.flush(); 75 if (doForce || myStream.rdbuf()->in_avail() > 0) 76 { 77 if (myMessenger) 78 { 79 myMessenger->Send(myStream, myGravity); 80 } 81 myStream.str(std::string()); // empty the buffer for possible reuse 82 } 83 } 84 85 //! Formal copy constructor. 86 //! 87 //! Since buffer is intended for use as temporary object or local 88 //! variable, copy (or move) is needed only formally to be able to 89 //! return the new instance from relevant creation method. 90 //! In practice it should never be called because modern compilers 91 //! create such instances in place. 92 //! However note that if this constructor is called, the buffer 93 //! content (string) will not be copied (move is not supported for 94 //! std::stringstream class on old compilers such as gcc 4.4, msvc 9). StreamBuffer(const StreamBuffer & theOther)95 StreamBuffer (const StreamBuffer& theOther) 96 : myMessenger(theOther.myMessenger), myGravity(theOther.myGravity) 97 { 98 } 99 100 //! Wrapper for operator << of the stream 101 template <typename T> operator <<(const T & theArg)102 StreamBuffer& operator << (const T& theArg) 103 { 104 myStream << theArg; 105 return *this; 106 } 107 108 //! Operator << for manipulators of ostream (ends, endl, flush), 109 //! flushes the buffer (sends the message) operator <<(std::ostream & (*)(std::ostream &))110 StreamBuffer& operator << (std::ostream& (*)(std::ostream&)) 111 { 112 Flush(Standard_True); 113 return *this; 114 } 115 116 //! Access to the stream object Stream()117 Standard_SStream& Stream () { return myStream; } 118 119 //! Cast to OStream& operator Standard_OStream&()120 operator Standard_OStream& () { return myStream; } 121 122 //! Access to the messenger Messenger()123 Message_Messenger* Messenger () { return myMessenger; } 124 125 private: 126 friend class Message_Messenger; 127 128 //! Main constructor creating temporary buffer. 129 //! Accessible only to Messenger class. StreamBuffer(Message_Messenger * theMessenger,Message_Gravity theGravity)130 StreamBuffer (Message_Messenger* theMessenger, Message_Gravity theGravity) 131 : myMessenger (theMessenger), 132 myGravity (theGravity) 133 {} 134 135 private: 136 Message_Messenger* myMessenger; // don't make a Handle since this object should be created on stack 137 Message_Gravity myGravity; 138 Standard_SStream myStream; 139 }; 140 141 public: 142 143 //! Empty constructor; initializes by single printer directed to std::cout. 144 //! Note: the default messenger is not empty but directed to cout 145 //! in order to protect against possibility to forget defining printers. 146 //! If printing to cout is not needed, clear messenger by GetPrinters().Clear() 147 Standard_EXPORT Message_Messenger(); 148 149 //! Create messenger with single printer 150 Standard_EXPORT Message_Messenger(const Handle(Message_Printer)& thePrinter); 151 152 //! Add a printer to the messenger. 153 //! The printer will be added only if it is not yet in the list. 154 //! Returns True if printer has been added. 155 Standard_EXPORT Standard_Boolean AddPrinter (const Handle(Message_Printer)& thePrinter); 156 157 //! Removes specified printer from the messenger. 158 //! Returns True if this printer has been found in the list 159 //! and removed. 160 Standard_EXPORT Standard_Boolean RemovePrinter (const Handle(Message_Printer)& thePrinter); 161 162 //! Removes printers of specified type (including derived classes) 163 //! from the messenger. 164 //! Returns number of removed printers. 165 Standard_EXPORT Standard_Integer RemovePrinters (const Handle(Standard_Type)& theType); 166 167 //! Returns current sequence of printers Printers() const168 const Message_SequenceOfPrinters& Printers() const { return myPrinters; } 169 170 //! Returns sequence of printers 171 //! The sequence can be modified. ChangePrinters()172 Message_SequenceOfPrinters& ChangePrinters() { return myPrinters; } 173 174 //! Dispatch a message to all the printers in the list. 175 //! Three versions of string representations are accepted for 176 //! convenience, by default all are converted to ExtendedString. 177 Standard_EXPORT void Send (const Standard_CString theString, 178 const Message_Gravity theGravity = Message_Warning) const; 179 180 //! See above 181 Standard_EXPORT void Send (const Standard_SStream& theStream, 182 const Message_Gravity theGravity = Message_Warning) const; 183 184 //! See above 185 Standard_EXPORT void Send (const TCollection_AsciiString& theString, 186 const Message_Gravity theGravity = Message_Warning) const; 187 188 //! See above 189 Standard_EXPORT void Send (const TCollection_ExtendedString& theString, 190 const Message_Gravity theGravity = Message_Warning) const; 191 192 //! Create string buffer for message of specified type Send(Message_Gravity theGravity)193 StreamBuffer Send (Message_Gravity theGravity) { return StreamBuffer (this, theGravity); } 194 195 //! See above 196 Standard_EXPORT void Send (const Handle(Standard_Transient)& theObject, const Message_Gravity theGravity = Message_Warning) const; 197 198 //! Create string buffer for sending Fail message SendFail()199 StreamBuffer SendFail () { return Send (Message_Fail); } 200 201 //! Create string buffer for sending Alarm message SendAlarm()202 StreamBuffer SendAlarm () { return Send (Message_Alarm); } 203 204 //! Create string buffer for sending Warning message SendWarning()205 StreamBuffer SendWarning () { return Send (Message_Warning); } 206 207 //! Create string buffer for sending Info message SendInfo()208 StreamBuffer SendInfo () { return Send (Message_Info); } 209 210 //! Create string buffer for sending Trace message SendTrace()211 StreamBuffer SendTrace () { return Send (Message_Trace); } 212 213 //! Short-cut to Send (theMessage, Message_Fail) SendFail(const TCollection_AsciiString & theMessage)214 void SendFail (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Fail); } 215 216 //! Short-cut to Send (theMessage, Message_Alarm) SendAlarm(const TCollection_AsciiString & theMessage)217 void SendAlarm (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Alarm); } 218 219 //! Short-cut to Send (theMessage, Message_Warning) SendWarning(const TCollection_AsciiString & theMessage)220 void SendWarning (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Warning); } 221 222 //! Short-cut to Send (theMessage, Message_Info) SendInfo(const TCollection_AsciiString & theMessage)223 void SendInfo (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Info); } 224 225 //! Short-cut to Send (theMessage, Message_Trace) SendTrace(const TCollection_AsciiString & theMessage)226 void SendTrace (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Trace); } 227 228 //! Dumps the content of me into the stream 229 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; 230 231 private: 232 233 Message_SequenceOfPrinters myPrinters; 234 235 }; 236 237 #endif // _Message_Messenger_HeaderFile 238