Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CAT/CATXMLParser.cpp Source File

CATXMLParser.cpp

Go to the documentation of this file.
00001 /// \file    CATXMLParser.cpp
00002 /// \brief   XML Parser
00003 /// \ingroup CAT
00004 ///
00005 /// Copyright (c) 2003-2008 by Michael Ellison.
00006 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00007 ///
00008 // $Author: mikeellison $
00009 // $Date: 2008-01-21 21:40:31 -0600 (Mon, 21 Jan 2008) $
00010 // $Revision:   $
00011 // $NoKeywords: $
00012 
00013 #include "CATXMLParser.h"
00014 #include "CATXMLObject.h"
00015 #include "CATStreamFile.h"
00016 CATXMLParser::CATXMLParser()
00017 {
00018     fCurParent    = 0;
00019 }
00020 
00021 
00022 CATXMLParser::~CATXMLParser()
00023 {
00024 }
00025 
00026 CATResult CATXMLParser::Parse(const CATWChar*  path,
00027                             CATXMLFactory* factory,
00028                             CATXMLObject*& root)
00029 {
00030     if (!path)
00031     {
00032         return CAT_ERR_XML_PARSER_INVALID_PATH;
00033     }
00034 
00035     CATStreamFile stream;
00036     CATResult result;
00037     if (CATFAILED(result = stream.Open(path,CATStream::READ_ONLY)))
00038     {
00039         return result;
00040     }
00041     result = CATXMLParser::ParseStream(&stream,factory,root);
00042     stream.Close();
00043     return result;
00044 }
00045 
00046 
00047 CATResult CATXMLParser::ParseStream(CATStream* stream,
00048                             CATXMLFactory* factory,
00049                             CATXMLObject*& root)
00050 {
00051     CATResult result;
00052     if (!stream)
00053     {
00054         return CATRESULT(CAT_ERR_XML_PARSER_INVALID_PATH);
00055     }
00056 
00057     stream->SeekAbsolute(0);
00058     CATInt64 filesize = 0;
00059     stream->Size(filesize);
00060 
00061     CATUInt32 fsize = (CATUInt32)filesize;
00062     if ((CATInt64)fsize != filesize)
00063     {        
00064         return CATRESULT(CAT_ERR_XML_PARSER_OUT_OF_MEMORY);
00065     }
00066 
00067     CATUInt8* buffer = new CATUInt8[fsize+1];
00068     if (!buffer)
00069     {        
00070         return CATRESULT(CAT_ERR_XML_PARSER_OUT_OF_MEMORY);
00071     }
00072 
00073     memset(buffer,0,fsize+1);
00074     if (CATFAILED(result = stream->Read(buffer,fsize)))
00075     {
00076         delete [] buffer;
00077         return result;
00078     }
00079 
00080     result = ParseMemory(buffer,fsize,factory,root);
00081 
00082     delete [] buffer;
00083     return result;
00084 }
00085 
00086 CATResult CATXMLParser::ParseMemory(const void*  memoryBuf,
00087                                   CATInt32        bufLen,
00088                                   CATXMLFactory* factory,
00089                                   CATXMLObject*& root)
00090 {
00091     CATXMLParser* parser = new CATXMLParser();    
00092     root = 0;    
00093     parser->fRootObjPtr = &root;
00094     parser->fFactory    = factory;
00095     
00096     XML_Parser expatParser = XML_ParserCreate(0);
00097     XML_SetUserData(expatParser, parser);    
00098     XML_SetElementHandler(expatParser,&CATXMLParser::StartElement,&CATXMLParser::EndElement);    
00099     XML_SetCharacterDataHandler(expatParser,&CATXMLParser::CharacterHandler);    
00100 
00101     if (XML_Parse(expatParser,(char*)memoryBuf,bufLen,1) == XML_STATUS_ERROR)
00102     {
00103          // On error, bail with a string....
00104          XML_ParserFree(expatParser);
00105          delete parser;
00106          return CATRESULT(CAT_ERR_XML_INVALID_XML);
00107     }
00108     
00109     if (root)
00110     {
00111        root->ParseAttributes();
00112     }
00113 
00114     XML_ParserFree(expatParser);
00115     
00116     delete parser;    
00117     return CAT_SUCCESS;
00118 }
00119 
00120 
00121 void XMLCALL CATXMLParser::StartElement(void *userData,
00122                                         const XML_Char *name,
00123                                         const XML_Char **atts)
00124 {    
00125     CATXMLParser* parser = (CATXMLParser*)userData;
00126     CATXMLAttribs* newAttribs = new CATXMLAttribs(CATXMLObject::CATXMLKeyComp);
00127     for (CATUInt32 i = 0; atts[i]; i += 2) 
00128     {
00129         CATWChar* newKey = new CATWChar[wcslen((const CATWChar*)atts[i])+1];
00130         CATWChar* newVal = new CATWChar[wcslen((const CATWChar*)atts[i+1])+1];
00131         wcscpy(newKey,atts[i]);
00132         wcscpy(newVal,atts[i+1]);
00133 
00134         newAttribs->insert(std::make_pair(newKey, newVal));
00135     }
00136 
00137     CATXMLObject* newObject = 0;    
00138     // Attributes object becomes owned by the new object.
00139     CATResult hr = parser->fFactory->Create( name, newAttribs, parser->fCurParent, newObject);
00140     if (CATFAILED(hr) || (newObject == 0))
00141     {
00142         while (newAttribs->size() != 0)
00143         {
00144             CATXMLAttribsIter iter = newAttribs->begin();                        
00145             delete [] (CATWChar*)iter->first;
00146             delete [] (CATWChar*)iter->second;
00147             newAttribs->erase(iter);
00148         }
00149         delete newAttribs;
00150         return;
00151     }
00152 
00153     if (*parser->fRootObjPtr == 0)
00154     {
00155         *parser->fRootObjPtr = newObject;
00156     }
00157 
00158     parser->fCurParent = newObject;
00159     parser->fObjectStack.push(newObject);    
00160 }
00161 
00162 
00163 void XMLCALL CATXMLParser::CharacterHandler(void *userData,
00164                                             const XML_Char *s,
00165                                             int len)
00166 {
00167     CATXMLParser* parser = (CATXMLParser*)userData;
00168     if (parser->fCurParent)
00169     {
00170         parser->fCurParent->AppendData(s,len);
00171     }
00172 }
00173 
00174         
00175        
00176 void XMLCALL CATXMLParser::EndElement(void *userData,
00177                                       const XML_Char* /*name*/)
00178 {
00179     CATXMLParser* parser = (CATXMLParser*)userData;
00180     parser->fObjectStack.pop();
00181     if (parser->fObjectStack.size())
00182     {
00183         parser->fCurParent = parser->fObjectStack.top();
00184     }
00185     else
00186     {
00187         parser->fCurParent = 0;
00188     }
00189 }
00190 
00191 CATResult CATXMLParser::Write(const CATString& filename, CATXMLObject* rootNode)
00192 {
00193    CATResult result = CAT_SUCCESS;
00194    CATString header = L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
00195    CATStreamFile xmlFile;
00196    header << kCRLF;
00197 
00198    if (CATFAILED(result = xmlFile.Open(filename,CATStream::READ_WRITE_CREATE_TRUNC)))
00199    {
00200       return result;
00201    }      
00202 
00203    result = xmlFile.Write((const char*)header, header.Length());
00204    if (CATFAILED(result))
00205    {
00206       (void)xmlFile.Close();
00207       return result;
00208    }
00209 
00210    CATXMLObject* curNode = 0;
00211    result = rootNode->WriteToStream(&xmlFile);
00212    (void)xmlFile.Close();
00213 
00214    return result;
00215 }

Generated on Mon Feb 11 04:09:50 2008 for Game Accessibility Suite by doxygen 1.5.4