Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ex-json3.cpp
#include "p6loader.h"
#include "p6jsonreader.h"
#include "cconsolestream.h"
#include "ccontenthandler.h"
using namespace P6R;
using namespace P6EXAMPLES;
P6DECLARE_CID(p6JSONReader);
P6DECLARE_IID(IContentHandlerInit);
namespace {
P6R::P6ERR getContentHandler(p6IConsole *pConsole, p6ISafeString *pStr,p6IJSONContentHandler **ppIface)
{
P6ERR err;
if(!pStr) return eInvalidArg;
if(!ppIface) return eInvalidArg;
*ppIface = NULL;
//
// Create an instance of our content handler and initialize it.
// Once that's done we return the content handler's p6IJSONContentHandler
// interface to the caller. queryInterface() will automatically addref()
// the interface and it is the callers responsability to release() the
// interface when they are done with it. This behavior fallows the
// standard rule of COM.
//
if(P6SUCCEEDED(err = CContentHandler::createInstance(NULL,VALIDATECOMPTR(IContentHandlerInit,cpInit)))) {
if(P6SUCCEEDED(err = cpInit->initialize(pConsole,pStr))) {
err = cpInit.queryInterface(IID_p6IJSONContentHandler,ppIface);
}
}
return err;
}
P6R::P6ERR runJSON(p6IConsole *pConsole, p6IDataStream *pStreamDebug)
{
P6UINT32 bufSize = 0;
P6ERR err = eOk;
//
// Some simple JSON encoded data from json.org
//
const P6CHAR* pszTemp =
"{" \
"\"glossary\": {" \
" \"title\": \"example glossary\"," \
" \"GlossDiv\": {" \
" \"title\": \"S\"," \
" \"GlossList\": {" \
" \"GlossEntry\": {" \
" \"ID\": \"SGML\"," \
" \"SortAs\": \"SGML\"," \
" \"GlossTerm\": \"Standard Generalized Markup Language\"," \
" \"Acronym\": \"SGML\"," \
" \"Abbrev\": \"ISO 8879:1986\"," \
" \"GlossDef\": {" \
" \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\"," \
" \"GlossSeeAlso\": [\"GML\", \"XML\"]" \
" }," \
" \"GlossSee\": \"markup\"" \
" }" \
" }" \
" }" \
" }" \
"}}";
//
// Create and initialize the content handler
//
if(P6SUCCEEDED(err = getContentHandler(pConsole,cpStr,cpContent.addressof()))) {
//
// Create an instance of the JSN Parser, initialize it,
// and set the content handler to use.
//
if(P6SUCCEEDED(err = p6CreateInstance(NULL,CID_p6JSONReader,VALIDATECOMPTR(p6IJSONReader,cpReader)))) {
if(P6SUCCEEDED( err = cpReader->initialize(P6JSON_NOFLAGS,0))) {
if(P6SUCCEEDED( err = cpReader->setContentHandler(cpContent))) {
//
// Get the p6IDataStream interface that we will use to
// feed the JSON encoded data to the parser with.
//
if(P6SUCCEEDED(err = cpReader.queryInterface(IID_p6IDataStream,cpStream.addressof()))) {
//
// Tell the parser that we are about to
// send it data
//
if(P6SUCCEEDED(err = cpStream->beginStream())) {
//
// Get the length of the data. The second argument
// is provided to prevent over-running your buffer
// if you know its overall size. P6SAFESTR_MAX_CCH
// can be passed if you have no way of knowing the
// largest possible size. You should always try to
// provide a meaningful size here if you can.
//
cpStr->strlen(pszTemp,1024,&bufSize);
//
// Send the data to the parser. processStream()
// can be called over and over until all data
// has been sent to the parser (for example if the
// data was being read from a file or a socket).
// In this simple example, we are only sending it
// a single buffer of data.
//
err = cpStream->processStream(pszTemp,(P6UINT32)bufSize);
//
// endStream() must always be called, even if an
// error is received when calling processStream().
//
cpStream->endStream();
}
}
}
}
}
}
}
else {
P6ARG args[2];
//
// Of course in a real application, there would be error
// handling added to log/print all failures. Here, we
// have provided one example of using p6ErrToStr() to
// print an error.
//
P6AI_UINT32_HEXL(&args[0],err);
P6AI_ERR(&args[1],err);
pConsole->writeStdout("\nERROR: Unable to get runtime interface %1$ [ %2$ ]",&args[0],2,NULL);
}
//
// Also notice that since we are using p6ComPtr<> there is no
// need to call release() on each interface when we are done
// with them. The smart pointer handles that detail for us
// and reduces the amount of overhead code we need to write
// to manage the interfaces. In doing this for us, it also
// prevents inteface leaks, which is also a good thing.
//
return err;
}
} // namespace
int main(int argc,char *argv[])
{
P6ERR err;
//
// Create our logging data stream. This is used by the loader
// to log any errors that occur during initialization. You can
// ask the loader to also log debug/warnings by specifying the
// P6SCLF_DBGLOG/P6SCLF_WRNLOG initialization flags. See p6loader.h.
//
if(P6SUCCEEDED(err = CConsoleStream::createInstance(NULL,VALIDATECOMPTR(p6IDataStream,cpDataStream)))) {
if(P6SUCCEEDED(err = p6InitializeLoader(cpDataStream,9,P6SCLF_NOFLAGS))) {
//
// If you would like to see verbose information passed to the provided data stream,
// you could pass P6SCLF_ALLLOG to see all output. This will tell the loader
// to output very verbose debugging information. By default, only errors are passed
// to the data stream. See p6loader.h for information on the flags which can be
// passed to p6IniitalizeLoader().
//
runJSON(cpConsole, cpDataStream);
//
// We are done and no longer need to use JSN
// (or other components/interfaces). This call
// unloads the component DLLs and frees any
// associated resources.
//
// It is very important to make sure that all
// component interfaces have been released and
// will no longer be referenced by anything
// before calling this method. Crashes will
// occur if an interface is referenced whose DLL
// has been removed from memory.
//
//
// Make sure to release the console interface
// before calling p6CleanupLoader() !! In this
// instance we don't let the smart pointer
// handle the cleanup.
//
cpConsole = NULL;
}
}
else {
//
// Since the loader failed to load successfully, we can
// not call any methods (eg. p6ErrToStr()) to translate
// the error return value to a string. We just print the hex
// value instead. Error values are defined in p6err.h
//
printf("ERROR: Failed to initialize the loader [ %x ]\n",err);
}
}
else {
printf("ERROR: Failed to create CConsoleStream [ %x ]\n",err);
}
return err;
}