taylor001 13 лет назад
Родитель
Сommit
90d2f1bcd0
2 измененных файлов с 0 добавлено и 625 удалено
  1. 0 489
      src/loaders/XMLReader.cpp
  2. 0 136
      src/loaders/XMLReader.h

+ 0 - 489
src/loaders/XMLReader.cpp

@@ -1,489 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <cstdio>
-#include <ctype.h>
-#include "Auto.h"
-#include "Log.h"
-#include "Types.h"
-#include "Str.h"
-#include "XMLReader.h"
-#include "Stream.h"
-#include "MathUtils.h"
-#include "Filesystem.h"
-
-namespace Crown
-{
-
-enum eXMLTokenizerState
-{
-	XTS_WHITESPACE,
-	XTS_WORD,
-	XTS_STRING,
-	XTS_ESCAPE,
-	XTS_SLASH,
-	XTS_LESSTHAN
-};
-
-XMLReader::XMLReader():
-  mRoot(NULL), mReadToken(XTT_UNDEFINED)
-{
-}
-
-XMLReader::~XMLReader()
-{
-	Clear();
-}
-
-void XMLReader::Print()
-{
-	if (mRoot)
-		PrintNode(mRoot, 0);
-	else
-		Log::I("XMLReader::Print: Empty XML or Error in loading");
-}
-
-void XMLReader::PrintNode(XMLNode* node, int depth)
-{
-	Str tag = "<" + node->name;
-
-	Dictionary<Str, Str>::Enumerator e = node->simpleAttributes.getBegin();
-	while (e.next())
-	{
-		tag += " " + e.current().key + "=\"" + e.current().value + "\"";
-	}
-
-	if (node->simpleAttributes.GetSize() == 0)
-		tag += " />";
-	else
-		tag += " >";
-
-	Log::I(Str(depth, ' ') + tag);
-
-	for(int i=0; i<node->children.GetSize(); i+=1)
-	{
-		PrintNode(node->children[i], depth + 1);
-	}
-
-	Log::I(Str(depth, ' ') + "</" + node->name + ">");
-}
-
-bool XMLReader::LoadFile(Str filePath)
-{
-	//This local Shared pointer keeps the stream alive, recursive calls can use plain pointers safely
-	Stream* streamIn = GetFilesystem()->OpenStream(filePath, SOM_READ);
-	if (streamIn == NULL)
-		return false;
-
-	if (!InitTokenizer(streamIn))
-		return false;
-
-	bool dummy;
-	mRoot = ReadNode(streamIn, NULL, dummy);
-
-	if (mRoot == NULL)
-		return false;
-
-	GetFilesystem()->Close(streamIn);
-	return true;
-}
-
-XMLNode* XMLReader::ReadNode(Stream* streamIn, XMLNode* parentNode, bool& isComplexProperty)
-{
-	Auto<XMLNode> node = new XMLNode();
-
-	bool accepted;
-	if (!Accepted(streamIn, XTT_TAG_OPEN, accepted))
-		return NULL;
-
-	if (!accepted)
-		return NULL;
-
-	if (!Expected(streamIn, XTT_WORD))
-		return NULL;
-
-	node->name = mReadValue;
-
-	isComplexProperty = false;
-	bool dotFound = false;
-	if (!Accepted(streamIn, XTT_DOT, dotFound))
-		return NULL;
-	
-	if (dotFound)
-	{
-		if (parentNode == NULL)
-		{
-			Log::E("A complex property can only be specified inside a tag");
-			return NULL;
-		}
-
-		if (parentNode->name != node->name)
-		{
-			Log::E("The name before the dot in a complex property must be the same as the parent tag. Expected '" + parentNode->name + "' but '" + node->name + "' found.");
-			return NULL;
-		}
-
-		//Case of complex property
-		//eg: Pear.Leaves in <Pear><Pear.Leaves>...</Pear.Leaves></Pear>
-		//Expect a dot and another name
-		isComplexProperty = true;
-
-		if (!Expected(streamIn, XTT_WORD))
-			return NULL;
-
-		node->name = mReadValue;
-	}
-
-	bool isInlineTag;
-
-	while (true)
-	{
-		bool accepted;
-		//Accept a > and proceed with children parsing
-		if (!Accepted(streamIn, XTT_TAG_CLOSE, accepted))
-			return NULL;
-
-		if (accepted)
-		{
-			isInlineTag = false;
-			break;
-		}
-
-		//Accept a /> and avoid parsing children
-		if (!Accepted(streamIn, XTT_TAG_INLINECLOSE, accepted))
-			return NULL;
-
-		if (accepted)
-		{
-			isInlineTag = true;
-			break;
-		}
-
-		if (!Expected(streamIn, XTT_WORD))
-			return NULL;
-		Str attributeName = mReadValue;
-
-		if (!Expected(streamIn, XTT_EQUAL))
-			return NULL;
-
-		if (!Expected(streamIn, XTT_STRING))
-			return NULL;
-		node->simpleAttributes[attributeName] = mReadValue;
-	}
-
-	if (!isInlineTag)
-	{
-
-		while(true)
-		{
-			bool isChildComplexProperty;
-			XMLNode* child = ReadNode(streamIn, node.GetPointer(), isChildComplexProperty);
-			if (child == NULL)
-				break;
-
-			if (isChildComplexProperty)
-			{
-				node->complexAttributes[child->name] = child;
-			}
-			else
-			{
-				node->children.Append(child);
-			}
-		}
-
-		if (!Expected(streamIn, XTT_TAG_OPENEXPLICIT))
-			return NULL;
-
-		if (!Expected(streamIn, XTT_WORD))
-			return NULL;
-
-		if (isComplexProperty)
-		{
-			if (mReadValue != parentNode->name)
-			{
-				Log::E("Closing tag of '" + parentNode->name + "." + node->name + "' is mismatched");
-				return NULL;
-			}
-
-			if (!Expected(streamIn, XTT_DOT))
-				return NULL;
-
-			if (!Expected(streamIn, XTT_WORD))
-				return NULL;
-		}
-
-		if (mReadValue != node->name)
-		{
-			Log::E("Closing tag of '" + node->name + "' is mismatched");
-			return NULL;
-		}
-
-		if (!Expected(streamIn, XTT_TAG_CLOSE))
-			return NULL;
-	}
-
-	return node.GetPointer(true);
-}
-
-bool XMLReader::InitTokenizer(Stream* streamIn)
-{
-	mStreamEnded = streamIn->EndOfStream();
-  if (mStreamEnded)
-		return false;
-	mCurrentCharacter = streamIn->ReadByte();
-
-	return true;
-}
-
-bool XMLReader::NextTokenIfUndefined(Stream* streamIn)
-{
-	if (mStreamEnded)
-		return false;
-	if (mReadToken != XTT_UNDEFINED)
-		return true;
-
-	mReadToken = XTT_UNDEFINED;
-	eXMLTokenizerState state = XTS_WHITESPACE;
-
-	while (!mStreamEnded)
-	{
-		bool exitWhile = false;
-
-		switch (state)
-		{
-			case XTS_WHITESPACE:
-			{
-				if (isalpha(mCurrentCharacter))
-				{
-					state = XTS_WORD;
-					mReadToken = XTT_WORD;
-					mReadValue = Str(mCurrentCharacter);
-				}
-				else if (mCurrentCharacter == '"')
-				{
-					state = XTS_STRING;
-					mReadToken = XTT_STRING;
-					mReadValue = Str::Empty();
-				}
-				else if (mCurrentCharacter == '<')
-				{
-					state = XTS_LESSTHAN;
-					mReadToken = XTT_TAG_OPEN;
-				}
-				else if (mCurrentCharacter == '>')
-				{
-					mReadToken = XTT_TAG_CLOSE;
-					exitWhile = true;
-				}
-				else if (mCurrentCharacter == '/')
-				{
-					state = XTS_SLASH;
-				}
-				else if (mCurrentCharacter == '=')
-				{
-					mReadToken = XTT_EQUAL;
-					exitWhile = true;
-				}
-				else if (mCurrentCharacter == '.')
-				{
-					mReadToken = XTT_DOT;
-					exitWhile = true;
-				}
-				else if (!isspace(mCurrentCharacter) && mCurrentCharacter != '\n' && mCurrentCharacter != '\r')
-					return false;
-			}
-			break;
-			case XTS_WORD:
-			{
-				if (isalpha(mCurrentCharacter))
-				{
-					mReadValue += Str(mCurrentCharacter);
-				}
-				else
-					return true;
-			}
-			break;
-			case XTS_STRING:
-			{
-				if (mCurrentCharacter == '\\')
-					state = XTS_ESCAPE;
-				else if (mCurrentCharacter == '"')
-					exitWhile = true;
-				else
-					mReadValue += Str(mCurrentCharacter);
-			}
-			break;
-			case XTS_ESCAPE:
-			{
-				if (mCurrentCharacter == '\\' || mCurrentCharacter == '"')
-				{
-					state = XTS_STRING;
-					mReadValue += Str(mCurrentCharacter);
-				}
-				else
-					return false;
-			}
-			break;
-			case XTS_SLASH:
-			{
-				if (mCurrentCharacter == '>')
-				{
-					mReadToken = XTT_TAG_INLINECLOSE;
-					exitWhile = true;
-				}
-				else
-					return false;
-			}
-			break;
-			case XTS_LESSTHAN:
-			{
-				if (mCurrentCharacter == '/')
-				{
-					mReadToken = XTT_TAG_OPENEXPLICIT;
-					exitWhile = true;
-				}
-				else
-					return true;
-			}
-			break;
-		}
-
-		if (streamIn->EndOfStream())
-			mStreamEnded = true;
-		else
-			mCurrentCharacter = streamIn->ReadByte();
-
-		if (exitWhile)
-			break;
-	}
-
-	if (state == XTS_ESCAPE || (state == XTS_SLASH && mReadToken != XTT_TAG_INLINECLOSE))
-		return false;
-
-	return true;
-}
-
-eXMLTokenType XMLReader::ConsumeCurrentToken()
-{
-	eXMLTokenType ret = mReadToken;
-	mReadToken = XTT_UNDEFINED;
-	return ret;
-}
-
-eXMLTokenType XMLReader::GetCurrentToken()
-{
-	return mReadToken;
-}
-
-bool XMLReader::Expected(Stream* streamIn, eXMLTokenType expectedToken)
-{
-	if (!NextTokenIfUndefined(streamIn))
-		return false;
-
-	if (ConsumeCurrentToken() != expectedToken)
-	{
-		char buff[21];
-		int bytesToRead = Math::Min<int>(20, streamIn->GetSize() - streamIn->GetPosition());
-		streamIn->ReadDataBlock(buff, bytesToRead);
-		buff[bytesToRead] = '\0';
-		Log::E("Unexpected character before '" + Str(buff) + "'");
-		mStreamEnded = true;
-		return false;
-	}
-
-	return true;
-}
-
-bool XMLReader::Accepted(Stream* streamIn, eXMLTokenType acceptedToken, bool& accepted)
-{
-	if (!NextTokenIfUndefined(streamIn))
-		return false;
-
-	accepted = (GetCurrentToken() == acceptedToken);
-
-	if (accepted)
-		ConsumeCurrentToken();
-
-	return true;
-}
-
-
-bool XMLReader::ExpectedWhitespace(Stream* streamIn)
-{
-	char currentChar = streamIn->ReadByte();
-	if (!isspace(currentChar))
-		return false;
-
-	return true;
-}
-
-Str XMLReader::ReadWord(Stream* streamIn)
-{
-	Str out = Str::Empty();
-	bool skippingWhite = true;
-
-	while (!streamIn->EndOfStream())
-	{
-		char currentChar = streamIn->ReadByte();
-
-		if (skippingWhite)
-		{
-			if (isspace(currentChar))
-			{
-				continue;
-			}
-			else
-			{
-				skippingWhite = false;
-			}
-		}
-
-		if (!isalpha(currentChar))
-		{
-			break;
-		}
-
-		//TODO: Add a operator+(char n)
-		out += Str(currentChar);
-	}
-
-	//Undo the last character (if not eof)
-	if (!streamIn->EndOfStream())
-		streamIn->Seek(-1, SM_SeekFromCurrent);
-
-	return out;
-}
-
-void XMLReader::Clear()
-{
-	if (mRoot)
-	{
-		delete mRoot;
-		mRoot = NULL;
-	}
-}
-
-} // namespace Crown
-

