mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 03:53:52 +02:00
adds optional LogStream for cpp iostream-style logging
This commit is contained in:
parent
e55863a662
commit
493fafb213
1 changed files with 106 additions and 0 deletions
106
interface/src/LogStream.h
Normal file
106
interface/src/LogStream.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// LogStream.h
|
||||
// interface
|
||||
//
|
||||
// Created by Tobias Schwinger on 4/17/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__LogStream__
|
||||
#define __interface__LogStream__
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
//
|
||||
// Makes the logging facility accessible as a C++ stream.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // somewhere central - ideally one per thread (else pass 'true' as
|
||||
// // second constructor argument and compromise some efficiency)
|
||||
// LogStream lOut(printLog);
|
||||
//
|
||||
// // elsewhere:
|
||||
// lOut << "Hello there!" << std::endl;
|
||||
//
|
||||
class LogStream {
|
||||
std::ostringstream _objOutStream;
|
||||
Log& _refLog;
|
||||
bool _flgThreadSafe;
|
||||
public:
|
||||
inline LogStream(Log& log, bool threadSafe = false);
|
||||
|
||||
class StreamRef; friend class StreamRef;
|
||||
|
||||
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
|
||||
|
||||
private:
|
||||
// don't
|
||||
LogStream(LogStream const&); // = delete;
|
||||
LogStream& operator=(LogStream const&); // = delete;
|
||||
|
||||
inline void ostreamBegin();
|
||||
inline void ostreamEnd();
|
||||
};
|
||||
|
||||
inline LogStream::LogStream(Log& log, bool threadSafe) :
|
||||
_objOutStream(std::ios_base::out), _refLog(log), _flgThreadSafe(threadSafe) { }
|
||||
|
||||
inline void LogStream::ostreamBegin() {
|
||||
|
||||
if (_flgThreadSafe) {
|
||||
// the user wants to share this LogStream among threads,
|
||||
// so lock the global log here, already
|
||||
pthread_mutex_lock(& _refLog._mtx);
|
||||
}
|
||||
_objOutStream.str("");
|
||||
}
|
||||
|
||||
inline void LogStream::ostreamEnd() {
|
||||
|
||||
if (! _flgThreadSafe) {
|
||||
// haven't locked, so far (we have memory for each thread)
|
||||
pthread_mutex_lock(& _refLog._mtx);
|
||||
}
|
||||
_refLog.addMessage(_objOutStream.str().c_str());
|
||||
pthread_mutex_unlock(& _refLog._mtx);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// The Log::StreamRef class makes operator<< work. It...
|
||||
//
|
||||
class LogStream::StreamRef {
|
||||
mutable LogStream* _ptrLogStream;
|
||||
typedef std::ostream& (*manipulator)(std::ostream&);
|
||||
|
||||
friend class LogStream;
|
||||
|
||||
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
|
||||
StreamRef(LogStream* log) : _ptrLogStream(log) { }
|
||||
public:
|
||||
// ...forwards << operator calls to stringstream...
|
||||
template< typename T > StreamRef const operator<<(T const& x) const { _ptrLogStream->_objOutStream << x; return *this; }
|
||||
// ...has to dance around to make manipulators (such as std::hex, std::endl) work...
|
||||
StreamRef const operator<<(manipulator x) const { _ptrLogStream->_objOutStream << x; return *this; }
|
||||
// ...informs the logger that a stream has ended when it has the responsibility...
|
||||
~StreamRef() { if (_ptrLogStream != 0l) { _ptrLogStream->ostreamEnd(); } }
|
||||
// ...which is passed on upon copy.
|
||||
StreamRef(StreamRef const& other) : _ptrLogStream(other._ptrLogStream) { other._ptrLogStream = 0l; }
|
||||
|
||||
private:
|
||||
// don't
|
||||
StreamRef& operator=(StreamRef const&); // = delete;
|
||||
};
|
||||
|
||||
template< typename T > inline LogStream::StreamRef const operator<<(LogStream& s, T const& x) {
|
||||
|
||||
s.ostreamBegin();
|
||||
s._objOutStream << x;
|
||||
return LogStream::StreamRef(& s); // calls streamEnd at the end of the stream expression
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue