Tracer.h
// Tracer.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2004
#pragma once
#ifndef Ceda_cxUtils_Tracer_H
#define Ceda_cxUtils_Tracer_H
#include "cxUtils.h"
#include "xstring.h"
#include "StringStream.h"
namespace ceda
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// TraceIndenter
cxUtils_API void IndentTrace(ssize_t offset);
// Number of space characters to indent the trace file
const ssize_t DEFAULT_TRACE_INDENTATION = 2;
struct cxUtils_API TraceIndenter
{
TraceIndenter(ssize_t indentation = DEFAULT_TRACE_INDENTATION);
~TraceIndenter();
ssize_t m_indentation;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
cxUtils_API void ClearTheTraceFile();
/*
todo: support setting the format of the file. E.g.
UTF-8 with BOM
UTF-8 without BOM
UTF-16(BE) with BOM
UTF-16(BE) without BOM
UTF-16(LE) with BOM
UTF-16(LE) without BOM
returns true if the file was opened correctly (or stdout is used), false if it failed to
open the file. If it returns true it cannot be called again.
*/
cxUtils_API bool SetTraceFile(const xstring& path, bool appendToExistingFile, bool traceTime);
// returns true if SetTraceFile has already been called and succeeded
cxUtils_API bool TraceFileIsOpen();
cxUtils_API void DestroyTheTraceFile();
cxUtils_API void Trace(const xstring& s);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Tracer
struct cxUtils_API TracerX : public StringStream
{
~TracerX();
TracerX& ref() { return *this; }
};
/*
todo: At warning level 4 this generates
warning C4239: nonstandard extension used : 'type cast' : conversion from 'ceda::TracerX' to
'ceda::TracerX &'
A non-const reference may only be bound to an lvalue
*/
#define Tracer() ceda::TracerX().ref()
///////////////////////////////////////////////////////////////////////////////////////////////////
struct ITraceObserver
{
virtual void OnTrace(const xstring& str) = 0;
};
cxUtils_API void SetTraceObserver(ITraceObserver* obs);
cxUtils_API ITraceObserver* GetTraceObserver();
struct cxUtils_API ScopedTraceObserver
{
ceda::ITraceObserver* prev_;
ScopedTraceObserver( ITraceObserver* o )
{
prev_ = ceda::GetTraceObserver();
SetTraceObserver( o );
}
~ScopedTraceObserver()
{
// restore the previous trace observer
SetTraceObserver( prev_ );
}
};
class cxUtils_API StreamTraceObserver : public ITraceObserver
{
ITraceObserver* prev_;
StringStream m_ss;
public:
// supply a non-nullptr ITraceObserver to create a chain
StreamTraceObserver( ITraceObserver* prev ) : prev_( prev ) {}
virtual void OnTrace(const xstring& str)
{
m_ss << str;
if( prev_ ) prev_->OnTrace( str );
}
StringStream& GetStream()
{
return m_ss;
}
xstring GetString()
{
return m_ss.GetString();
}
};
} // namespace ceda
#endif // include guard