aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/script/objects/sxmldoc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/script/objects/sxmldoc.cpp')
-rw-r--r--Src/Wasabi/api/script/objects/sxmldoc.cpp231
1 files changed, 231 insertions, 0 deletions
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 <precomp.h>
+#include "sxmldoc.h"
+
+#include "slist.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+
+// {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<SXmlDoc *>(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<SXmlDoc *>(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<SXmlDoc *>(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<SXmlDoc *>(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<SXmlDoc *>(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