From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Wasabi/api/script/objects/sxmldoc.cpp | 231 ++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 Src/Wasabi/api/script/objects/sxmldoc.cpp (limited to 'Src/Wasabi/api/script/objects/sxmldoc.cpp') diff --git a/Src/Wasabi/api/script/objects/sxmldoc.cpp b/Src/Wasabi/api/script/objects/sxmldoc.cpp new file mode 100644 index 00000000..f5954c20 --- /dev/null +++ b/Src/Wasabi/api/script/objects/sxmldoc.cpp @@ -0,0 +1,231 @@ +#include +#include "sxmldoc.h" + +#include "slist.h" + +#include +#include +#include + + +// {417FFB69-987F-4be8-8D87-D9965EEEC868} +static const GUID xmlDocGuid = +{ 0x417ffb69, 0x987f, 0x4be8, { 0x8d, 0x87, 0xd9, 0x96, 0x5e, 0xee, 0xc8, 0x68 } }; + + +XmlDocScriptController _xmlDocController; +XmlDocScriptController *xmlDocController=&_xmlDocController; + +// -- Functions table ------------------------------------- +function_descriptor_struct XmlDocScriptController::exportedFunction[] = { + {L"parser_addCallback", 1, (void*)SXmlDoc::script_vcpu_addParserCallback }, + {L"parser_start", 0, (void*)SXmlDoc::script_vcpu_parse }, + {L"parser_destroy", 0, (void*)SXmlDoc::script_vcpu_destroyParser }, + {L"parser_onCallback", 4, (void*)SXmlDoc::script_vcpu_onXmlParserCallback}, + {L"parser_onCloseCallback", 2, (void*)SXmlDoc::script_vcpu_onXmlParserEndCallback}, + {L"parser_onError", 5, (void*)SXmlDoc::script_vcpu_onXmlParserError}, +}; +// -------------------------------------------------------- + +const wchar_t *XmlDocScriptController::getClassName() { + return L"XmlDoc"; +} + +const wchar_t *XmlDocScriptController::getAncestorClassName() { + return L"File"; +} + +ScriptObjectController *XmlDocScriptController::getAncestorController() { return rootScriptObjectController; } + +ScriptObject *XmlDocScriptController::instantiate() { + SXmlDoc *xd = new SXmlDoc; + ASSERT(xd != NULL); + return xd->getScriptObject(); +} + +void XmlDocScriptController::destroy(ScriptObject *o) { + SXmlDoc *xd = static_cast(o->vcpu_getInterface(xmlDocGuid)); + ASSERT(xd != NULL); + delete xd; +} + +void *XmlDocScriptController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for XmlDocs for now +} + +void XmlDocScriptController::deencapsulate(void *o) { +} + +int XmlDocScriptController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +const function_descriptor_struct *XmlDocScriptController::getExportedFunctions() { + return exportedFunction; +} + +GUID XmlDocScriptController::getClassGuid() { + return xmlDocGuid; +} + + +SXmlDoc::SXmlDoc() { + getScriptObject()->vcpu_setInterface(xmlDocGuid, (void *)static_cast(this)); + getScriptObject()->vcpu_setClassName(L"XmlDoc"); + getScriptObject()->vcpu_setController(xmlDocController); + filename = NULL; + myXmlParser = NULL; +} + +SXmlDoc::~SXmlDoc() { + destroyParser(); +} + +void SXmlDoc::addParserCallback(const wchar_t *name) +{ + createParser(); + StringW sw_name = name; + sw_name.replace(L"/", L"\f"); // We call subsections in Maki with a single /. in Wasabi \f is used + //debug: Std::messageBox(sw_name,name,0); + myXmlParser->xmlreader_registerCallback(sw_name, &myXmlParserCallback); + //debug: myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback); +} + +void LoadXmlFile(obj_xml *parser, const wchar_t *filename); + +void SXmlDoc::startParsing() +{ +/* debug: createParser(); +myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback); +myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbrowserQuickLinks", &myXmlParserCallback);*/ + + if (!myXmlParser) return; + myXmlParser->xmlreader_open(); + LoadXmlFile(myXmlParser, filename); +} + +void SXmlDoc::createParser() +{ + if (myXmlParser != NULL) return; + + myXmlParserCallback.parent = this; + + myXmlParserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID); + if (myXmlParserFactory) + { + myXmlParser = (obj_xml *)myXmlParserFactory->getInterface(); + + if (myXmlParser) + { + const wchar_t *file = Wasabi::Std::filename(filename); + int fnlen = wcslen(file); + StringW path = filename; + path.trunc( -fnlen); + XMLAutoInclude include(myXmlParser, path); + } + } +} + +void SXmlDoc::destroyParser() +{ + if (!myXmlParser) return; + myXmlParser->xmlreader_unregisterCallback(&myXmlParserCallback); + myXmlParser->xmlreader_close(); + myXmlParserFactory->releaseInterface(myXmlParser); + myXmlParser = NULL; +} + +// ParserCallbacks + +void SXmlDocParserCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) +{ + //debug: Std::messageBox(xmlpath,xmltag,0); + StringW sw_xmlpath = xmlpath; + sw_xmlpath.replace(L"\f", L"/"); + + // Store the params and paramvalues in a SList + SList param; + SList paramvalue; + + for (size_t i = 0; i != params->getNbItems(); i++) + { + SList::script_vcpu_addItem(SCRIPT_CALL, param.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemName(i))); + SList::script_vcpu_addItem(SCRIPT_CALL, paramvalue.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemValue(i))); + } + + // and now the monster call ;) + SXmlDoc::script_vcpu_onXmlParserCallback( + SCRIPT_CALL, parent->getScriptObject(), + MAKE_SCRIPT_STRING(sw_xmlpath), + MAKE_SCRIPT_STRING(xmltag), + MAKE_SCRIPT_OBJECT(param.getScriptObject()), + MAKE_SCRIPT_OBJECT(paramvalue.getScriptObject()) ); +} + +void SXmlDocParserCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag) +{ + StringW sw_xmlpath = xmlpath; + sw_xmlpath.replace(L"\f", L"/"); + + SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_CALL, parent->getScriptObject(), MAKE_SCRIPT_STRING(sw_xmlpath), MAKE_SCRIPT_STRING(xmltag)); +} + +void SXmlDocParserCallback::xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr) +{ + SXmlDoc::script_vcpu_onXmlParserError( + SCRIPT_CALL, parent->getScriptObject(), + MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function! + MAKE_SCRIPT_INT(linenum), + MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function! + MAKE_SCRIPT_INT(errcode), + MAKE_SCRIPT_STRING(errstr) ); +} + +// VCPU + +scriptVar SXmlDoc::script_vcpu_addParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn) { + SCRIPT_FUNCTION_INIT; + ASSERT(fn.type == SCRIPT_STRING); + SXmlDoc *m = static_cast(o->vcpu_getInterface(xmlDocGuid)); + if (m) m->addParserCallback(fn.data.sdata); + + RETURN_SCRIPT_VOID; +} + +scriptVar SXmlDoc::script_vcpu_parse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + SXmlDoc *m = static_cast(o->vcpu_getInterface(xmlDocGuid)); + if (m) m->startParsing(); + + RETURN_SCRIPT_VOID; +} + +scriptVar SXmlDoc::script_vcpu_destroyParser(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT; + SXmlDoc *m = static_cast(o->vcpu_getInterface(xmlDocGuid)); + if (m) m->destroyParser(); + + RETURN_SCRIPT_VOID; +} + +scriptVar SXmlDoc::script_vcpu_onXmlParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag, scriptVar param, scriptVar paramvalue) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS4(o, xmlDocController, xmlpath, xmltag, param, paramvalue); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT4(o, xmlpath, xmltag, param, paramvalue); +} +scriptVar SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS2(o, xmlDocController, xmlpath, xmltag); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT2(o, xmlpath, xmltag); +} +scriptVar SXmlDoc::script_vcpu_onXmlParserError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar filename, scriptVar linenum, scriptVar incpath, scriptVar errcode, scriptVar errstr) +{ + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS5(o, xmlDocController, filename, linenum, incpath, errcode, errstr); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT5(o, filename, linenum, incpath, errcode, errstr); +} \ No newline at end of file -- cgit