+ 0 - 136
src/loaders/XMLReader.h

@@ -1,136 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#pragma once
-
-#include "Types.h"
-#include "Device.h"
-#include "Str.h"
-#include "Dictionary.h"
-
-namespace Crown
-{
-
-class Stream;
-
-enum eXMLTokenType
-{
-	XTT_UNDEFINED,
-	XTT_WORD,
-	XTT_TAG_OPEN,
-	XTT_TAG_CLOSE,
-	XTT_TAG_INLINECLOSE,
-	XTT_TAG_OPENEXPLICIT,
-	XTT_EQUAL,
-	XTT_STRING,
-	XTT_DOT
-};
-
-class XMLNode
-{
-public:
-	Str name;
-	Dictionary<Str, Str> simpleAttributes;		//Attributes whose value is a string
-	Dictionary<Str, XMLNode*> complexAttributes;	//Attributes whose value is a XMLNode representing a structured value
-	List<XMLNode*> children;
-
-	XMLNode()
-	{
-
-	}
-
-	virtual ~XMLNode()
-	{
-		Dictionary<Str, XMLNode*>::Enumerator e = complexAttributes.getBegin();
-		while (e.next())
-		{
-			delete e.current().value;
-		}
-
-		for(int i=0; i<children.GetSize(); i++)
-		{
-			delete children[i];
-		}
-	}
-
-	XMLNode* Clone() const
-	{
-		XMLNode* clone = new XMLNode();
-		clone->name = name;
-
-		Dictionary<Str, Str>::Enumerator es = simpleAttributes.getBegin();
-		while (es.next())
-		{
-			clone->simpleAttributes[es.current().key] = es.current().value;
-		}
-
-		Dictionary<Str, XMLNode*>::Enumerator ec = complexAttributes.getBegin();
-		while (ec.next())
-		{
-			clone->complexAttributes[ec.current().key] = ec.current().value->Clone();
-		}
-
-		for(int i=0; i<children.GetSize(); i++)
-		{
-			clone->children.Append(children[i]->Clone());
-		}
-
-		return clone;
-	}
-};
-
-class XMLReader
-{
-public:
-	XMLReader();
-	~XMLReader();
-
-	bool LoadFile(Str filePath);
-	inline XMLNode* GetRootXMLNode()
-	  { return mRoot; }
-	void Clear();
-	void Print();
-
-private:
-	XMLNode* mRoot;
-	char mCurrentCharacter;
-	bool mStreamEnded;
-	eXMLTokenType mReadToken;
-	Str mReadValue;
-
-	XMLNode* ReadNode(Stream* streamIn, XMLNode* parentNode, bool& isComplexProperty);
-	void PrintNode(XMLNode* node, int depth);
-	bool InitTokenizer(Stream* streamIn);
-	bool NextTokenIfUndefined(Stream* streamIn);
-	eXMLTokenType ConsumeCurrentToken();
-	eXMLTokenType GetCurrentToken();
-	bool Expected(Stream* streamIn, eXMLTokenType expectedToken);
-	bool Accepted(Stream* streamIn, eXMLTokenType acceptedToken, bool& accepted);
-	bool ExpectedWhitespace(Stream* streamIn);
-	Str ReadWord(Stream* streamIn);
-};
-
-} // namespace Crown
-