sxmldoc.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include <precomp.h>
  2. #include "sxmldoc.h"
  3. #include "slist.h"
  4. #include <api/script/script.h>
  5. #include <api/script/scriptmgr.h>
  6. #include <api/script/objecttable.h>
  7. // {417FFB69-987F-4be8-8D87-D9965EEEC868}
  8. static const GUID xmlDocGuid =
  9. { 0x417ffb69, 0x987f, 0x4be8, { 0x8d, 0x87, 0xd9, 0x96, 0x5e, 0xee, 0xc8, 0x68 } };
  10. XmlDocScriptController _xmlDocController;
  11. XmlDocScriptController *xmlDocController=&_xmlDocController;
  12. // -- Functions table -------------------------------------
  13. function_descriptor_struct XmlDocScriptController::exportedFunction[] = {
  14. {L"parser_addCallback", 1, (void*)SXmlDoc::script_vcpu_addParserCallback },
  15. {L"parser_start", 0, (void*)SXmlDoc::script_vcpu_parse },
  16. {L"parser_destroy", 0, (void*)SXmlDoc::script_vcpu_destroyParser },
  17. {L"parser_onCallback", 4, (void*)SXmlDoc::script_vcpu_onXmlParserCallback},
  18. {L"parser_onCloseCallback", 2, (void*)SXmlDoc::script_vcpu_onXmlParserEndCallback},
  19. {L"parser_onError", 5, (void*)SXmlDoc::script_vcpu_onXmlParserError},
  20. };
  21. // --------------------------------------------------------
  22. const wchar_t *XmlDocScriptController::getClassName() {
  23. return L"XmlDoc";
  24. }
  25. const wchar_t *XmlDocScriptController::getAncestorClassName() {
  26. return L"File";
  27. }
  28. ScriptObjectController *XmlDocScriptController::getAncestorController() { return rootScriptObjectController; }
  29. ScriptObject *XmlDocScriptController::instantiate() {
  30. SXmlDoc *xd = new SXmlDoc;
  31. ASSERT(xd != NULL);
  32. return xd->getScriptObject();
  33. }
  34. void XmlDocScriptController::destroy(ScriptObject *o) {
  35. SXmlDoc *xd = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
  36. ASSERT(xd != NULL);
  37. delete xd;
  38. }
  39. void *XmlDocScriptController::encapsulate(ScriptObject *o) {
  40. return NULL; // no encapsulation for XmlDocs for now
  41. }
  42. void XmlDocScriptController::deencapsulate(void *o) {
  43. }
  44. int XmlDocScriptController::getNumFunctions() {
  45. return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
  46. }
  47. const function_descriptor_struct *XmlDocScriptController::getExportedFunctions() {
  48. return exportedFunction;
  49. }
  50. GUID XmlDocScriptController::getClassGuid() {
  51. return xmlDocGuid;
  52. }
  53. SXmlDoc::SXmlDoc() {
  54. getScriptObject()->vcpu_setInterface(xmlDocGuid, (void *)static_cast<SXmlDoc *>(this));
  55. getScriptObject()->vcpu_setClassName(L"XmlDoc");
  56. getScriptObject()->vcpu_setController(xmlDocController);
  57. filename = NULL;
  58. myXmlParser = NULL;
  59. }
  60. SXmlDoc::~SXmlDoc() {
  61. destroyParser();
  62. }
  63. void SXmlDoc::addParserCallback(const wchar_t *name)
  64. {
  65. createParser();
  66. StringW sw_name = name;
  67. sw_name.replace(L"/", L"\f"); // We call subsections in Maki with a single /. in Wasabi \f is used
  68. //debug: Std::messageBox(sw_name,name,0);
  69. myXmlParser->xmlreader_registerCallback(sw_name, &myXmlParserCallback);
  70. //debug: myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback);
  71. }
  72. void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
  73. void SXmlDoc::startParsing()
  74. {
  75. /* debug: createParser();
  76. myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback);
  77. myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbrowserQuickLinks", &myXmlParserCallback);*/
  78. if (!myXmlParser) return;
  79. myXmlParser->xmlreader_open();
  80. LoadXmlFile(myXmlParser, filename);
  81. }
  82. void SXmlDoc::createParser()
  83. {
  84. if (myXmlParser != NULL) return;
  85. myXmlParserCallback.parent = this;
  86. myXmlParserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
  87. if (myXmlParserFactory)
  88. {
  89. myXmlParser = (obj_xml *)myXmlParserFactory->getInterface();
  90. if (myXmlParser)
  91. {
  92. const wchar_t *file = Wasabi::Std::filename(filename);
  93. int fnlen = wcslen(file);
  94. StringW path = filename;
  95. path.trunc( -fnlen);
  96. XMLAutoInclude include(myXmlParser, path);
  97. }
  98. }
  99. }
  100. void SXmlDoc::destroyParser()
  101. {
  102. if (!myXmlParser) return;
  103. myXmlParser->xmlreader_unregisterCallback(&myXmlParserCallback);
  104. myXmlParser->xmlreader_close();
  105. myXmlParserFactory->releaseInterface(myXmlParser);
  106. myXmlParser = NULL;
  107. }
  108. // ParserCallbacks
  109. void SXmlDocParserCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
  110. {
  111. //debug: Std::messageBox(xmlpath,xmltag,0);
  112. StringW sw_xmlpath = xmlpath;
  113. sw_xmlpath.replace(L"\f", L"/");
  114. // Store the params and paramvalues in a SList
  115. SList param;
  116. SList paramvalue;
  117. for (size_t i = 0; i != params->getNbItems(); i++)
  118. {
  119. SList::script_vcpu_addItem(SCRIPT_CALL, param.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemName(i)));
  120. SList::script_vcpu_addItem(SCRIPT_CALL, paramvalue.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemValue(i)));
  121. }
  122. // and now the monster call ;)
  123. SXmlDoc::script_vcpu_onXmlParserCallback(
  124. SCRIPT_CALL, parent->getScriptObject(),
  125. MAKE_SCRIPT_STRING(sw_xmlpath),
  126. MAKE_SCRIPT_STRING(xmltag),
  127. MAKE_SCRIPT_OBJECT(param.getScriptObject()),
  128. MAKE_SCRIPT_OBJECT(paramvalue.getScriptObject()) );
  129. }
  130. void SXmlDocParserCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
  131. {
  132. StringW sw_xmlpath = xmlpath;
  133. sw_xmlpath.replace(L"\f", L"/");
  134. SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_CALL, parent->getScriptObject(), MAKE_SCRIPT_STRING(sw_xmlpath), MAKE_SCRIPT_STRING(xmltag));
  135. }
  136. void SXmlDocParserCallback::xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr)
  137. {
  138. SXmlDoc::script_vcpu_onXmlParserError(
  139. SCRIPT_CALL, parent->getScriptObject(),
  140. MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function!
  141. MAKE_SCRIPT_INT(linenum),
  142. MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function!
  143. MAKE_SCRIPT_INT(errcode),
  144. MAKE_SCRIPT_STRING(errstr) );
  145. }
  146. // VCPU
  147. scriptVar SXmlDoc::script_vcpu_addParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn) {
  148. SCRIPT_FUNCTION_INIT;
  149. ASSERT(fn.type == SCRIPT_STRING);
  150. SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
  151. if (m) m->addParserCallback(fn.data.sdata);
  152. RETURN_SCRIPT_VOID;
  153. }
  154. scriptVar SXmlDoc::script_vcpu_parse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  155. SCRIPT_FUNCTION_INIT;
  156. SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
  157. if (m) m->startParsing();
  158. RETURN_SCRIPT_VOID;
  159. }
  160. scriptVar SXmlDoc::script_vcpu_destroyParser(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  161. SCRIPT_FUNCTION_INIT;
  162. SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
  163. if (m) m->destroyParser();
  164. RETURN_SCRIPT_VOID;
  165. }
  166. scriptVar SXmlDoc::script_vcpu_onXmlParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag, scriptVar param, scriptVar paramvalue)
  167. {
  168. SCRIPT_FUNCTION_INIT
  169. PROCESS_HOOKS4(o, xmlDocController, xmlpath, xmltag, param, paramvalue);
  170. SCRIPT_FUNCTION_CHECKABORTEVENT;
  171. SCRIPT_EXEC_EVENT4(o, xmlpath, xmltag, param, paramvalue);
  172. }
  173. scriptVar SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag)
  174. {
  175. SCRIPT_FUNCTION_INIT
  176. PROCESS_HOOKS2(o, xmlDocController, xmlpath, xmltag);
  177. SCRIPT_FUNCTION_CHECKABORTEVENT;
  178. SCRIPT_EXEC_EVENT2(o, xmlpath, xmltag);
  179. }
  180. scriptVar SXmlDoc::script_vcpu_onXmlParserError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar filename, scriptVar linenum, scriptVar incpath, scriptVar errcode, scriptVar errstr)
  181. {
  182. SCRIPT_FUNCTION_INIT
  183. PROCESS_HOOKS5(o, xmlDocController, filename, linenum, incpath, errcode, errstr);
  184. SCRIPT_FUNCTION_CHECKABORTEVENT;
  185. SCRIPT_EXEC_EVENT5(o, filename, linenum, incpath, errcode, errstr);
  186. }