diff options
Diffstat (limited to 'Src/Wasabi/api/xml')
-rw-r--r-- | Src/Wasabi/api/xml/LoadXML.cpp | 92 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/LoadXML.h | 7 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/XMLAutoInclude.cpp | 87 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/XMLAutoInclude.h | 22 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/api_xmlreadercallback.cpp | 2 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparams.cpp | 12 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparams.h | 103 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparamsi.cpp | 119 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparamsi.h | 52 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparamsx.cpp | 32 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparamsx.h | 38 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlparse.h | 23 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlreader.cpp | 197 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlreader.h | 75 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlwrite.cpp | 262 | ||||
-rw-r--r-- | Src/Wasabi/api/xml/xmlwrite.h | 45 |
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("<", 4, 1, fp); break; + case '>': fwrite(">", 4, 1, fp); break; + case '&': fwrite("&", 5, 1, fp); break; + case '\"': fwrite(""", 6, 1, fp); break; + case '\'': fwrite("'", 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("<", 4, 1, fp); bcount += 4; break; + case '>': fwrite(">", 4, 1, fp); bcount += 4; break; + case '&': fwrite("&", 5, 1, fp); bcount += 5; break; + case '\"': fwrite(""", 6, 1, fp); bcount += 6; break; + case '\'': fwrite("'", 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 |