Torque3D Documentation / _generateds / tamlXmlParser.cpp

tamlXmlParser.cpp

Engine/source/persistence/taml/xml/tamlXmlParser.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2013 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "persistence/taml/xml/tamlXmlParser.h"
 25#include "persistence/taml/tamlVisitor.h"
 26#include "console/console.h"
 27
 28// Debug Profiling.
 29#include "platform/profiler.h"
 30
 31#ifndef _FILESTREAM_H_
 32#include "core/stream/fileStream.h"
 33#endif
 34
 35//-----------------------------------------------------------------------------
 36
 37bool TamlXmlParser::accept( const char* pFilename, TamlVisitor& visitor )
 38{
 39    // Debug Profiling.
 40    PROFILE_SCOPE(TamlXmlParser_Accept);
 41
 42    // Sanity!
 43    AssertFatal( pFilename != NULL, "Cannot parse a NULL filename." );
 44
 45    // Expand the file-path.
 46    char filenameBuffer[1024];
 47    // TODO: Make sure this is a proper substitute for
 48    // Con::expandPath (T2D)
 49    Con::expandToolScriptFilename( filenameBuffer, sizeof(filenameBuffer), pFilename );
 50    /** T2D uses a custom version of TinyXML that supports FileStream.
 51      * We don't so we can't do this
 52      *
 53    FileStream stream;
 54
 55#ifdef TORQUE_OS_ANDROID
 56    if (strlen(pFilename) > strlen(filenameBuffer)) {
 57      dStrcpy(filenameBuffer, pFilename, 1024);
 58    }
 59#endif
 60
 61    // File open for read?
 62    if ( !stream.open( filenameBuffer, Torque::FS::File::AccessMode::Read ) )
 63    {
 64        // No, so warn.
 65        Con::warnf("TamlXmlParser::parse() - Could not open filename '%s' for parse.", filenameBuffer );
 66        return false;
 67    }
 68    
 69     */
 70
 71    TiXmlDocument xmlDocument;
 72
 73    // Load document from stream.
 74    if ( !xmlDocument.LoadFile( filenameBuffer ) )
 75    {
 76        // Warn!
 77        Con::warnf("TamlXmlParser: Could not load Taml XML file from stream.");
 78        return false;
 79    }
 80
 81    // Close the stream.
 82    // stream.close();
 83
 84    // Set parsing filename.
 85    setParsingFilename( filenameBuffer );
 86
 87    // Flag document as not dirty.
 88    mDocumentDirty = false;
 89
 90    // Parse root element.
 91    parseElement( xmlDocument.RootElement(), visitor );
 92
 93    // Reset parsing filename.
 94    setParsingFilename( StringTable->EmptyString() );
 95
 96    // Finish if the document is not dirty.
 97    if ( !mDocumentDirty )
 98        return true;
 99
100    // Open for write?
101    /*if ( !stream.open( filenameBuffer, FileStream::StreamWrite ) )
102    {
103        // No, so warn.
104        Con::warnf("TamlXmlParser::parse() - Could not open filename '%s' for write.", filenameBuffer );
105        return false;
106    }*/
107
108    // Yes, so save the document.
109    if ( !xmlDocument.SaveFile( filenameBuffer ) )
110    {
111        // Warn!
112        Con::warnf("TamlXmlParser: Could not save Taml XML document.");
113        return false;
114    }
115
116    // Close the stream.
117    //stream.close();
118
119    return true;
120}
121
122//-----------------------------------------------------------------------------
123
124inline bool TamlXmlParser::parseElement( TiXmlElement* pXmlElement, TamlVisitor& visitor )
125{
126    // Debug Profiling.
127    PROFILE_SCOPE(TamlXmlParser_ParseElement);
128
129    // Parse attributes (stop processing if instructed).
130    if ( !parseAttributes( pXmlElement, visitor ) )
131        return false;
132
133    // Finish if only the root is needed.
134    if ( visitor.wantsRootOnly() )
135        return false;
136
137    // Fetch any children.
138    TiXmlNode* pChildXmlNode = pXmlElement->FirstChild();
139
140    // Do we have any element children?
141    if ( pChildXmlNode != NULL && pChildXmlNode->Type() == TiXmlNode::TINYXML_ELEMENT )
142    {
143        // Iterate children.
144        for ( TiXmlElement* pChildXmlElement = dynamic_cast<TiXmlElement*>( pChildXmlNode ); pChildXmlElement; pChildXmlElement = pChildXmlElement->NextSiblingElement() )
145        {
146            // Parse element (stop processing if instructed).
147            if ( !parseElement( pChildXmlElement, visitor ) )
148                return false;
149        }
150    }
151
152    return true;
153}
154
155//-----------------------------------------------------------------------------
156
157inline bool TamlXmlParser::parseAttributes( TiXmlElement* pXmlElement, TamlVisitor& visitor )
158{
159    // Debug Profiling.
160    PROFILE_SCOPE(TamlXmlParser_ParseAttribute);
161
162    // Calculate if element is at the root or not.
163    const bool isRoot = pXmlElement->GetDocument()->RootElement() == pXmlElement;
164
165    // Create a visitor property state.
166    TamlVisitor::PropertyState propertyState;
167    propertyState.setObjectName( pXmlElement->Value(), isRoot );
168
169    // Iterate attributes.
170    for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
171    {
172        // Configure property state.
173        propertyState.setProperty( pAttribute->Name(), pAttribute->Value() );
174
175        // Visit this attribute.
176        const bool visitStatus = visitor.visit( *this, propertyState );
177
178        // Was the property value changed?
179        if ( propertyState.getPropertyValueDirty() )
180        {
181            // Yes, so update the attribute.
182            pAttribute->SetValue( propertyState.getPropertyValue() );
183
184            // Flag the document as dirty.
185            mDocumentDirty = true;
186        }
187
188        // Finish if requested.
189        if ( !visitStatus )
190            return false;
191    }
192
193    return true;
194}
195