Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
CConsoleStream

Introduction

p6loader, which is used to load all P6R component libraries, uses an p6IDataStream interface to write out all it's error and debug information. CConsoleStream is just a sample of an p6IDataStream implementation which writes this information to the console (via prinf()).

It's important to note that its methods can be called before p6Loader is initialized, and therefore, the implementation can not call any p6loader APIs

#ifndef CCONSOLESTREAM_H_
#define CCONSOLESTREAM_H_ 1
namespace {
//
// Simple p6IDataStream implementation which outputs
// data to stdout (via printf). This implementation
// is not thread-safe, but is adequate for this
// example.
//
class CConsoleStream : public P6R::p6IDataStream
{
public:
//
// Standard [p6]COM queryInterface() method.
//
{
const P6R::IID IID_p6ICom = IF_p6ICom;
const P6R::IID IID_p6IDataStream = IF_p6IDataStream;
if (!ppIface) return P6R::eAccessFault;
*ppIface = NULL;
if(iid == IID_p6ICom) *ppIface = static_cast<p6IDataStream*>(this);
else if(iid == IID_p6IDataStream) *ppIface = static_cast<p6IDataStream*>(this);
else return P6R::eNoInterface;
reinterpret_cast<p6ICom*>(*ppIface)->addref();
return P6R::eOk;
}
//
// Standard [p6]COM addref() method.
//
{
return m_cRef++;
}
//
// Standard [p6]COM release() method.
//
{
P6R::P6INT32 tmp = 0;
if(0 == (tmp = (--m_cRef))) { delete this; }
return tmp;
}
//
// beginStream() method prepares the stream for use.
//
{
return P6R::eOk;
}
//
// processStream() is call to pass data to the data stream.
// This method then performs it's stream specific
// operations on the data (in this case, writing it out
// to stdout).
//
// Since printf() requires an ASCIIZ string (NULL terminated string),
// this method first copies the data into a buffer and NULL
// terminates, then passes that to printf().
//
{
//
// Free the buffer if we do not have enough room
//
if (m_cBuffer && cData+1 > m_cBuffer)
{
free( m_pBuffer );
m_pBuffer = NULL;
m_cBuffer = 0;
}
//
// Allocate the buffer if not already allocated
//
if (!m_pBuffer)
{
m_pBuffer = (P6R::P6CHAR*) malloc(cData+1);
m_cBuffer = cData;
}
//
// Output the data to the console
//
if (m_pBuffer)
{
memcpy( m_pBuffer, pData, cData );
m_pBuffer[cData] = '\0';
printf( m_pBuffer );
}
return P6R::eOk;
}
//
// endStream() is called to notify the stream that there is
// no more data to be processed. In this simple case there is
// nothing to do.
//
P6COMMETHOD endStream() { return P6R::eOk; }
//
// This method creates a new uninitialized instance
// of our component and returns a pointer to the
// requested interface.
//
static P6R::P6ERR createInstance( P6R::p6ICom *pOuter, const P6R::IID &iid, P6R::P6VOID **ppIface )
{
P6R::P6ERR err = P6R::eNoMemory;
CConsoleStream *pObj = NULL;
if(NULL != pOuter) return P6R::eNoAgregation;
if(NULL == ppIface) return P6R::eAccessFault;
*ppIface = NULL;
if (NULL != (pObj = new (std::nothrow) CConsoleStream() ))
{
pObj->addref();
err = pObj->queryInterface( iid, ppIface );
pObj->release();
}
return err;
}
CConsoleStream() : m_cRef(0), m_pBuffer(NULL), m_cBuffer(0) {;}
virtual ~CConsoleStream() { if (m_pBuffer) free(m_pBuffer); }
protected:
P6R::P6INT32 m_cRef; // Holds the components reference count
P6R::P6CHAR *m_pBuffer; // A pointer to our output buffer.
P6R::P6UINT32 m_cBuffer; // The current size in characters of our output buffer
};
} // namespace
#endif