www.pudn.com > uoth_src.zip > DataParser.h
#ifndef DSSI_DATAPARSER_H #define DSSI_DATAPARSER_H //----------------------------------------------------------------------------- // // @doc // // @module DataParser.h - Data parser | // // This module contains the definition of the data parser // // Copyright (c) 2002 - Descartes Systems Sciences, Inc. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // 2. Neither the name of Descartes Systems Sciences, Inc nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // @end // // $History: ExpatImpl.h $ // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // // Required include files // //----------------------------------------------------------------------------- #include#include "ExpatImpl.h" #include "uoth.h" #include "Level.h" #include "Region.h" #include "Treasure.h" #include "RuneBook.h" #include "RuneLibrary.h" #include "Character.h" //----------------------------------------------------------------------------- // // Forward definitions // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // // Template class definition // //----------------------------------------------------------------------------- class CDataParser : public CExpatImpl { public: enum _State { Start = 0, InData = 1, InTreasure = 2, InRegion = 3, InLevel = 4, InRuneLibrary = 5, InRuneBook = 6, InCharacter = 7, }; public: // Constructor CDataParser () { m_nState = Start; m_nTextLength = 0; } // Invoked by CExpatImpl after the parser is created void OnPostCreate () { // Enable all the event routines we want EnableStartElementHandler (); EnableEndElementHandler (); // Note: EnableElementHandler will do both start and end EnableCharacterDataHandler (); } // @cmember Start element handler void OnStartElement (const XML_Char *pszName, const XML_Char **papszAttrs) { // // If we have already failed, return // if (!m_strError .IsEmpty ()) return; // // Reset the text length // m_nTextLength = 0; // // Switch based on the state // switch (m_nState) { // // If this is the start element // case Start: // // If the data element // if (stricmp (pszName, "uoth-data") == 0) { // // No attributes are allowed // if (papszAttrs [0] != NULL) { SetError (IDS_ERR_XML_NO_ATTRS); return; } // // Set the state // m_nState = InData; } // // Otherwise, all other elements are invalid // else { SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } break; // // If we are already in data // case InData: { if (stricmp (pszName, "Treasure") == 0) m_sTreasure .OnStart (this, papszAttrs); else if (stricmp (pszName, "Region") == 0) m_sRegion .OnStart (this, papszAttrs); else if (stricmp (pszName, "Level") == 0) m_sLevel .OnStart (this, papszAttrs); else if (stricmp (pszName, "RuneLibrary") == 0) m_sRuneLibrary .OnStart (this, papszAttrs); else if (stricmp (pszName, "Character") == 0) m_sCharacter .OnStart (this, papszAttrs); else { SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } } break; case InTreasure: m_sTreasure .OnStartElement (this, pszName, papszAttrs); break; case InRegion: m_sRegion .OnStartElement (this, pszName, papszAttrs); break; case InLevel: m_sLevel .OnStartElement (this, pszName, papszAttrs); break; case InRuneLibrary: m_sRuneLibrary .OnStartElement (this, pszName, papszAttrs); break; case InRuneBook: m_sRuneBook .OnStartElement (this, pszName, papszAttrs); break; case InCharacter: m_sCharacter .OnStartElement (this, pszName, papszAttrs); break; } return; } // End element handler void OnEndElement (const XML_Char *pszName) { // // If we have already failed, return // if (!m_strError .IsEmpty ()) return; // // Switch based on the state // switch (m_nState) { case Start: SetError (IDS_ERR_XML_UNEXPECTED); return; case InData: if (stricmp (pszName, "uoth-data") == 0) { m_nState = Start; } else { SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } break; case InTreasure: m_sTreasure .OnEndElement (this, pszName); break; case InRegion: m_sRegion .OnEndElement (this, pszName); break; case InLevel: m_sLevel .OnEndElement (this, pszName); break; case InRuneLibrary: m_sRuneLibrary .OnEndElement (this, pszName); break; case InRuneBook: m_sRuneBook .OnEndElement (this, pszName); break; case InCharacter: m_sCharacter .OnEndElement (this, pszName); break; } return; } // Character data handler void OnCharacterData (const XML_Char *pszData, int nLength) { // // If we have already failed, return // if (!m_strError .IsEmpty ()) return; // // Add the text // if (nLength + m_nTextLength > _countof (m_szText) - 1) nLength = _countof (m_szText) - 1 - m_nTextLength; memcpy (&m_szText [m_nTextLength], pszData, nLength * sizeof (XML_Char)); m_nTextLength += nLength; return; } // @access Public methods public: // @cmember Set the current state void SetState (_State nState) { m_nState = nState; } // @cmember Return the text XML_Char *GetText (bool fRemoveWhitespace) { if (fRemoveWhitespace) RemoveWhitespace (); else m_szText [m_nTextLength] = 0; return m_szText; } // @cmember Set the error string void SetError (LPCTSTR pszError) { m_strError = pszError; m_nLineNumber = GetCurrentLineNumber (); m_nColumnNumber = GetCurrentColumnNumber (); } // @cmember Set the error string void SetError (UINT nID) { m_strError .LoadString (nID); m_nLineNumber = GetCurrentLineNumber (); m_nColumnNumber = GetCurrentColumnNumber (); } // @cmember Convert coords void GetCoord (int *px, int *py) { RemoveWhitespace (); XML_Char *pcomma = strchr (m_szText, ','); if (pcomma == NULL) { SetError (IDS_ERR_XML_INVALID_COORD); return; } *pcomma++ = 0; *px = atol (m_szText); *py = atol (pcomma); } // @cmember Add the current rune book to the library void AddRuneBookToLibrary () { m_sRuneLibrary .AddRuneBook (m_sRuneBook); } // @access Protected methods protected: // @cmember Remove whitespace void RemoveWhitespace () { int nOut = 0; bool fHaveWhite = true; int nIn = 0; while (nIn < m_nTextLength) { XML_Char c = m_szText [nIn++]; if (isspace (c)) { if (!fHaveWhite) { fHaveWhite = true; } } else { if (fHaveWhite) { fHaveWhite = false; if (nOut != 0) m_szText [nOut++] = ' '; } m_szText [nOut++] = c; } } m_szText [nOut] = 0; m_nTextLength = nOut; } // @access Public data public: // @cmember Current state _State m_nState; // @cmember Current text buffer XML_Char m_szText [1024]; //FIXME // @cmember Current text length int m_nTextLength; // @cmember If set, the process has failed CString m_strError; // @cmember Scratch region space CRegion m_sRegion; // @cmember Scratch treasure space CTreasure m_sTreasure; // @cmember Scratch level space CLevel m_sLevel; // @cmember Scratch rune library space CRuneLibrary m_sRuneLibrary; // @cmember Scratch rune book space CRuneBook m_sRuneBook; // @cmember Scratch character space CCharacter m_sCharacter; // @cmember Scratch map index int m_nMapIndex; // @cmember Error line number int m_nLineNumber; // @cmember column number int m_nColumnNumber; }; #endif // DSSI_DATAPARSER_H