1
0
forked from 0ad/0ad

wchar_t/etc fixes

This was SVN commit r690.
This commit is contained in:
Ykkrosh 2004-07-10 20:33:42 +00:00
parent 4769a92894
commit 970685e82c
8 changed files with 190 additions and 117 deletions

View File

@ -394,23 +394,49 @@ void CGUI::DrawSprite(const CStr& SpriteName,
std::vector<SGUIImage>::const_iterator cit;
for (cit=Sprite.m_Images.begin(); cit!=Sprite.m_Images.end(); ++cit)
{
if (cit->m_Texture)
{
// HACK: Please ignore all this texture code
glEnable(GL_TEXTURE_2D);
glDisable(GL_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Urgh
Handle x = tex_load(cit->m_TextureName);
assert(x>0);
tex_upload(x);
tex_bind(x);
glColor3f(1.0f, 1.0f, 1.0f);
}
else
{
glColor3f(cit->m_BackColor.r , cit->m_BackColor.g, cit->m_BackColor.b);
}
CRect real = cit->m_Size.GetClientArea(Rect);
glPushMatrix();
glTranslatef(0.f, 0.f, cit->m_DeltaZ);
glColor3f(cit->m_BackColor.r , cit->m_BackColor.g, cit->m_BackColor.b);
//glColor3f((float)real.right/1000.f, 0.5f, 0.5f);
// Do this
glBegin(GL_QUADS);
glVertex2i(real.right, real.bottom);
glVertex2i(real.left, real.bottom);
glVertex2i(real.left, real.top);
glVertex2i(real.right, real.top);
//glTexCoord2i(0, 1);
glVertex2i(real.right, real.bottom);
//glTexCoord2i(1, 1);
glVertex2i(real.left, real.bottom);
//glTexCoord2i(1, 0);
glVertex2i(real.left, real.top);
//glTexCoord2i(0, 0);
glVertex2i(real.right, real.top);
glEnd();
glPopMatrix();
if (cit->m_Texture)
{
glDisable(GL_TEXTURE_2D);
}
}
glPopMatrix();
}
@ -855,9 +881,9 @@ void CGUI::LoadXMLFile(const string &Filename)
// Check root element's (node) name so we know what kind of
// data we'll be expecting
std::wstring root_name = XeroFile.getElementString(node.getNodeName());
std::string root_name = XeroFile.getElementString(node.getNodeName());
if (root_name == L"objects")
if (root_name == "objects")
{
Xeromyces_ReadRootObjects(node, &XeroFile);
@ -865,17 +891,17 @@ void CGUI::LoadXMLFile(const string &Filename)
//UpdateResolution();
}
else
if (root_name == L"sprites")
if (root_name == "sprites")
{
Xeromyces_ReadRootSprites(node, &XeroFile);
}
else
if (root_name == L"styles")
if (root_name == "styles")
{
Xeromyces_ReadRootStyles(node, &XeroFile);
}
else
if (root_name == L"setup")
if (root_name == "setup")
{
Xeromyces_ReadRootSetup(node, &XeroFile);
}
@ -950,9 +976,9 @@ void CGUI::Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile)
// Read in this whole object into the GUI
std::wstring name = pFile->getElementString(child.getNodeName());
std::string name = pFile->getElementString(child.getNodeName());
if (name == L"scrollbar")
if (name == "scrollbar")
{
Xeromyces_ReadScrollBarStyle(child, pFile);
}
@ -971,7 +997,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
XMBAttributeList attributes = Element.getAttributes();
// Well first of all we need to determine the type
std::wstring type = attributes.getNamedItem( pFile->getAttributeID(L"type") );
std::wstring type = attributes.getNamedItem( pFile->getAttributeID("type") );
// Construct object from specified type
// henceforth, we need to do a rollback before aborting.
@ -988,8 +1014,8 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
}
// Cache some IDs for element attribute names, to avoid string comparisons
#define ELMT(x) int elmt_##x = pFile->getElementID(L#x)
#define ATTR(x) int attr_##x = pFile->getAttributeID(L#x)
#define ELMT(x) int elmt_##x = pFile->getElementID(#x)
#define ATTR(x) int attr_##x = pFile->getAttributeID(#x)
ELMT(object);
ELMT(action);
ATTR(style);
@ -1055,12 +1081,12 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
// Try setting the value
try
{
object->SetSetting(tocstr(pFile->getAttributeString(attr.Name)), tocstr(attr.Value));
object->SetSetting(pFile->getAttributeString(attr.Name), tocstr(attr.Value));
}
catch (PS_RESULT e)
{
UNUSED(e);
ReportParseError(CStr("Can't set \"") + tocstr(pFile->getAttributeString(attr.Name)) + CStr("\" to \"") + tocstr(attr.Value) + CStr("\""));
ReportParseError(CStr("Can't set \"") + pFile->getAttributeString(attr.Name) + CStr("\" to \"") + tocstr(attr.Value) + CStr("\""));
// This is not a fatal error
}
@ -1180,7 +1206,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile)
//
// Get name, we know it exists because of DTD requirements
name = tocstr( Element.getAttributes().getNamedItem( pFile->getAttributeID(L"name") ) );
name = tocstr( Element.getAttributes().getNamedItem( pFile->getAttributeID("name") ) );
//
// Read Children (the images)
@ -1224,16 +1250,16 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
for (int i=0; i<attributes.Count; ++i)
{
XMBAttribute attr = attributes.item(i);
std::wstring attr_name = pFile->getAttributeString(attr.Name);
std::string attr_name = pFile->getAttributeString(attr.Name);
CStr attr_value = tocstr( attr.Value );
// This is the only attribute we want
if (attr_name == L"texture")
if (attr_name == "texture")
{
image.m_Texture = attr_value;
image.m_TextureName = attr_value;
}
else
if (attr_name == L"size")
if (attr_name == "size")
{
CClientArea ca;
if (!GUI<CClientArea>::ParseString(attr_value, ca))
@ -1243,7 +1269,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
else image.m_Size = ca;
}
else
if (attr_name == L"z-level")
if (attr_name == "z-level")
{
int z_level;
if (!GUI<int>::ParseString(attr_value, z_level))
@ -1253,7 +1279,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
else image.m_DeltaZ = (float)z_level/100.f;
}
else
if (attr_name == L"backcolor")
if (attr_name == "backcolor")
{
CColor color;
if (!GUI<CColor>::ParseString(attr_value, color))
@ -1292,15 +1318,15 @@ void CGUI::Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile)
for (int i=0; i<attributes.Count; ++i)
{
XMBAttribute attr = attributes.item(i);
std::wstring attr_name = pFile->getAttributeString(attr.Name);
std::string attr_name = pFile->getAttributeString(attr.Name);
CStr attr_value = tocstr( attr.Value );
// The "name" setting is actually the name of the style
// and not a new default
if (attr_name == L"name")
if (attr_name == "name")
name = attr_value;
else
style.m_SettingsDefaults[tocstr(attr_name)] = attr_value;
style.m_SettingsDefaults[attr_name] = attr_value;
}
//
@ -1325,16 +1351,16 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
for (int i=0; i<attributes.Count; ++i)
{
XMBAttribute attr = attributes.item(i);
std::wstring attr_name = pFile->getAttributeString(attr.Name);
std::string attr_name = pFile->getAttributeString(attr.Name);
CStr attr_value = tocstr( attr.Value );
if (attr_value == CStr("null"))
continue;
if (attr_name == L"name")
if (attr_name == "name")
name = attr_value;
else
if (attr_name == L"width")
if (attr_name == "width")
{
int i;
if (!GUI<int>::ParseString(attr_value, i))
@ -1344,7 +1370,7 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
scrollbar.m_Width = i;
}
else
if (attr_name == L"minimum-bar-size")
if (attr_name == "minimum-bar-size")
{
int i;
if (!GUI<int>::ParseString(attr_value, i))
@ -1354,40 +1380,40 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
scrollbar.m_MinimumBarSize = i;
}
else
if (attr_name == L"sprite-button-top")
if (attr_name == "sprite-button-top")
scrollbar.m_SpriteButtonTop = attr_value;
else
if (attr_name == L"sprite-button-top-pressed")
if (attr_name == "sprite-button-top-pressed")
scrollbar.m_SpriteButtonTopPressed = attr_value;
else
if (attr_name == L"sprite-button-top-disabled")
if (attr_name == "sprite-button-top-disabled")
scrollbar.m_SpriteButtonTopDisabled = attr_value;
else
if (attr_name == L"sprite-button-top-over")
if (attr_name == "sprite-button-top-over")
scrollbar.m_SpriteButtonTopOver = attr_value;
else
if (attr_name == L"sprite-button-bottom")
if (attr_name == "sprite-button-bottom")
scrollbar.m_SpriteButtonBottom = attr_value;
else
if (attr_name == L"sprite-button-bottom-pressed")
if (attr_name == "sprite-button-bottom-pressed")
scrollbar.m_SpriteButtonBottomPressed = attr_value;
else
if (attr_name == L"sprite-button-bottom-disabled")
if (attr_name == "sprite-button-bottom-disabled")
scrollbar.m_SpriteButtonBottomDisabled = attr_value;
else
if (attr_name == L"sprite-button-bottom-over")
if (attr_name == "sprite-button-bottom-over")
scrollbar.m_SpriteButtonBottomOver = attr_value;
else
if (attr_name == L"sprite-back-vertical")
if (attr_name == "sprite-back-vertical")
scrollbar.m_SpriteBackVertical = attr_value;
else
if (attr_name == L"sprite-bar-vertical")
if (attr_name == "sprite-bar-vertical")
scrollbar.m_SpriteBarVertical = attr_value;
else
if (attr_name == L"sprite-bar-vertical-over")
if (attr_name == "sprite-bar-vertical-over")
scrollbar.m_SpriteBarVerticalOver = attr_value;
else
if (attr_name == L"sprite-bar-vertical-pressed")
if (attr_name == "sprite-bar-vertical-pressed")
scrollbar.m_SpriteBarVerticalPressed = attr_value;
/*

View File

@ -27,6 +27,7 @@ gee@pyro.nu
//--------------------------------------------------------
#include "GUI.h"
#include "Overlay.h"
#include "lib/res/tex.h"
//--------------------------------------------------------
// Macros
@ -52,10 +53,15 @@ gee@pyro.nu
*/
struct SGUIImage
{
SGUIImage() : m_Border(false), m_DeltaZ(0.f) {}
~SGUIImage() {}
SGUIImage() : m_Texture(0), m_Border(false), m_DeltaZ(0.f) {}
~SGUIImage()
{
if (m_Texture)
tex_free(m_Texture);
}
CStr m_Texture;
CStr m_TextureName;
Handle m_Texture;
// Image placement
CClientArea m_Size;

View File

@ -41,7 +41,7 @@
# define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#include "lib/crc32.h"
#include "zlib.h" // for crc32
#include "res/h_mgr.h"
#include "lib.h"
@ -78,7 +78,7 @@ public:
int OpenFile(const char *path);
// Calculate the CRC32 checksum of the file's contents
unsigned long CRC32() { return crc32_calculate((char*)m_pBuffer, (int)m_BufferSize); }
unsigned long CRC32(unsigned long seed) { return crc32(seed, (Bytef*)m_pBuffer, (int)m_BufferSize); }
virtual BinInputStream *makeStream() const;
};

View File

@ -1,14 +1,18 @@
// $Id: XeroXMB.cpp,v 1.1 2004/07/08 15:21:42 philip Exp $
// $Id: XeroXMB.cpp,v 1.2 2004/07/10 20:33:00 philip Exp $
#include "precompiled.h"
#include "Xeromyces.h"
#include "ps/utf16string.h"
#include <assert.h>
const int HeaderMagic = 0x30424D58; // = "XMB0" (little-endian)
const char* HeaderMagicStr = "XMB0";
typedef std::utf16string::value_type char16;
// Warning: May contain traces of pointer abuse
void XMBFile::Initialise(char* FileData)
@ -25,11 +29,11 @@ void XMBFile::Initialise(char* FileData)
// Build a std::map of all the names->ids
int ElementNameCount = *(int*)m_Pointer; m_Pointer += 4;
for (i = 0; i < ElementNameCount; ++i)
m_ElementNames[ReadZStr()] = i;
m_ElementNames[ReadZStrA()] = i;
int AttributeNameCount = *(int*)m_Pointer; m_Pointer += 4;
for (i = 0; i < AttributeNameCount; ++i)
m_AttributeNames[ReadZStr()] = i;
m_AttributeNames[ReadZStrA()] = i;
#else
// Ignore all the names for now, and skip over them
// (remembering the position of the first)
@ -46,11 +50,11 @@ void XMBFile::Initialise(char* FileData)
}
std::wstring XMBFile::ReadZStr()
std::string XMBFile::ReadZStrA()
{
int Length = *(int*)m_Pointer;
m_Pointer += 4;
std::wstring String ((wchar_t*)m_Pointer);
std::string String (m_Pointer); // reads up until the first NULL
m_Pointer += Length;
return String;
}
@ -63,30 +67,30 @@ XMBElement XMBFile::getRoot()
#ifdef XERO_USEMAP
int XMBFile::getElementID(const wchar_t* Name)
int XMBFile::getElementID(const char* Name)
{
return m_ElementNames[Name];
}
int XMBFile::getAttributeID(const wchar_t* Name)
int XMBFile::getAttributeID(const char* Name)
{
return m_AttributeNames[Name];
}
#else // #ifdef XERO_USEMAP
int XMBFile::getElementID(const wchar_t* Name)
int XMBFile::getElementID(const char* Name)
{
char* Pos = m_ElementPointer;
int len = ((int)wcslen(Name)+1)<<1; // count bytes, including null terminator
int len = (int)strlen(Name)+1; // count bytes, including null terminator
// Loop through each string to find a match
for (int i = 0; i < m_ElementNameCount; ++i)
{
// See if this could be the right string, checking its
// length and then its contents
if (*(int*)Pos == len && memcmp((wchar_t*)(Pos+4), Name, len) == 0)
if (*(int*)Pos == len && memcmp(Pos+4, Name, len) == 0)
return i;
// If not, jump to the next string
Pos += 4 + *(int*)Pos;
@ -95,18 +99,18 @@ int XMBFile::getElementID(const wchar_t* Name)
return -1;
}
int XMBFile::getAttributeID(const wchar_t* Name)
int XMBFile::getAttributeID(const char* Name)
{
char* Pos = m_AttributePointer;
int len = ((int)wcslen(Name)+1)<<1; // count bytes, including null terminator
int len = (int)strlen(Name)+1; // count bytes, including null terminator
// Loop through each string to find a match
for (int i = 0; i < m_AttributeNameCount; ++i)
{
// See if this could be the right string, checking its
// length and then its contents
if (*(int*)Pos == len && memcmp((wchar_t*)(Pos+4), Name, len) == 0)
if (*(int*)Pos == len && memcmp(Pos+4, Name, len) == 0)
return i;
// If not, jump to the next string
Pos += 4 + *(int*)Pos;
@ -119,20 +123,20 @@ int XMBFile::getAttributeID(const wchar_t* Name)
// Relatively inefficient, so only use when
// laziness overcomes the need for speed
std::wstring XMBFile::getElementString(const int ID)
std::string XMBFile::getElementString(const int ID)
{
char* Pos = m_ElementPointer;
for (int i = 0; i < ID; ++i)
Pos += 4 + *(int*)Pos;
return std::wstring((wchar_t*)(Pos+4));
return std::string(Pos+4);
}
std::wstring XMBFile::getAttributeString(const int ID)
std::string XMBFile::getAttributeString(const int ID)
{
char* Pos = m_AttributePointer;
for (int i = 0; i < ID; ++i)
Pos += 4 + *(int*)Pos;
return std::wstring((wchar_t*)(Pos+4));
return std::string(Pos+4);
}
@ -158,9 +162,9 @@ XMBAttributeList XMBElement::getAttributes()
);
}
std::wstring XMBElement::getText()
std::utf16string XMBElement::getText()
{
return std::wstring((wchar_t*)(m_Pointer + 24)); // == Text
return std::utf16string((char16*)(m_Pointer + 24));
}
@ -190,7 +194,7 @@ XMBElement XMBElementList::item(const int id)
return XMBElement(Pos);
}
std::wstring XMBAttributeList::getNamedItem(const int AttributeName)
std::utf16string XMBAttributeList::getNamedItem(const int AttributeName)
{
char* Pos = m_Pointer;
@ -199,12 +203,12 @@ std::wstring XMBAttributeList::getNamedItem(const int AttributeName)
for (int i = 0; i < Count; ++i)
{
if (*(int*)Pos == AttributeName)
return std::wstring((wchar_t*)(Pos+8));
return std::utf16string((char16*)(Pos+8));
Pos += 8 + *(int*)(Pos+4); // Skip over the string
}
// Can't find attribute
return std::wstring(L"");
return std::utf16string();
}
XMBAttribute XMBAttributeList::item(const int id)
@ -231,17 +235,17 @@ XMBAttribute XMBAttributeList::item(const int id)
m_LastItemID = id;
m_LastPointer = Pos;
return XMBAttribute(*(int*)Pos, std::wstring((wchar_t*)(Pos+8)));
return XMBAttribute(*(int*)Pos, std::utf16string( (char16*)(Pos+8) ));
}
// Temporary hackiness. (Could CStr do automatic conversions?)
CStr tocstr(std::wstring s)
CStr tocstr(std::utf16string s)
{
size_t len = s.size();
char* s2 = new char[len+1];
const wchar_t* s1 = s.c_str();
const char16* s1 = s.c_str();
for (size_t i=0; i<=len; ++i)
s2[i] = (char)s1[i];
CStr r(s2);

View File

@ -1,4 +1,4 @@
/* $Id: XeroXMB.h,v 1.1 2004/07/08 15:21:42 philip Exp $
/* $Id: XeroXMB.h,v 1.2 2004/07/10 20:33:00 philip Exp $
Xeromyces - XMB reading library
@ -36,10 +36,10 @@ XMB_File {
int Checksum; // CRC32 of original XML file, to detect changes
int ElementNameCount;
XMB_ZStr ElementNames[];
ZStrA ElementNames[];
int AttributeNameCount;
ZStr AttributeNames[];
ZStrA AttributeNames[];
XMB_Node Root;
}
@ -53,7 +53,7 @@ XMB_Node {
12) int ChildCount;
16) int ChildrenOffset; // == sizeof(Text)+sizeof(Attributes)
20) ZStr Text;
20) ZStrW Text;
XMB_Attribute Attributes[];
XMB_Node Children[];
@ -61,12 +61,17 @@ XMB_Node {
XMB_Attribute {
int Name;
XMB_ZStr Value;
ZStrW Value;
}
XMB_ZStr {
int Length; // in bytes (always a multiple of 2)
wchar_t* Text; // null-terminated, UTF16-LE
XMB_ZStrA {
int Length; // in bytes
char* Text; // null-terminated ASCII
}
XMB_ZStrW {
int Length; // in bytes
char* Text; // null-terminated UTF16
}
@ -81,6 +86,8 @@ XMB_ZStr {
#include <string>
#include "ps/utf16string.h"
#ifdef XERO_USEMAP
# include <map>
#endif
@ -109,23 +116,22 @@ public:
XMBElement getRoot();
// Returns internal ID for a given element/attribute string.
// Use getElementID(L"name") to get a wchar_t*
int getElementID(const wchar_t* Name);
int getAttributeID(const wchar_t* Name);
// Returns internal ID for a given ASCII element/attribute string.
int getElementID(const char* Name);
int getAttributeID(const char* Name);
// For lazy people (e.g. me) when speed isn't vital:
// Returns element/attribute string for a given internal ID
std::wstring getElementString(const int ID);
std::wstring getAttributeString(const int ID);
std::string getElementString(const int ID);
std::string getAttributeString(const int ID);
private:
char* m_Pointer;
#ifdef XERO_USEMAP
std::map<std::wstring, int> m_ElementNames;
std::map<std::wstring, int> m_AttributeNames;
std::map<std::string, int> m_ElementNames;
std::map<std::string, int> m_AttributeNames;
#else
int m_ElementNameCount;
int m_AttributeNameCount;
@ -133,7 +139,7 @@ private:
char* m_AttributePointer;
#endif
std::wstring ReadZStr();
std::string ReadZStrA();
};
class XMBElement
@ -142,10 +148,10 @@ public:
XMBElement(char* offset)
: m_Pointer(offset) {}
int getNodeName(); // == ElementName
int getNodeName();
XMBElementList getChildNodes();
XMBAttributeList getAttributes();
std::wstring getText();
std::utf16string getText();
private:
// Pointer to the start of the node
@ -175,11 +181,11 @@ private:
struct XMBAttribute
{
XMBAttribute(int name, std::wstring value)
XMBAttribute(int name, std::utf16string value)
: Name(name), Value(value) {};
int Name;
std::wstring Value;
std::utf16string Value;
};
class XMBAttributeList
@ -189,7 +195,7 @@ public:
: Count(count), m_Pointer(offset) {};
// Get the attribute value directly (unlike Xerces)
std::wstring getNamedItem(const int AttributeName);
std::utf16string getNamedItem(const int AttributeName);
// Returns an attribute by position in the list
XMBAttribute item(const int id);
@ -208,6 +214,6 @@ private:
#include "ps/CStr.h"
CStr tocstr(std::wstring s);
CStr tocstr(std::utf16string s);
#endif // _XEROXMB_H_

View File

@ -1,4 +1,4 @@
// $Id: Xeromyces.cpp,v 1.3 2004/07/10 18:57:13 olsner Exp $
// $Id: Xeromyces.cpp,v 1.4 2004/07/10 20:33:00 philip Exp $
#include "precompiled.h"
@ -95,13 +95,13 @@ private:
// Convenient storage for the internal tree
typedef struct {
std::wstring name;
std::wstring value;
std::string name;
std::utf16string value;
} XMLAttribute;
typedef struct XMLElement {
std::wstring name;
std::wstring text;
std::string name;
std::utf16string text;
std::vector<XMLElement*> childs;
std::vector<XMLAttribute*> attrs;
} XMLElement;
@ -122,14 +122,14 @@ public:
void CreateXMB(unsigned long crc);
membuffer buffer;
private:
std::set<std::wstring> ElementNames;
std::set<std::wstring> AttributeNames;
std::set<std::string> ElementNames;
std::set<std::string> AttributeNames;
XMLElement* Root;
XMLElement* CurrentElement;
std::stack<XMLElement*> ElementStack;
std::map<std::wstring, int> ElementID;
std::map<std::wstring, int> AttributeID;
std::map<std::string, int> ElementID;
std::map<std::string, int> AttributeID;
void OutputElement(XMLElement* el);
};
@ -186,7 +186,12 @@ void CXeromyces::Load(const char* filename)
LOG(ERROR, "CXeromyces: Failed to load XML file '%s'", filename);
throw "Failed to load XML file";
}
unsigned long XMLChecksum = source.CRC32();
// Start the checksum with a particular seed value, so the XMBs will
// be recreated whenever the version/etc string has been changed, so
// the string can be changed whenever the file format's changed.
const char* ChecksumID = "version A";
unsigned long XMLChecksum = source.CRC32( crc32( crc32(0L, Z_NULL, 0), (Bytef*)ChecksumID, (int)strlen(ChecksumID) ) );
// Check whether the XMB file needs to be regenerated:
@ -309,6 +314,7 @@ void XeroHandler::endDocument()
{
}
/*
std::wstring lowercase(const XMLCh *a)
{
std::wstring b;
@ -318,10 +324,22 @@ std::wstring lowercase(const XMLCh *a)
b[i] = towlower(a[i]);
return b;
}
*/
// Silently clobbers non-ASCII characters
std::string lowercase_ascii(const XMLCh *a)
{
std::string b;
uint len=XMLString::stringLen(a);
b.resize(len);
for (uint i = 0; i < len; ++i)
b[i] = (char)towlower(a[i]);
return b;
}
void XeroHandler::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs)
{
std::wstring elementName = lowercase(localname);
std::string elementName = lowercase_ascii(localname);
ElementNames.insert(elementName);
// Create a new element
@ -331,12 +349,12 @@ void XeroHandler::startElement(const XMLCh* const uri, const XMLCh* const localn
// Store all the attributes in the new element
for (unsigned int i = 0; i < attrs.getLength(); ++i)
{
std::wstring attrName = lowercase(attrs.getLocalName(i));
std::string attrName = lowercase_ascii(attrs.getLocalName(i));
AttributeNames.insert(attrName);
XMLAttribute* a = new XMLAttribute;
a->name = attrName;
const XMLCh *tmp = attrs.getValue(i);
a->value = std::wstring(tmp, tmp+XMLString::stringLen(tmp));
a->value = std::utf16string(tmp, tmp+XMLString::stringLen(tmp));
e->attrs.push_back(a);
}
@ -354,7 +372,7 @@ void XeroHandler::endElement(const XMLCh* const uri, const XMLCh* const localnam
void XeroHandler::characters(const XMLCh* const chars, const unsigned int length)
{
ElementStack.top()->text += std::wstring(chars, chars+XMLString::stringLen(chars));
ElementStack.top()->text += std::utf16string(chars, chars+XMLString::stringLen(chars));
}
@ -366,7 +384,7 @@ void XeroHandler::CreateXMB(unsigned long crc)
// Checksum
buffer.write(&crc, 4);
std::set<std::wstring>::iterator it;
std::set<std::string>::iterator it;
int i;
// Element names
@ -375,7 +393,7 @@ void XeroHandler::CreateXMB(unsigned long crc)
buffer.write(&ElementCount, 4);
for (it = ElementNames.begin(); it != ElementNames.end(); ++it)
{
int TextLen = 2*((int)it->length()+1);
int TextLen = (int)it->length()+1;
buffer.write(&TextLen, 4);
buffer.write((void*)it->c_str(), TextLen);
ElementID[*it] = i++;
@ -387,7 +405,7 @@ void XeroHandler::CreateXMB(unsigned long crc)
buffer.write(&AttributeCount, 4);
for (it = AttributeNames.begin(); it != AttributeNames.end(); ++it)
{
int TextLen = 2*((int)it->length()+1);
int TextLen = (int)it->length()+1;
buffer.write(&TextLen, 4);
buffer.write((void*)it->c_str(), TextLen);
AttributeID[*it] = i++;
@ -422,10 +440,11 @@ void XeroHandler::OutputElement(XMLElement* el)
buffer.write("????", 4);
// Trim excess whitespace
std::wstring whitespace = L" \t\r\n";
std::wstring whitespaceW = L" \t\r\n";
std::utf16string whitespace (whitespaceW.begin(), whitespaceW.end());
size_t first = el->text.find_first_not_of(whitespace);
if (first == -1) // entirely whitespace
el->text = L"";
el->text = std::utf16string();
else
{
size_t last = el->text.find_last_not_of(whitespace);

View File

@ -5,6 +5,16 @@
#ifndef utf16string_H
#define utf16string_H
// On Windows, wchar_t is 16-bit, so just use std::wstring
#ifdef _MSC_VER
namespace std {
typedef wstring utf16string;
}
// On Linux, wchar_t is 32-bit, so define a new version of it
#else
#include <string>
#include "types.h"
@ -89,4 +99,6 @@ namespace std {
};
}
#endif // #ifdef _MSC_VER / #else
#endif

View File

@ -39,8 +39,8 @@ bool CBaseEntity::loadXML( CStr filename )
}
// Define all the elements and attributes used in the XML file
#define EL(x) int el_##x = XeroFile.getElementID(L#x)
#define AT(x) int at_##x = XeroFile.getAttributeID(L#x)
#define EL(x) int el_##x = XeroFile.getElementID(#x)
#define AT(x) int at_##x = XeroFile.getAttributeID(#x)
EL(entity);
EL(name);
EL(actor);