0ad/source/ps/XML/XeroXMB.h
janwas b755ddefda remove all author/modified by tags.
make include guards consistent.

This was SVN commit r5040.
2007-05-07 16:33:24 +00:00

226 lines
4.7 KiB
C++

/*
Xeromyces - XMB reading library
*/
/*
Brief outline:
XMB is a binary representation of XML, with some limitations
but much more efficiency (particularly for loading simple data
classes that don't need much initialisation).
Main limitations:
* Only handles UTF16 internally. (It's meant to be a feature, but
can be detrimental if it's always being converted back to
ASCII.)
* Can't correctly handle mixed text/elements inside elements -
"<div> <b> Text </b> </div>" and "<div> Te<b/>xt </div>" are
considered identical.
* Tries to avoid using strings - you usually have to load the
numeric IDs and use them instead.
* Case-sensitive (but converts all element/attribute names in
the XML file to lowercase, so you only have to be careful in
the code)
Theoretical file structure:
XMB_File {
char Header[4]; // because everyone has one; currently "XMB0"
int ElementNameCount;
ZStrA ElementNames[];
int AttributeNameCount;
ZStrA AttributeNames[];
XMB_Node Root;
}
XMB_Node {
0) int Length; // of entire struct, so it can be skipped over
4) int ElementName;
8) int AttributeCount;
12) int ChildCount;
16) int ChildrenOffset; // == sizeof(Text)+sizeof(Attributes)
20) XMB_Text Text;
XMB_Attribute Attributes[];
XMB_Node Children[];
}
XMB_Attribute {
int Name;
ZStrW Value;
}
ZStrA {
int Length; // in bytes
char* Text; // null-terminated ASCII
}
ZStrW {
int Length; // in bytes
char16* Text; // null-terminated UTF16
}
XMB_Text {
20) int Length; // 0 if there's no text, else 4+sizeof(Text) in bytes including terminator
// If Length != 0:
24) int LineNumber; // for e.g. debugging scripts
28) char16* Text; // null-terminated UTF16
}
*/
#ifndef INCLUDED_XEROXMB
#define INCLUDED_XEROXMB
// Define to use a std::map for name lookups rather than a linear search.
// (The map is usually slower.)
//#define XERO_USEMAP
#include <string>
#include "ps/utf16string.h"
#ifdef XERO_USEMAP
# include <map>
#endif
// File headers, to make sure it doesn't try loading anything other than an XMB
extern const u32 HeaderMagic;
extern const char* HeaderMagicStr;
class XMBElement;
class XMBElementList;
class XMBAttributeList;
class XMBFile
{
public:
XMBFile() : m_Pointer(NULL) {}
// Initialise from the contents of an XMB file.
// FileData must remain allocated and unchanged while
// the XMBFile is being used.
void Initialise(const char* FileData);
// Returns the root element
XMBElement GetRoot() const;
// Returns internal ID for a given ASCII element/attribute string.
int GetElementID(const char* Name) const;
int GetAttributeID(const char* Name) const;
// For lazy people (e.g. me) when speed isn't vital:
// Returns element/attribute string for a given internal ID
std::string GetElementString(const int ID) const;
std::string GetAttributeString(const int ID) const;
private:
const char* m_Pointer;
#ifdef XERO_USEMAP
std::map<std::string, int> m_ElementNames;
std::map<std::string, int> m_AttributeNames;
#else
int m_ElementNameCount;
int m_AttributeNameCount;
const char* m_ElementPointer;
const char* m_AttributePointer;
#endif
std::string ReadZStrA();
};
class XMBElement
{
public:
// janwas: default ctor needed for ReadXML
XMBElement()
: m_Pointer(0) {}
XMBElement(const char* offset)
: m_Pointer(offset) {}
int GetNodeName() const;
XMBElementList GetChildNodes() const;
XMBAttributeList GetAttributes() const;
utf16string GetText() const;
int GetLineNumber() const;
private:
// Pointer to the start of the node
const char* m_Pointer;
};
class XMBElementList
{
public:
// janwas: default ctor needed for ReadXML
XMBElementList()
: Count(0), m_Pointer(0), m_LastItemID(-2) {}
XMBElementList(const char* offset, int count)
: Count(count),
m_Pointer(offset),
m_LastItemID(-2) {} // use -2 because it isn't x-1 where x is a non-negative integer
XMBElement Item(const int id); // returns Children[id]
int Count;
private:
const char* m_Pointer;
// For optimised sequential access:
int m_LastItemID;
const char* m_LastPointer;
};
struct XMBAttribute
{
XMBAttribute() {}
XMBAttribute(int name, utf16string value)
: Name(name), Value(value) {};
int Name;
utf16string Value;
};
class XMBAttributeList
{
public:
XMBAttributeList(const char* offset, int count)
: Count(count), m_Pointer(offset), m_LastItemID(-2) {};
// Get the attribute value directly (unlike Xerces)
utf16string GetNamedItem(const int AttributeName) const;
// Returns an attribute by position in the list
XMBAttribute Item(const int id);
int Count;
private:
// Pointer to start of attribute list
const char* m_Pointer;
// For optimised sequential access:
int m_LastItemID;
const char* m_LastPointer;
};
#endif // INCLUDED_XEROXMB