Commit 8aff3b74 authored by Peter Eastman's avatar Peter Eastman
Browse files

Replaced TinyXML with irrXML

parent 83ed602e
// Copyright (C) 2002-2005 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
#include "irrXML.h"
#include "irrString.h"
#include "irrArray.h"
#include "fast_atof.h"
#include "CXMLReaderImpl.h"
namespace irr
{
namespace io
{
//! Implementation of the file read callback for ordinary files
class CFileReadCallBack : public IFileReadCallBack
{
public:
//! construct from filename
CFileReadCallBack(const char* filename)
: File(0), Size(0), Close(true)
{
// open file
File = fopen(filename, "rb");
if (File)
getFileSize();
}
//! construct from FILE pointer
CFileReadCallBack(FILE* file)
: File(file), Size(0), Close(false)
{
if (File)
getFileSize();
}
//! destructor
virtual ~CFileReadCallBack()
{
if (Close && File)
fclose(File);
}
//! Reads an amount of bytes from the file.
virtual int read(void* buffer, int sizeToRead)
{
if (!File)
return 0;
return (int)fread(buffer, 1, sizeToRead, File);
}
//! Returns size of file in bytes
virtual int getSize()
{
return Size;
}
private:
//! retrieves the file size of the open file
void getFileSize()
{
fseek(File, 0, SEEK_END);
Size = ftell(File);
fseek(File, 0, SEEK_SET);
}
FILE* File;
int Size;
bool Close;
}; // end class CFileReadCallBack
// FACTORY FUNCTIONS:
//! Creates an instance of an UFT-8 or ASCII character xml parser.
IrrXMLReader* createIrrXMLReader(const char* filename)
{
return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(filename));
}
//! Creates an instance of an UFT-8 or ASCII character xml parser.
IrrXMLReader* createIrrXMLReader(FILE* file)
{
return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(file));
}
//! Creates an instance of an UFT-8 or ASCII character xml parser.
IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback)
{
return new CXMLReaderImpl<char, IXMLBase>(callback, false);
}
//! Creates an instance of an UTF-16 xml parser.
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename)
{
return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(filename));
}
//! Creates an instance of an UTF-16 xml parser.
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file)
{
return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(file));
}
//! Creates an instance of an UTF-16 xml parser.
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback)
{
return new CXMLReaderImpl<char16, IXMLBase>(callback, false);
}
//! Creates an instance of an UTF-32 xml parser.
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename)
{
return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(filename));
}
//! Creates an instance of an UTF-32 xml parser.
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file)
{
return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(file));
}
//! Creates an instance of an UTF-32 xml parser.
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback)
{
return new CXMLReaderImpl<char32, IXMLBase>(callback, false);
}
} // end namespace io
} // end namespace irr
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2010-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -38,8 +38,6 @@ ...@@ -38,8 +38,6 @@
#include "openmm/internal/windowsExport.h" #include "openmm/internal/windowsExport.h"
#include <iosfwd> #include <iosfwd>
class TiXmlElement;
namespace OpenMM { namespace OpenMM {
/** /**
...@@ -77,10 +75,10 @@ public: ...@@ -77,10 +75,10 @@ public:
return reinterpret_cast<T*>(deserializeStream(stream)); return reinterpret_cast<T*>(deserializeStream(stream));
} }
private: private:
class StreamReader;
static void serialize(const SerializationNode& node, std::ostream& stream); static void serialize(const SerializationNode& node, std::ostream& stream);
static void* deserializeStream(std::istream& stream); static void* deserializeStream(std::istream& stream);
static void encodeNode(const SerializationNode& node, std::ostream& stream, int depth); static void encodeNode(const SerializationNode& node, std::ostream& stream, int depth);
static void decodeNode(SerializationNode& node, const TiXmlElement& element);
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2010-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -30,10 +30,81 @@ ...@@ -30,10 +30,81 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/serialization/XmlSerializer.h" #include "openmm/serialization/XmlSerializer.h"
#include "tinyxml.h" #include "irrXML.h"
#include <cstring>
#include <iostream>
#include <map>
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
using namespace irr;
using namespace io;
/**
* Apply XML encoding to a string. This is adapted from TinyXML (written by Lee Thomason).
*/
static void encodeString(const string& str, string* outString) {
static map<char, string> entities;
static bool hasInitialized = false;
if (!hasInitialized) {
hasInitialized = true;
entities['&'] = "&amp;";
entities['<'] = "&lt;";
entities['>'] = "&gt;";
entities['\"'] = "&quot;";
entities['\''] = "&apos;";
}
int i=0;
while (i<(int)str.length()) {
unsigned char c = (unsigned char) str[i];
if (c == '&'
&& i < ((int)str.length() - 2)
&& str[i+1] == '#'
&& str[i+2] == 'x') {
// Hexadecimal character reference.
// Pass through unchanged.
// &#xA9; -- copyright symbol, for example.
//
// The -1 is a bug fix from Rob Laveaux. It keeps
// an overflow from happening if there is no ';'.
// There are actually 2 ways to exit this loop -
// while fails (error case) and break (semicolon found).
// However, there is no mechanism (currently) for
// this function to return an error.
while (i<(int)str.length()-1) {
outString->append(str.c_str() + i, 1);
++i;
if (str[i] == ';')
break;
}
}
else if (entities.find(c) != entities.end()) {
outString->append(entities[c]);
++i;
}
else if (c < 32) {
// Easy pass at non-alpha/numeric/symbol
// Below 32 is symbolic.
char buf[ 32 ];
snprintf(buf, sizeof(buf), "&#x%02X;", (unsigned) (c & 0xff));
//*ME: warning C4267: convert 'size_t' to 'int'
//*ME: Int-Cast to make compiler happy ...
outString->append(buf, (int)strlen(buf));
++i;
}
else {
//char realc = (char) c;
//outString->append(&realc, 1);
*outString += (char) c; // somewhat more efficient function call.
++i;
}
}
}
void XmlSerializer::serialize(const SerializationNode& node, std::ostream& stream) { void XmlSerializer::serialize(const SerializationNode& node, std::ostream& stream) {
stream << "<?xml version=\"1.0\" ?>\n"; stream << "<?xml version=\"1.0\" ?>\n";
...@@ -47,8 +118,8 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre ...@@ -47,8 +118,8 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre
const map<string, string>& properties = node.getProperties(); const map<string, string>& properties = node.getProperties();
for (map<string, string>::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { for (map<string, string>::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) {
string name, value; string name, value;
TiXmlBase::EncodeString(iter->first, &name); encodeString(iter->first, &name);
TiXmlBase::EncodeString(iter->second, &value); encodeString(iter->second, &value);
stream << ' ' << name << "=\"" << value << '\"'; stream << ' ' << name << "=\"" << value << '\"';
} }
const vector<SerializationNode>& children = node.getChildren(); const vector<SerializationNode>& children = node.getChildren();
...@@ -64,20 +135,64 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre ...@@ -64,20 +135,64 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre
} }
} }
/**
* Adapter class to let irrXML read a C++ stream.
*/
class XmlSerializer::StreamReader : public IFileReadCallBack {
public:
StreamReader(std::istream& stream) : stream(stream) {
stream.seekg(0, ios_base::end);
size = stream.tellg();
stream.seekg(0);
}
int read(void* buffer, int sizeToRead) {
stream.read((char*) buffer, sizeToRead);
return stream.gcount();
}
int getSize() {
return size;
}
private:
std::istream& stream;
int size;
};
/**
* Process an XML node, storing its content into a SerializationNode.
*/
static void decodeNode(SerializationNode& node, IrrXMLReader& xml) {
for (int i = 0; i < xml.getAttributeCount(); i++)
node.setStringProperty(xml.getAttributeName(i), xml.getAttributeValue(i));
if (xml.isEmptyElement())
return;
while (xml.read()) {
switch (xml.getNodeType()) {
case EXN_ELEMENT:
{
SerializationNode& childNode = node.createChildNode(xml.getNodeName());
decodeNode(childNode, xml);
break;
}
case EXN_ELEMENT_END:
return;
}
}
}
void* XmlSerializer::deserializeStream(std::istream& stream) { void* XmlSerializer::deserializeStream(std::istream& stream) {
TiXmlDocument doc;
stream >> doc;
SerializationNode root; SerializationNode root;
decodeNode(root, *doc.FirstChildElement()); StreamReader reader(stream);
IrrXMLReader* xml = createIrrXMLReader(&reader);
// Find the root node in the file.
while (xml->read() && xml->getNodeType() != EXN_ELEMENT)
;
decodeNode(root, *xml);
delete xml;
// Process the SerializationNodes.
const SerializationProxy& proxy = SerializationProxy::getProxy(root.getStringProperty("type")); const SerializationProxy& proxy = SerializationProxy::getProxy(root.getStringProperty("type"));
return proxy.deserialize(root); return proxy.deserialize(root);
} }
void XmlSerializer::decodeNode(SerializationNode& node, const TiXmlElement& element) {
for (const TiXmlAttribute* attribute = element.FirstAttribute(); attribute != NULL; attribute = attribute->Next())
node.setStringProperty(attribute->NameTStr(), attribute->ValueStr());
for (const TiXmlElement* child = element.FirstChildElement(); child != NULL; child = child->NextSiblingElement()) {
SerializationNode& childNode = node.createChildNode(child->ValueTStr());
decodeNode(childNode, *child);
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "tinyxml.h"
// The goal of the seperate error file is to make the first
// step towards localization. tinyxml (currently) only supports
// english error messages, but the could now be translated.
//
// It also cleans up the code a bit.
//
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
{
"No error",
"Error",
"Failed to open file",
"Error parsing Element.",
"Failed to read Element name",
"Error reading Element value.",
"Error reading Attributes.",
"Error: empty tag.",
"Error reading end tag.",
"Error parsing Unknown.",
"Error parsing Comment.",
"Error parsing Declaration.",
"Error document empty.",
"Error null (0) or unexpected EOF found in input stream.",
"Error parsing CDATA.",
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
};
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment