aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/xml
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/xml')
-rw-r--r--Src/Wasabi/api/xml/LoadXML.cpp92
-rw-r--r--Src/Wasabi/api/xml/LoadXML.h7
-rw-r--r--Src/Wasabi/api/xml/XMLAutoInclude.cpp87
-rw-r--r--Src/Wasabi/api/xml/XMLAutoInclude.h22
-rw-r--r--Src/Wasabi/api/xml/api_xmlreadercallback.cpp2
-rw-r--r--Src/Wasabi/api/xml/xmlparams.cpp12
-rw-r--r--Src/Wasabi/api/xml/xmlparams.h103
-rw-r--r--Src/Wasabi/api/xml/xmlparamsi.cpp119
-rw-r--r--Src/Wasabi/api/xml/xmlparamsi.h52
-rw-r--r--Src/Wasabi/api/xml/xmlparamsx.cpp32
-rw-r--r--Src/Wasabi/api/xml/xmlparamsx.h38
-rw-r--r--Src/Wasabi/api/xml/xmlparse.h23
-rw-r--r--Src/Wasabi/api/xml/xmlreader.cpp197
-rw-r--r--Src/Wasabi/api/xml/xmlreader.h75
-rw-r--r--Src/Wasabi/api/xml/xmlwrite.cpp262
-rw-r--r--Src/Wasabi/api/xml/xmlwrite.h45
16 files changed, 1168 insertions, 0 deletions
diff --git a/Src/Wasabi/api/xml/LoadXML.cpp b/Src/Wasabi/api/xml/LoadXML.cpp
new file mode 100644
index 00000000..35709227
--- /dev/null
+++ b/Src/Wasabi/api/xml/LoadXML.cpp
@@ -0,0 +1,92 @@
+#include <precomp.h>
+#include "LoadXML.h"
+#include <bfc/file/wildcharsenum.h>
+#include <wchar.h>
+
+void LoadXmlServiceProvider(obj_xml *parser, const wchar_t *filename)
+{
+ /* TODO:
+ svc = XmlProviderEnum(filename).getNext();
+ pbuf = svc->getXmlData(filename, incpath, &p);
+ SvcEnum::release(svc);
+ svc = NULL;
+ */
+}
+
+// when filename begins with "buf:"
+void LoadXmlBuffer(obj_xml *parser, const wchar_t *filename)
+{
+ filename += 4;
+ if (parser->xmlreader_feed((void *)filename, wcslen(filename)*sizeof(wchar_t)) == API_XML_SUCCESS)
+ parser->xmlreader_feed(0, 0);
+}
+
+bool LoadXmlFilename(obj_xml *parser, const wchar_t *filename)
+{
+ OSFILETYPE file = WFOPEN(filename, WF_READONLY_BINARY, NO_FILEREADERS);
+// HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
+
+// if (file == INVALID_HANDLE_VALUE)
+ if (file == OPEN_FAILED)
+ return false;
+
+ size_t bytesRead=0;
+ do
+ {
+ char data[4096] = {0};
+ bytesRead = FREAD(data, 1, sizeof(data), file);
+// if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
+ if (bytesRead)
+ {
+ if (parser->xmlreader_feed(data, bytesRead)!=API_XML_SUCCESS)
+ {
+// CloseHandle(file);
+ FCLOSE(file);
+ return false;
+ }
+ }
+ else
+ {
+ if (parser->xmlreader_feed(0, 0) != API_XML_SUCCESS)
+ {
+ FCLOSE(file);
+// CloseHandle(file);
+ return false;
+ }
+ bytesRead=0;
+ }
+ } while (bytesRead);
+
+ FCLOSE(file);
+// CloseHandle(file);
+ return true;
+}
+
+/*** TODO:
+ ** move this to a separate file
+ ** deal with wildcard filenames (e.g. *.xml)
+ */
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename)
+{
+ if (!WCSNICMP(filename, L"buf:", 4))
+ {
+ LoadXmlBuffer(parser, filename);
+ return ;
+ }
+ WildcharsEnumerator e(filename);
+
+ if (e.getNumFiles() > 0) // if we're including multiple files
+ {
+ for (int i = 0;i < e.getNumFiles();i++)
+ {
+ if (i) // don't reset the first time around
+ parser->xmlreader_reset();
+ LoadXmlFilename(parser, e.enumFile(i));
+ }
+ }
+ else if (!LoadXmlFilename(parser, filename))
+ {
+ LoadXmlServiceProvider(parser, filename);
+ return ;
+ }
+}
diff --git a/Src/Wasabi/api/xml/LoadXML.h b/Src/Wasabi/api/xml/LoadXML.h
new file mode 100644
index 00000000..8e6ef2c3
--- /dev/null
+++ b/Src/Wasabi/api/xml/LoadXML.h
@@ -0,0 +1,7 @@
+#ifndef NULLSOFT_WASABI_LOADXML_H
+#define NULLSOFT_WASABI_LOADXML_H
+
+#include "../xml/obj_xml.h"
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/XMLAutoInclude.cpp b/Src/Wasabi/api/xml/XMLAutoInclude.cpp
new file mode 100644
index 00000000..8821fe4d
--- /dev/null
+++ b/Src/Wasabi/api/xml/XMLAutoInclude.cpp
@@ -0,0 +1,87 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include "XMLAutoInclude.h"
+#include <bfc/file/wildcharsenum.h>
+#include <api/util/varmgr.h>
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+XMLAutoInclude::XMLAutoInclude(obj_xml *_parser, const wchar_t *_path)
+{
+ path=_path;
+ parser = _parser;
+ if (parser)
+ {
+ parser->xmlreader_registerCallback(L"*\finclude", this);
+ }
+}
+
+XMLAutoInclude::~XMLAutoInclude()
+{
+ if (parser)
+ {
+ parser->xmlreader_unregisterCallback(this);
+ }
+}
+static const wchar_t *varmgr_translate(const wchar_t *str)
+{
+ static StringW ret;
+ StringW *s = PublicVarManager::translate_nocontext(str);
+ if (s)
+ {
+ ret.swap(s);
+ delete s;
+ return ret.getValueSafe();
+ }
+ return str;
+}
+void XMLAutoInclude::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *includeFile = params->getItemValue(L"file");
+ const wchar_t *trans = /*WASABI_API_WNDMGR->*/varmgr_translate(includeFile);
+ if (trans)
+ {
+ //const char *path = WASABI_API_SKIN->getSkinsPath();
+ if (!Wasabi::Std::isRootPath(trans))
+ includeFn=StringPathCombine(path, trans);
+ else
+ includeFn=trans;
+ }
+
+}
+
+void XMLAutoInclude::Include(const wchar_t *filename)
+{
+ if (filename && *filename)
+ {
+ parser->xmlreader_interrupt();
+ StringW oldPath = path;
+
+ const wchar_t *file = Wasabi::Std::filename(filename);
+ int fnlen = wcslen(file);
+ path = filename;
+ path.trunc(-fnlen);
+ LoadXmlFile(parser, filename);
+ path = oldPath;
+ parser->xmlreader_resume();
+ }
+}
+
+void XMLAutoInclude::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ if (!includeFn.isempty())
+ {
+ WildcharsEnumerator e(includeFn);
+ if (e.getNumFiles() > 0) // if we're including multiple files
+ {
+ for (int i = 0;i < e.getNumFiles();i++)
+ {
+ Include(e.enumFile(i));
+ }
+ }
+ else
+ Include(includeFn);
+ }
+
+}
+
diff --git a/Src/Wasabi/api/xml/XMLAutoInclude.h b/Src/Wasabi/api/xml/XMLAutoInclude.h
new file mode 100644
index 00000000..8b3df85e
--- /dev/null
+++ b/Src/Wasabi/api/xml/XMLAutoInclude.h
@@ -0,0 +1,22 @@
+#ifndef NULLSOFT_WASABI_XMLAUTOINCLUDE_H
+#define NULLSOFT_WASABI_XMLAUTOINCLUDE_H
+
+#include "../xml/obj_xml.h"
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <bfc/string/StringW.h>
+
+class XMLAutoInclude : public ifc_xmlreadercallbackI
+{
+public:
+ XMLAutoInclude(obj_xml *_parser, const wchar_t *_path);
+ ~XMLAutoInclude();
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+//private:
+ obj_xml *parser;
+ StringW path, includeFn;
+private:
+ void Include(const wchar_t *filename);
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/api_xmlreadercallback.cpp b/Src/Wasabi/api/xml/api_xmlreadercallback.cpp
new file mode 100644
index 00000000..c6741d87
--- /dev/null
+++ b/Src/Wasabi/api/xml/api_xmlreadercallback.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include <api/xml/ifc_xmlreadercallback.h>
diff --git a/Src/Wasabi/api/xml/xmlparams.cpp b/Src/Wasabi/api/xml/xmlparams.cpp
new file mode 100644
index 00000000..c8570eee
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparams.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparams.cpp
+// Class : ifc_xmlreaderparams
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "xmlparams.h"
+
+
diff --git a/Src/Wasabi/api/xml/xmlparams.h b/Src/Wasabi/api/xml/xmlparams.h
new file mode 100644
index 00000000..06d915a7
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparams.h
@@ -0,0 +1,103 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparams.h
+// Class : skin_xmlreaderparams
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __XMLREADERPARAMS_H
+#define __XMLREADERPARAMS_H
+
+#include <bfc/dispatch.h>
+//#include <bfc/common.h>
+#include "../xml/ifc_xmlreaderparams.h"
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE skin_xmlreaderparams : public ifc_xmlreaderparams
+{
+ protected:
+ skin_xmlreaderparams() {}
+ ~skin_xmlreaderparams() {}
+ public:
+ /*
+ const wchar_t *getItemName(int i);
+ const wchar_t *getItemValue(int i);
+ const wchar_t *getItemValue(const wchar_t *name);
+ const wchar_t *enumItemValues(const wchar_t *name, int nb);
+ int getItemValueInt(const wchar_t *name, int def = 0);
+ int getNbItems();
+ */
+ void addItem(const wchar_t *parm, const wchar_t *value);
+ void removeItem(const wchar_t *parm);
+ void replaceItem(const wchar_t *parm, const wchar_t *value);
+ int findItem(const wchar_t *parm);
+
+ protected:
+ enum {
+ /*XMLREADERPARAMS_GETITEMNAME = 100,
+ XMLREADERPARAMS_GETITEMVALUE = 200,
+ XMLREADERPARAMS_GETITEMVALUE2 = 201,
+ XMLREADERPARAMS_ENUMITEMVALUES = 202,
+ XMLREADERPARAMS_GETITEMVALUEINT = 300,
+ XMLREADERPARAMS_GETNBITEMS = 400,*/
+ XMLREADERPARAMS_ADDITEM = 500,
+ XMLREADERPARAMS_REMOVEITEM = 600,
+ XMLREADERPARAMS_REPLACEITEM = 700,
+ XMLREADERPARAMS_FINDITEM = 800,
+ };
+};
+
+// ----------------------------------------------------------------------------
+/*
+inline const wchar_t *skin_xmlreaderparams::getItemName(int i) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMNAME, (const wchar_t *)0, i);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::getItemValue(int i) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMVALUE, (const wchar_t *)0, i);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::getItemValue(const wchar_t *name) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMVALUE2, (const wchar_t *)0, name);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::enumItemValues(const wchar_t *name, int nb) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_ENUMITEMVALUES, (const wchar_t *)0, name, nb);
+ return __retval;
+}
+
+inline int skin_xmlreaderparams::getItemValueInt(const wchar_t *name, int def) {
+ int __retval = _call(XMLREADERPARAMS_GETITEMVALUEINT, (int)0, name, def);
+ return __retval;
+}
+
+inline int skin_xmlreaderparams::getNbItems() {
+ int __retval = _call(XMLREADERPARAMS_GETNBITEMS, (int)0);
+ return __retval;
+}
+*/
+inline void skin_xmlreaderparams::addItem(const wchar_t *parm, const wchar_t *value) {
+ _voidcall(XMLREADERPARAMS_ADDITEM, parm, value);
+}
+
+inline void skin_xmlreaderparams::removeItem(const wchar_t *parm) {
+ _voidcall(XMLREADERPARAMS_REMOVEITEM, parm);
+}
+
+inline void skin_xmlreaderparams::replaceItem(const wchar_t *parm, const wchar_t *value) {
+ _voidcall(XMLREADERPARAMS_REPLACEITEM, parm, value);
+}
+
+inline int skin_xmlreaderparams::findItem(const wchar_t *parm) {
+ int __retval = _call(XMLREADERPARAMS_FINDITEM, (int)0, parm);
+ return __retval;
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __XMLREADERPARAMS_H
diff --git a/Src/Wasabi/api/xml/xmlparamsi.cpp b/Src/Wasabi/api/xml/xmlparamsi.cpp
new file mode 100644
index 00000000..9ac7b711
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsi.cpp
@@ -0,0 +1,119 @@
+#include <precomp.h>
+#include "xmlparamsi.h"
+#include <bfc/wasabi_std.h>
+
+XmlReaderParamsI::~XmlReaderParamsI()
+{
+ parms_list.deleteAll();
+}
+
+const wchar_t *XmlReaderParamsI::getItemName(int i)
+{
+ if(i>getNbItems())
+ return L"";
+ return
+ parms_list[i]->parm;
+}
+
+
+const wchar_t *XmlReaderParamsI::getItemValue(int i)
+{
+ if(i>getNbItems())
+ return L"";
+ return
+ parms_list[i]->value;
+}
+
+const wchar_t *XmlReaderParamsI::getItemValue(const wchar_t *name)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ return parms_list[i]->value;
+ return NULL;
+}
+
+const wchar_t *XmlReaderParamsI::enumItemValues(const wchar_t *name, int nb)
+{
+ int f=0;
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ if(f==nb)
+ return parms_list[i]->value;
+ else f++;
+ return NULL;
+}
+
+int XmlReaderParamsI::getItemValueInt(const wchar_t *name, int def)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ {
+ // TODO: benski> do we want to return "def" when there's an empty value?
+ return WTOI(parms_list[i]->value);
+ }
+ return def;
+}
+
+
+int XmlReaderParamsI::getNbItems()
+{
+ return parms_list.getNumItems();
+}
+
+void XmlReaderParamsI::addItem(const wchar_t *parm, const wchar_t *value)
+{
+ parms_struct *p= new parms_struct;
+ p->parm = WCSDUP(parm);
+ p->ownValue = true;
+ p->value = value;
+ parms_list.addItem(p);
+}
+
+void XmlReaderParamsI::removeItem(const wchar_t *parm)
+{
+ for (int i=0;i<parms_list.getNumItems();i++)
+ {
+ parms_struct *s = parms_list.enumItem(i);
+ if (!WCSICMP(parm, s->parm))
+ {
+ delete s;
+ parms_list.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+void XmlReaderParamsI::replaceItem(const wchar_t *parm, const wchar_t *value)
+{
+ if (!value)
+ {
+ removeItem(parm);
+ return;
+ }
+
+ StringW s = value; // if we were passed our current value's pointer ...
+
+ const wchar_t *curval = getItemValue(parm);
+ if (s.isequal(value) && curval) return; // (hey, if we're replacing with same value, forget about it, but only if we did have that value, because isequal will return true if curval is NULL and we pass it ("") )
+
+ removeItem(parm); // ... then this call would make the value param invalid ...
+
+ addItem(parm, s); // ... so we're sending a saved buffer instead
+}
+
+int XmlReaderParamsI::findItem(const wchar_t *parm)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, parm))
+ return i;
+ return -1;
+}
+
+ // calling this will destroy your String... here for optimization ...
+void XmlReaderParamsI::addItemSwapValue(const wchar_t *parm, StringW &value)
+{
+ parms_struct *p= new parms_struct;
+ p->parm = parm;
+ p->value.swap(&value);
+ parms_list.addItem(p);
+}
diff --git a/Src/Wasabi/api/xml/xmlparamsi.h b/Src/Wasabi/api/xml/xmlparamsi.h
new file mode 100644
index 00000000..606c462c
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsi.h
@@ -0,0 +1,52 @@
+#ifndef __XMLPARAMSI_H
+#define __XMLPARAMSI_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+/*<?<autoheader/>*/
+#include <api/xml/xmlparams.h>
+#include <api/xml/xmlparamsx.h>
+/*?>*/
+
+
+class XmlReaderParamsI : public XmlReaderParamsX
+{
+public:
+ XmlReaderParamsI() {}
+ virtual ~XmlReaderParamsI();
+
+ DISPATCH(100) const wchar_t *getItemName(int i);
+ DISPATCH(200) const wchar_t *getItemValue(int i);
+ DISPATCH(201) const wchar_t *getItemValue(const wchar_t *name);
+ DISPATCH(202) const wchar_t *enumItemValues(const wchar_t *name, int nb);
+ DISPATCH(300) int getItemValueInt(const wchar_t *name, int def = 0);
+ DISPATCH(400) int getNbItems();
+
+ DISPATCH(500) void addItem(const wchar_t *parm, const wchar_t *value);
+ DISPATCH(600) void removeItem(const wchar_t *parm);
+ DISPATCH(700) void replaceItem(const wchar_t *parm, const wchar_t *value);
+ DISPATCH(800) int findItem(const wchar_t *parm);
+
+ NODISPATCH void addItemSwapValue(const wchar_t *parm, StringW &value); // calling this will destroy your String... here for optimization ...
+private:
+ struct parms_struct
+ {
+ parms_struct() : parm(0), ownValue(false)
+ {}
+ ~parms_struct()
+ {
+ if (ownValue)
+ FREE((wchar_t *)parm);
+ }
+ const wchar_t *parm;
+ StringW value;
+ bool ownValue;
+ };
+ PtrList<parms_struct> parms_list;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlparamsx.cpp b/Src/Wasabi/api/xml/xmlparamsx.cpp
new file mode 100644
index 00000000..2b6b91ac
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsx.cpp
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparamsx.cpp
+// Class : skin_xmlreaderparams
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "xmlparamsx.h"
+#include "xmlparamsi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS XmlReaderParamsX
+START_DISPATCH;
+ CB(XMLREADERPARAMS_GETITEMNAME, getItemName);
+ CB(XMLREADERPARAMS_GETITEMVALUE, getItemValue);
+ CB(XMLREADERPARAMS_GETITEMVALUE2, getItemValue2);
+ CB(XMLREADERPARAMS_ENUMITEMVALUES, enumItemValues);
+ CB(XMLREADERPARAMS_GETITEMVALUEINT, getItemValueInt);
+ CB(XMLREADERPARAMS_GETNBITEMS, getNbItems);
+ VCB(XMLREADERPARAMS_ADDITEM, addItem);
+ VCB(XMLREADERPARAMS_REMOVEITEM, removeItem);
+ VCB(XMLREADERPARAMS_REPLACEITEM, replaceItem);
+ CB(XMLREADERPARAMS_FINDITEM, findItem);
+END_DISPATCH;
+#undef CBCLASS
+
+const wchar_t *XmlReaderParamsX::getItemValue2(const wchar_t *name) { return static_cast<XmlReaderParamsI *>(this)->getItemValue(name); }
diff --git a/Src/Wasabi/api/xml/xmlparamsx.h b/Src/Wasabi/api/xml/xmlparamsx.h
new file mode 100644
index 00000000..8e2c6eae
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsx.h
@@ -0,0 +1,38 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparamsx.h
+// Class : ifc_xmlreaderparams
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __XMLREADERPARAMSX_H
+#define __XMLREADERPARAMSX_H
+
+#include "xmlparams.h"
+
+
+
+
+// ----------------------------------------------------------------------------
+
+class XmlReaderParamsX : public skin_xmlreaderparams {
+ protected:
+ XmlReaderParamsX() {}
+ public:
+ virtual const wchar_t *getItemName(int i)=0;
+ virtual const wchar_t *getItemValue(int i)=0;
+ virtual const wchar_t *getItemValue2(const wchar_t *name);
+ virtual const wchar_t *enumItemValues(const wchar_t *name, int nb)=0;
+ virtual int getItemValueInt(const wchar_t *name, int def = 0)=0;
+ virtual int getNbItems()=0;
+ virtual void addItem(const wchar_t *parm, const wchar_t *value)=0;
+ virtual void removeItem(const wchar_t *parm)=0;
+ virtual void replaceItem(const wchar_t *parm, const wchar_t *value)=0;
+ virtual int findItem(const wchar_t *parm)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __XMLREADERPARAMSX_H
diff --git a/Src/Wasabi/api/xml/xmlparse.h b/Src/Wasabi/api/xml/xmlparse.h
new file mode 100644
index 00000000..68c81b43
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparse.h
@@ -0,0 +1,23 @@
+#ifndef _XMLPARSE_H
+#define _XMLPARSE_H
+
+class XMLParse {
+private:
+ void *parser;
+
+public:
+ XMLParse();
+ virtual ~XMLParse();
+
+ virtual void SetUserData(void *param);
+ virtual void SetElementHandler(void (*start)(void *userData, const wchar_t *name, const wchar_t **atts),
+ void (*end)(void *userData, const wchar_t *name));
+ virtual void SetCharacterDataHandler(void (*handler)(void *userData,const wchar_t *s, int len));
+ virtual int Parse(const wchar_t *s, int len, int isFinal);
+ virtual const wchar_t *ErrorString(int code);
+ virtual int GetErrorCode();
+ virtual int GetCurrentLineNumber();
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlreader.cpp b/Src/Wasabi/api/xml/xmlreader.cpp
new file mode 100644
index 00000000..c6d649b8
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlreader.cpp
@@ -0,0 +1,197 @@
+#include <precomp.h>
+#include "xmlreader.h"
+#include <bfc/parse/pathparse.h>
+#include <bfc/file/wildcharsenum.h>
+#include <bfc/string/url.h>
+#include <api/service/svcs/svc_xmlprov.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/util/varmgr.h>
+#endif
+#include <api/xml/xmlparamsi.h>
+#include <api/xml/XMLAutoInclude.h>
+#include "../nu/regexp.h"
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void XmlReader::registerCallback(const wchar_t *matchstr, XmlReaderCallbackI *callback)
+{
+ if (matchstr == NULL || callback == NULL) return ;
+ xmlreader_cb_struct *s = new xmlreader_cb_struct(matchstr, TYPE_CLASS_CALLBACK, callback);
+ callback_list.addItem(s, 0); // mig: add to FRONT of list... so we don't step on hierarchical toes.
+}
+
+void XmlReader::registerCallback(const wchar_t *matchstr, void (* callback)(int, const wchar_t *, skin_xmlreaderparams *))
+{
+ if (matchstr == NULL || callback == NULL) return ;
+ xmlreader_cb_struct *s = new xmlreader_cb_struct(matchstr, TYPE_STATIC_CALLBACK, (XmlReaderCallbackI *)callback);
+ callback_list.addItem(s, 0); // mig: add to FRONT of list... so we don't step on hierarchical toes.
+}
+
+void XmlReader::unregisterCallback(void *callback)
+{
+ for (int i = 0;i < callback_list.getNumItems();i++)
+ {
+ if (callback_list[i]->callback == callback)
+ {
+ delete callback_list[i];
+ callback_list.delByPos(i);
+ i--;
+ }
+ }
+}
+
+int XmlReader::loadFile(const wchar_t *filename, const wchar_t *incpath, int isinclude)
+{
+ includePath=incpath;
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ includer = new XMLAutoInclude(parser, incpath);
+ parser->xmlreader_registerCallback(L"*", this);
+ parser->xmlreader_open();
+
+ LoadXmlFile(parser, filename);
+ parser->xmlreader_unregisterCallback(this);
+ delete includer;
+ includer=0;
+
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ return 1;
+ }
+
+ }
+
+ return 0;
+}
+
+const wchar_t *XmlReader::getIncludePath()
+{
+ // return include_stack.top()->getValue();
+ return (includer != NULL ? includer->path.getValue() : L"");
+ //return includePath;
+}
+
+void XmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ size_t numParams = params->getNbItems();
+ XmlReaderParamsI p;
+ for (size_t i = 0;i!=numParams;i++)
+ { //CT> removed api-> for speed
+ // BU String* for no exploit
+ const wchar_t *paramStr = params->getItemValue(i);
+ StringW *str = PublicVarManager::translate_nocontext(paramStr);
+ if (str)
+ {
+ Url::decode(str->getNonConstVal());
+ p.addItemSwapValue(params->getItemName(i), *str);
+ delete str;
+ }
+ else
+ {
+
+ StringW temp = paramStr;
+ Url::decode(temp.getNonConstVal());
+ p.addItemSwapValue(params->getItemName(i), temp);
+ }
+ }
+
+ foreach(callback_list)
+ if (Match(callback_list.getfor()->matchstr.v(), xmlpath))
+ {
+ switch (callback_list.getfor()->type)
+ {
+ case TYPE_CLASS_CALLBACK:
+ callback_list.getfor()->callback->xmlReaderOnStartElementCallback(xmltag, &p);
+ break;
+ case TYPE_STATIC_CALLBACK:
+ ((void (*)(int, const wchar_t *, skin_xmlreaderparams *))callback_list.getfor()->callback)(1, xmltag, &p);
+ break;
+ }
+ }
+
+ endfor
+}
+
+void XmlReader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ foreach(callback_list)
+ if (Match(callback_list.getfor()->matchstr.v(), xmlpath))
+ {
+ switch (callback_list.getfor()->type)
+ {
+ case TYPE_CLASS_CALLBACK:
+ callback_list.getfor()->callback->xmlReaderOnEndElementCallback(xmltag);
+ break;
+ case TYPE_STATIC_CALLBACK:
+ ((void (*)(int, const wchar_t *, skin_xmlreaderparams *))callback_list.getfor()->callback)(0, xmltag, NULL);
+ break;
+ }
+
+ }
+ endfor
+
+}
+
+void XmlReader::xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr)
+{
+ int disperr = 1;
+ StringPrintfW txt(L"error parsing xml layer\n");
+ StringPrintfW err(L"%s at line %d\n", errstr, linenum);
+
+ if (disperr)
+ {
+#ifdef WASABI_COMPILE_WND
+ Wasabi::Std::messageBox(err, txt, 0);
+#else
+ DebugStringW("%s - %s", err.getValue(), txt.getValue());
+#endif
+
+ }
+ else
+ {
+#ifdef _WIN32
+ OutputDebugStringW(txt);
+ OutputDebugStringW(err);
+#endif
+ }
+}
+
+#if 0 // TODO: benski> need to do onError for obj_xml
+int XmlReader::parseBuffer(void *parser, const char *xml, int size, int final, const char *filename, const char *incpath)
+{
+ if (!XML_Parse(parser, xml, size, final))
+ {
+ int disperr = 1;
+ StringPrintf txt("error parsing xml layer (%s)\n", filename);
+ StringPrintf err("%s at line %d\n",
+ XML_ErrorString(XML_GetErrorCode(parser)),
+ XML_GetCurrentLineNumber(parser));
+ if (disperr)
+ {
+#ifdef WASABI_COMPILE_WND
+ Std::messageBox(err, txt, 0);
+#else
+ DebugString("%s - %s", err.getValue(), txt.getValue());
+#endif
+
+ }
+ else
+ {
+ OutputDebugString(txt);
+ OutputDebugString(err);
+ }
+ currentpos = "";
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+
+XmlReader skinXML; \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/xmlreader.h b/Src/Wasabi/api/xml/xmlreader.h
new file mode 100644
index 00000000..b8a599d9
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlreader.h
@@ -0,0 +1,75 @@
+#ifndef _XMLREADER_H
+#define _XMLREADER_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/stack.h>
+#include <bfc/dispatch.h>
+#include <api/xml/xmlparams.h>
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <api/xml/XMLAutoInclude.h>
+class svc_xmlProvider;
+
+typedef enum {
+ TYPE_CLASS_CALLBACK = 1,
+ TYPE_STATIC_CALLBACK,
+} xmlreader_callbackType;
+
+
+class XmlReaderCallbackI
+{
+public:
+ XmlReaderCallbackI() : handle(NULL) {}
+
+ virtual void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) { }
+ virtual void xmlReaderOnEndElementCallback(const wchar_t *xmltag) { }
+
+private:
+ void *handle;
+};
+
+
+class xmlreader_cb_struct
+{
+public:
+ xmlreader_cb_struct(const wchar_t *m, xmlreader_callbackType t, XmlReaderCallbackI *cb) : matchstr(m), type(t), callback(cb)
+ {
+ matchstr.toupper();
+ }
+
+ StringW matchstr;
+ xmlreader_callbackType type;
+ XmlReaderCallbackI * callback;
+};
+
+class XmlReader : public ifc_xmlreadercallbackI
+{
+public:
+ // matchstr is a regexp string such as "WinampAbstractionLayer/Layer[a-z]"
+ // or "Winamp*Layer/*/Layout"
+ void registerCallback(const wchar_t *matchstr, XmlReaderCallbackI *callback);
+ void registerCallback(const wchar_t *matchstr, void (*static_callback)(int start, const wchar_t *xmltag, skin_xmlreaderparams *params));
+
+ void unregisterCallback(void *callback);
+
+ // if only_this_class param is specified, only this class will be called back
+ // returns 1 on success, 0 on error
+ int loadFile(const wchar_t *filename, const wchar_t *incpath = NULL, int isinclude = 0);
+ const wchar_t *getIncludePath();
+
+ int getNumCallbacks() { return callback_list.getNumItems(); }
+
+private:
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+ void xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr);
+// int doLoadFile(FILE *fp, svc_xmlProvider *svc, const wchar_t *filename, const wchar_t *incpath);
+
+ PtrList<xmlreader_cb_struct> callback_list;
+ StringW includePath;
+XMLAutoInclude *includer;
+};
+
+extern XmlReader skinXML;
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlwrite.cpp b/Src/Wasabi/api/xml/xmlwrite.cpp
new file mode 100644
index 00000000..732c05f7
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlwrite.cpp
@@ -0,0 +1,262 @@
+#include <precomp.h>
+
+#include "xmlwrite.h"
+
+#include <bfc/wasabi_std.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/parse/paramparser.h>
+
+#if 0
+static unsigned char xmltypecheck[256] =
+{
+#define BT_COLON BT_NMSTRT
+#include "latin1tab.h"
+#undef BT_COLON
+#include "asciitab.h"
+ };
+#endif
+
+#define EFPRINTF (nohicharconversion ? eutf8fprintf : efprintf)
+
+#include "../nu/AutoChar.h"
+XMLWrite::XMLWrite(const wchar_t *filename, const wchar_t *doctype, const wchar_t *dtddoctype, int no_hi_chars_conversion)
+{
+ nohicharconversion = no_hi_chars_conversion;
+ FILE *f = _wfopen(filename, WF_WRITE_BINARY);
+ Init(f, doctype, dtddoctype);
+}
+
+XMLWrite::XMLWrite(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype, int no_hi_chars_conversion)
+{
+ nohicharconversion = no_hi_chars_conversion;
+ Init(file, doctype, dtddoctype);
+}
+
+void XMLWrite::Init(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype)
+{
+ fp = file;
+ ASSERT(fp != NULL); // sheet, need exceptions here
+ indenter.setValue(L"");
+ utf8fprintf(fp, L"<?xml version=\"1.0\" encoding='UTF-8' standalone=\"yes\"?>\n");
+ if (dtddoctype != NULL)
+ utf8fprintf(fp, L"<!DOCTYPE %s>\n", dtddoctype);
+ pushCategory(doctype, 1, 0);
+}
+
+XMLWrite::~XMLWrite()
+{
+ popCategory(1, 0);
+ fflush(fp);
+ fclose(fp);
+ ASSERT(titles.peek() == 0);
+}
+
+void XMLWrite::comment(const wchar_t *comment)
+{
+ utf8fprintf(fp, L"<!-- %s -->\n", comment);
+}
+
+void XMLWrite::pushCategory(const wchar_t *title, int wantcr, int wantindent)
+{
+ if (wantindent)
+ {
+ utf8fprintf(fp, L"%s<%s>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ }
+ else
+ utf8fprintf(fp, L"<%s>%s", title, wantcr ? L"\n" : L"");
+ indenter+=L" ";
+ ParamParser pp(title, L" ");
+ titles.push(WCSDUP(pp.enumItem(0)));
+}
+
+void XMLWrite::pushCategoryAttrib(const wchar_t *title, int nodata)
+{
+ utf8fprintf(fp, L"%s<%s", indenter.getValue(), title);
+ indenter+=L" ";
+ titles.push(nodata ? NULL : WCSDUP(title));
+}
+
+void XMLWrite::writeCategoryAttrib(const wchar_t *title, const int val)
+{
+ utf8fprintf(fp, L" %s=\"%d\"", title, val);
+}
+
+void XMLWrite::writeCategoryAttrib(const wchar_t *title, const wchar_t *str)
+{
+ if (!str)
+ str = L"";
+ utf8fprintf(fp, L" %s=\"", title);
+ EFPRINTF(fp, L"%s", str);
+ utf8fprintf(fp, L"\"");
+}
+
+void XMLWrite::closeCategoryAttrib(int wantcr)
+{
+ if (titles.top() == NULL)
+ utf8fprintf(fp, L" /");
+ utf8fprintf(fp, L">%s", wantcr ? L"\n" : L"");
+}
+
+void XMLWrite::writeAttribEmpty(const wchar_t *title, int wantcr, int wantindent)
+{
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s/>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"<%s/>%s", title, wantcr ? L"\n" : L"");
+}
+
+void XMLWrite::writeAttrib(const wchar_t *title, const wchar_t *text, int wantcr, int wantindent)
+{
+ if (text && *text)
+ {
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s>", indenter.getValue(), title);
+ else
+ utf8fprintf(fp, L"<%s>", title);
+ EFPRINTF(fp, L"%s", text);
+ utf8fprintf(fp, L"</%s>%s", title, wantcr ? L"\n" : L"");
+ }
+ else
+ {
+ writeAttribEmpty(title, wantcr, wantindent);
+ }
+}
+
+void XMLWrite::writeAttrib(const wchar_t *title, int val, int wantcr, int wantindent)
+{
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s>%d</%s>%s", indenter.getValue(), title, val, title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"<%s>%d</%s>%s", title, val, title, wantcr ? L"\n" : L"");
+}
+
+int XMLWrite::popCategory(int wantcr, int wantindent)
+{
+ indenter.trunc(-2);
+ wchar_t *title;
+ int r = titles.pop(&title);
+ if (!r) return 0;
+ if (title != NULL)
+ {
+ if (wantindent)
+ utf8fprintf(fp, L"%s</%s>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"</%s>%s", title, wantcr ? L"\n" : L"");
+ FREE(title);
+ }
+ return titles.peek();
+}
+
+int XMLWrite::utf8fprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+
+#ifdef _WIN32
+ AutoChar utf8(outstr, CP_UTF8);
+#else
+#warning port me
+ AutoChar utf8(outstr);
+#endif
+ const char *data = (const char *)utf8; // to make the next line less messay
+ fwrite(data, STRLEN(data), 1, fp);
+ return 0;
+}
+
+int XMLWrite::eutf8fprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+
+#ifdef _WIN32
+ AutoChar utf8(outstr, CP_UTF8);
+#else
+#warning port me
+ AutoChar utf8(outstr);
+#endif
+
+ const char *data = (const char *)utf8; // to make the next line less messay
+ while (data && *data)
+ {
+ size_t cur_length=0;
+ while (data[cur_length] && data[cur_length] != '<' && data[cur_length] != '>' && data[cur_length] != '&' && data[cur_length] != '\"' && data[cur_length] != '\'')
+ {
+ cur_length++;
+ }
+ fwrite(data, cur_length, 1, fp);
+ data += cur_length;
+ if (*data)
+ {
+ // if we get here, it was a special character
+ switch(*data)
+ {
+ case '<': fwrite("&lt;", 4, 1, fp); break;
+ case '>': fwrite("&gt;", 4, 1, fp); break;
+ case '&': fwrite("&amp;", 5, 1, fp); break;
+ case '\"': fwrite("&quot;", 6, 1, fp); break;
+ case '\'': fwrite("&apos;", 6, 1, fp); break;
+ }
+ data++;
+ }
+ };
+
+ return 0;
+}
+
+int XMLWrite::efprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ // http://www.w3.org/TR/REC-xml#syntax
+ int bcount = 0;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+ size_t n = outstr.len();
+ for (size_t i = 0; i != n; i++)
+ {
+ wchar_t c = outstr.getValue()[i];
+ switch (c)
+ {
+ case '<': fwrite("&lt;", 4, 1, fp); bcount += 4; break;
+ case '>': fwrite("&gt;", 4, 1, fp); bcount += 4; break;
+ case '&': fwrite("&amp;", 5, 1, fp); bcount += 5; break;
+ case '\"': fwrite("&quot;", 6, 1, fp); bcount += 6; break;
+ case '\'': fwrite("&apos;", 6, 1, fp); bcount += 6; break;
+ default:
+ // if (xmltypecheck[c] != 0)
+ {
+ // TODO: benski> optimize by scanning for the next character to be escaped (or NULL)
+ size_t numChars=1;
+ while (1)
+ {
+ wchar_t check = outstr.getValue()[i+numChars];
+ if (check == 0
+ || check == '<'
+ || check == '>'
+ || check == '&'
+ || check == '\''
+ || check == '\"')
+ break;
+ numChars++;
+ }
+ const wchar_t *str = outstr.getValue() + i;
+ int len = WideCharToMultiByte(CP_UTF8, 0, str, (int)numChars, 0, 0, 0, 0);
+ char *utf8 = (char *)malloc(len);
+ WideCharToMultiByte(CP_UTF8, 0, str, (int)numChars, utf8, len, 0, 0);
+ fwrite(utf8, len, 1, fp);
+ free(utf8);
+ bcount+=(int)numChars;
+ i+=(numChars-1);
+ }
+ break;
+ }
+ }
+ return bcount;
+}
diff --git a/Src/Wasabi/api/xml/xmlwrite.h b/Src/Wasabi/api/xml/xmlwrite.h
new file mode 100644
index 00000000..b4c55868
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlwrite.h
@@ -0,0 +1,45 @@
+#ifndef _XML_H
+#define _XML_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/stack.h>
+#include <bfc/string/StringW.h>
+
+class XMLWrite
+{
+public:
+ XMLWrite(const wchar_t *filename, const wchar_t *doctype, const wchar_t *dtddoctype = NULL, int no_hi_chars_conversion = 0);
+ XMLWrite(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype = NULL, int no_hi_chars_conversion = 0);
+ ~XMLWrite();
+
+ void Init(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype);
+
+ void comment(const wchar_t *comment);
+
+ void pushCategory(const wchar_t *title, int wantcr = 1, int wantindent = 1);
+
+ void pushCategoryAttrib(const wchar_t *title, int nodata = FALSE);
+ void writeCategoryAttrib(const wchar_t *title, const int val);
+ void writeCategoryAttrib(const wchar_t *title, const wchar_t *val);
+ void closeCategoryAttrib(int wantcr = 1);
+
+ void writeAttribEmpty(const wchar_t *title, int wantcr = 1, int wantindent = 1);
+ void writeAttrib(const wchar_t *title, const wchar_t *text, int wantcr = 1, int wantindent = 1);
+ void writeAttrib(const wchar_t *title, int val, int wantcr = 1, int wantindent = 1);
+ int popCategory(int wantcr = 1, int wantindent = 1); // returns nonzero if more categories are open
+
+ static int efprintf(FILE *fp, const wchar_t *format, ...);
+ static int utf8fprintf(FILE *fp, const wchar_t *format, ...);
+ static int eutf8fprintf(FILE *fp, const wchar_t *format, ...);
+
+private:
+ FILE *fp;
+ StringW indenter;
+// int indent;
+ Stack<wchar_t *>titles;
+ int nohicharconversion;
+};
+
+
+
+#endif