Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -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 ;
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -0,0 +1,2 @@
#include <precomp.h>
#include <api/xml/ifc_xmlreadercallback.h>

View file

@ -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"

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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); }

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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