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