#include "tinyxml2.h" #include "squirrel.h" #include SQ_OPT_STRING_STRLEN(); #define XML_TAG(tag) SQXML_##tag##_TYPE_TAG #define CREATE_TAG(tag) static const SQChar* XML_TAG(tag) = #tag static const SQChar sq_tinyxml2_TAG[] = _SC("TinyXml2"); CREATE_TAG(XMLNode); CREATE_TAG(XMLComment); CREATE_TAG(XMLText); CREATE_TAG(XMLDeclaration); CREATE_TAG(XMLUnknown); CREATE_TAG(XMLAttribute); CREATE_TAG(XMLElement); CREATE_TAG(XMLDocument); CREATE_TAG(XMLPrinter); #define GET_TINYXML2_INSTANCE(v, idx, klass, var) SQ_GET_INSTANCE_VAR(v, idx, tinyxml2::klass, var, XML_TAG(klass)) #define GET_XMLNode_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLNode, node) #define GET_XMLNode_INSTANCE2(v, idx, var) GET_TINYXML2_INSTANCE(v, idx, XMLNode, var) #define GET_XMLComment_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, Comment, comment) #define GET_XMLText_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLText, text) #define GET_XMLDeclaration_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLDeclaration, declaration) #define GET_XMLUnknown_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLUnknown, unknown) #define GET_XMLAttribute_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLAttribute, attribute) #define GET_XMLElement_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, idx, XMLElement, element) #define GET_XMLDocument_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, 1, XMLDocument, doc) #define GET_XMLPrinter_INSTANCE(v, idx) GET_TINYXML2_INSTANCE(v, 1, XMLPrinter, printer) static SQRESULT sq_push_xml_class(HSQUIRRELVM v, const SQChar *klass_tag, void *self){ if(!self) { sq_pushnull(v); return 1; } sq_pushstring(v, sq_tinyxml2_TAG, -1); if(sq_getonroottable(v) == SQ_OK){ sq_pushstring(v, klass_tag, -1); if(sq_rawget(v, -2) == SQ_OK) { if(sq_createinstance(v, -1) == SQ_OK){ sq_setinstanceup(v, -1, self); return 1; } } } return SQ_ERROR; } static SQRESULT sq_XMLNode_GetDocument(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLDocument *doc = node->GetDocument(); return sq_push_xml_class(v, XML_TAG(XMLDocument), doc); } static SQRESULT sq_XMLNode_ToElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = node->ToElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLNode_ToText(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLText *ptr = node->ToText(); return sq_push_xml_class(v, XML_TAG(XMLText), ptr); } static SQRESULT sq_XMLNode_ToComment(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLComment *ptr = node->ToComment(); return sq_push_xml_class(v, XML_TAG(XMLComment), ptr); } static SQRESULT sq_XMLNode_ToDocument(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLDocument *ptr = node->ToDocument(); return sq_push_xml_class(v, XML_TAG(XMLDocument), ptr); } static SQRESULT sq_XMLNode_ToDeclaration(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLDeclaration *ptr = node->ToDeclaration(); return sq_push_xml_class(v, XML_TAG(XMLDeclaration), ptr); } static SQRESULT sq_XMLNode_ToUnknown(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLUnknown *ptr = node->ToUnknown(); return sq_push_xml_class(v, XML_TAG(XMLUnknown), ptr); } static SQRESULT sq_XMLNode_Parent(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *ptr = node->Parent(); return sq_push_xml_class(v, XML_TAG(XMLNode), ptr); } static SQRESULT sq_XMLNode_FirstChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *ptr = node->FirstChild(); return sq_push_xml_class(v, XML_TAG(XMLNode), ptr); } static SQRESULT sq_XMLNode_LastChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *ptr = node->LastChild(); return sq_push_xml_class(v, XML_TAG(XMLNode), ptr); } static SQRESULT sq_XMLNode_PreviousSibling(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *ptr = node->PreviousSibling(); return sq_push_xml_class(v, XML_TAG(XMLNode), ptr); } static SQRESULT sq_XMLNode_NextSibling(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *ptr = node->NextSibling(); return sq_push_xml_class(v, XML_TAG(XMLNode), ptr); } static SQRESULT sq_XMLNode_FirstChildElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = node->FirstChildElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLNode_LastChildElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = node->LastChildElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLNode_PreviousSiblingElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = node->PreviousSiblingElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLNode_NextSiblingElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = node->NextSiblingElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLNode_InsertEndChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, addThis); node->InsertEndChild(addThis); return 1; } static SQRESULT sq_XMLNode_LinkEndChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, addThis); node->LinkEndChild(addThis); return 1; } static SQRESULT sq_XMLNode_InsertFirstChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, addThis); node->InsertFirstChild(addThis); return 1; } static SQRESULT sq_XMLNode_InsertAfterChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, afterThis); GET_XMLNode_INSTANCE2(v, 3, addThis); node->InsertAfterChild(afterThis, addThis); return 1; } static SQRESULT sq_XMLNode_DeleteChildren(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); node->DeleteChildren(); return 0; } static SQRESULT sq_XMLNode_DeleteChild(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, child); node->DeleteChild(child); return 0; } static SQRESULT sq_XMLNode_ShallowClone(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLNode_INSTANCE(v, 1); tinyxml2::XMLNode *clone; if(_top_ > 1){ GET_XMLDocument_INSTANCE(v, 2); clone = node->ShallowClone(doc); } else clone = node->ShallowClone(0); return sq_push_xml_class(v, XML_TAG(XMLNode), clone); } static SQRESULT sq_XMLNode_ShallowEqual(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); GET_XMLNode_INSTANCE2(v, 2, compare); sq_pushbool(v, node->ShallowEqual(compare)); return 1; } static SQRESULT sq_XMLNode_Value(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLNode_INSTANCE(v, 1); if(_top_ > 1){ SQ_GET_STRING(v, 2, value); node->SetValue(value); return 0; } else { const char *value = node->Value(); if(value) sq_pushstring(v, value, -1); else sq_pushnull(v); } return 1; } static SQRESULT sq_XMLNode_NoChildren(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLNode_INSTANCE(v, 1); sq_pushbool(v, node->NoChildren()); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLNode_##name,nparams,tycheck} static SQRegFunction XMLNode_methods[] = { _DECL_FUNC(GetDocument,1,_SC("x")), _DECL_FUNC(ToElement,1,_SC("x")), _DECL_FUNC(ToText,1,_SC("x")), _DECL_FUNC(ToComment,1,_SC("x")), _DECL_FUNC(ToDocument,1,_SC("x")), _DECL_FUNC(ToDeclaration,1,_SC("x")), _DECL_FUNC(ToUnknown,1,_SC("x")), _DECL_FUNC(Parent,1,_SC("x")), _DECL_FUNC(FirstChild,1,_SC("x")), _DECL_FUNC(LastChild,1,_SC("x")), _DECL_FUNC(PreviousSibling,1,_SC("x")), _DECL_FUNC(NextSibling,1,_SC("x")), _DECL_FUNC(FirstChildElement,1,_SC("x")), _DECL_FUNC(LastChildElement,1,_SC("x")), _DECL_FUNC(PreviousSiblingElement,1,_SC("x")), _DECL_FUNC(NextSiblingElement,1,_SC("x")), _DECL_FUNC(InsertEndChild,2,_SC("xx")), _DECL_FUNC(LinkEndChild,2,_SC("xx")), _DECL_FUNC(InsertFirstChild,2,_SC("xx")), _DECL_FUNC(InsertAfterChild,3,_SC("xxx")), _DECL_FUNC(DeleteChildren,1,_SC("x")), _DECL_FUNC(DeleteChild,2,_SC("xx")), _DECL_FUNC(ShallowClone,-1,_SC("xx")), _DECL_FUNC(ShallowEqual,2,_SC("xx")), _DECL_FUNC(Value,-1,_SC("xs")), _DECL_FUNC(NoChildren,1,_SC("x")), {0,0} }; #undef _DECL_FUNC static SQRESULT sq_XMLText_CData(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLText_INSTANCE(v, 1); if(_top_ > 1){ SQ_GET_BOOL(v, 2, bvalue); text->SetCData(bvalue); return 0; } else sq_pushbool(v, text->CData()); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLText_##name,nparams,tycheck} static SQRegFunction XMLText_methods[] = { _DECL_FUNC(CData,-1,_SC("xb")), {0,0} }; #undef _DECL_FUNC static SQRESULT sq_XMLAttribute_Name(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLAttribute_INSTANCE(v, 1); sq_pushstring(v, attribute->Name(), -1); return 1; } static SQRESULT sq_XMLAttribute_Value(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLAttribute_INSTANCE(v, 1); sq_pushstring(v, attribute->Value(), -1); return 1; } static SQRESULT sq_XMLAttribute_Next(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLAttribute_INSTANCE(v, 1); const tinyxml2::XMLAttribute *next = attribute->Next(); if(next) return sq_push_xml_class(v, XML_TAG(XMLAttribute), (void*)next); sq_pushnull(v); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLAttribute_##name,nparams,tycheck} static SQRegFunction XMLAttribute_methods[] = { _DECL_FUNC(Name,1,_SC("x")), _DECL_FUNC(Value,1,_SC("x")), _DECL_FUNC(Next,1,_SC("x")), {0,0} }; #undef _DECL_FUNC static SQRESULT sq_XMLElement_Name(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLElement_INSTANCE(v, 1); if(_top_ > 1){ SQ_GET_STRING(v, 2, name); element->SetName(name); return 0; } else sq_pushstring(v, element->Name(), -1); return 1; } static SQRESULT sq_XMLElement_Attribute(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLElement_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); SQ_OPT_STRING(v, 3, value, NULL); const char* res = element->Attribute(name, value); if(res) sq_pushstring(v, res, -1); else sq_pushnull(v); return 1; } static SQRESULT sq_XMLElement_SetAttribute(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLElement_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); SQ_GET_STRING(v, 3, value); element->SetAttribute(name, value); return 0; } static SQRESULT sq_XMLElement_DeleteAttribute(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLElement_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); element->DeleteAttribute(name); return 0; } static SQRESULT sq_XMLElement_FirstAttribute(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLElement_INSTANCE(v, 1); element->FirstAttribute(); return 0; } static SQRESULT sq_XMLElement_FindAttribute(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLElement_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); const tinyxml2::XMLAttribute *attr = ((const tinyxml2::XMLElement*)element)->FindAttribute(name); if(attr) return sq_push_xml_class(v, XML_TAG(XMLAttribute), (void*)attr); sq_pushnull(v); return 1; } static SQRESULT sq_XMLElement_GetText(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLElement_INSTANCE(v, 1); const char *txt = element->GetText(); if(txt) sq_pushstring(v, txt, -1); else sq_pushnull(v); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLElement_##name,nparams,tycheck} static SQRegFunction XMLElement_methods[] = { _DECL_FUNC(Name,-1,_SC("xs")), _DECL_FUNC(Attribute,-1,_SC("xss")), _DECL_FUNC(SetAttribute,3,_SC("xss")), _DECL_FUNC(DeleteAttribute,2,_SC("xs")), _DECL_FUNC(FirstAttribute,1,_SC("x")), _DECL_FUNC(FindAttribute,2,_SC("xs")), _DECL_FUNC(GetText,1,_SC("x")), {0,0} }; #undef _DECL_FUNC static SQRESULT sq_XMLDocument_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) { tinyxml2::XMLDocument *doc = (tinyxml2::XMLDocument *)p; if(doc) delete doc; return 0; } /* ** Creates a new XMLDocument. */ static SQRESULT sq_XMLDocument_constructor (HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLDocument_INSTANCE(v, 1); SQ_OPT_BOOL(v, 2, processEntities, true); SQ_OPT_INTEGER(v, 3, Whitespace, tinyxml2::PRESERVE_WHITESPACE); if(Whitespace == tinyxml2::PRESERVE_WHITESPACE || Whitespace == tinyxml2::COLLAPSE_WHITESPACE) { tinyxml2::XMLDocument *ptr = new tinyxml2::XMLDocument(processEntities, (tinyxml2::Whitespace)Whitespace); sq_setinstanceup(v, 1, ptr); sq_setreleasehook(v, 1, sq_XMLDocument_release_hook); return 1; } return sq_throwerror(v, _SC("invalid value for Whitespace")); } static SQRESULT sq_XMLDocument_Parse(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, xml); SQ_OPT_INTEGER(v, 3, nBytes, -1); sq_pushinteger(v, doc->Parse(xml, (size_t)nBytes)); return 1; } static SQRESULT sq_XMLDocument_LoadFile(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, filename); sq_pushinteger(v, doc->LoadFile(filename)); return 1; } static SQRESULT sq_XMLDocument_SaveFile(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, filename); SQ_OPT_BOOL(v, 3, compact, SQFalse); sq_pushinteger(v, doc->SaveFile(filename, compact)); return 1; } static SQRESULT sq_XMLDocument_HasBOM(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushbool(v, doc->HasBOM()); return 1; } static SQRESULT sq_XMLDocument_SetBOM(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_BOOL(v, 2, useBOM); doc->SetBOM(useBOM); return 0; } static SQRESULT sq_XMLDocument_RootElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); tinyxml2::XMLElement *ptr = doc->RootElement(); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLDocument_NewElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); tinyxml2::XMLElement *ptr = doc->NewElement(name); return sq_push_xml_class(v, XML_TAG(XMLElement), ptr); } static SQRESULT sq_XMLDocument_NewComment(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); tinyxml2::XMLComment *ptr = doc->NewComment(name); return sq_push_xml_class(v, XML_TAG(XMLComment), ptr); } static SQRESULT sq_XMLDocument_NewText(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); tinyxml2::XMLText *ptr = doc->NewText(name); return sq_push_xml_class(v, XML_TAG(XMLText), ptr); } static SQRESULT sq_XMLDocument_NewDeclaration(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLDocument_INSTANCE(v, 1); SQ_OPT_STRING(v, 2, name, NULL); tinyxml2::XMLDeclaration *ptr = doc->NewDeclaration(name); return sq_push_xml_class(v, XML_TAG(XMLDeclaration), ptr); } static SQRESULT sq_XMLDocument_NewUnknown(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); tinyxml2::XMLUnknown *ptr = doc->NewUnknown(name); return sq_push_xml_class(v, XML_TAG(XMLUnknown), ptr); } static SQRESULT sq_XMLDocument_DeleteNode(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); GET_XMLNode_INSTANCE(v, 2); doc->DeleteNode(node); return 0; } static SQRESULT sq_XMLDocument_Error(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushbool(v, doc->Error()); return 1; } static SQRESULT sq_XMLDocument_ErrorID(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushinteger(v, doc->ErrorID()); return 1; } static SQRESULT sq_XMLDocument_GetErrorStr1(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushstring(v, doc->GetErrorStr1(), -1); return 1; } static SQRESULT sq_XMLDocument_GetErrorStr2(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushstring(v, doc->GetErrorStr2(), -1); return 1; } static SQRESULT sq_XMLDocument_ProcessEntities(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushbool(v, doc->ProcessEntities()); return 1; } static SQRESULT sq_XMLDocument_WhitespaceMode(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); sq_pushinteger(v, doc->WhitespaceMode()); return 1; } static SQRESULT sq_XMLDocument_tostring(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLDocument_INSTANCE(v, 1); tinyxml2::XMLPrinter printer; doc->Print( &printer ); sq_pushstring(v, printer.CStr(), printer.CStrSize()); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLDocument_##name,nparams,tycheck} static SQRegFunction XMLDocument_methods[] = { _DECL_FUNC(constructor,-1,_SC("xbi")), _DECL_FUNC(Parse,-2,_SC("xsi")), _DECL_FUNC(LoadFile,2,_SC("xs")), _DECL_FUNC(SaveFile,-2,_SC("xsb")), _DECL_FUNC(HasBOM,1,_SC("x")), _DECL_FUNC(SetBOM,2,_SC("xb")), _DECL_FUNC(RootElement,1,_SC("x")), _DECL_FUNC(NewElement,2,_SC("xs")), _DECL_FUNC(NewComment,2,_SC("xs")), _DECL_FUNC(NewText,2,_SC("xs")), _DECL_FUNC(NewDeclaration,-1,_SC("xs")), _DECL_FUNC(NewUnknown,2,_SC("xs")), _DECL_FUNC(DeleteNode,2,_SC("xx")), _DECL_FUNC(Error,1,_SC("x")), _DECL_FUNC(ErrorID,1,_SC("x")), _DECL_FUNC(GetErrorStr1,1,_SC("x")), _DECL_FUNC(GetErrorStr2,1,_SC("x")), _DECL_FUNC(ProcessEntities,1,_SC("x")), _DECL_FUNC(WhitespaceMode,1,_SC("x")), _DECL_FUNC(tostring,1,_SC("x")), {0,0} }; #undef _DECL_FUNC static SQRESULT sq_XMLPrinter_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) { tinyxml2::XMLPrinter *printer = (tinyxml2::XMLPrinter *)p; if(printer) delete printer; return 0; } /* ** Creates a new XMLDocument. */ static SQRESULT sq_XMLPrinter_constructor (HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_OPT_BOOL(v, 2, compact, false); tinyxml2::XMLPrinter *ptr = new tinyxml2::XMLPrinter(0, compact); sq_setinstanceup(v, 1, ptr); sq_setreleasehook(v, 1, sq_XMLPrinter_release_hook); return 1; } static SQRESULT sq_XMLPrinter_PushHeader(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_BOOL(v, 2, writeBOM); SQ_GET_BOOL(v, 3, writeDeclaration); printer->PushHeader(writeBOM, writeDeclaration); return 0; } static SQRESULT sq_XMLPrinter_OpenElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); printer->OpenElement(name); return 0; } static SQRESULT sq_XMLPrinter_PushAttribute(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, name); SQ_GET_STRING(v, 3, value); printer->PushAttribute(name, value); return 0; } static SQRESULT sq_XMLPrinter_CloseElement(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); printer->CloseElement(); return 0; } static SQRESULT sq_XMLPrinter_PushText(HSQUIRRELVM v) { SQ_FUNC_VARS(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, text); SQ_OPT_BOOL(v, 3, cdata, false); printer->PushText(text, cdata); return 0; } static SQRESULT sq_XMLPrinter_PushComment(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, comment); printer->PushComment(comment); return 0; } static SQRESULT sq_XMLPrinter_PushDeclaration(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, value); printer->PushDeclaration(value); return 0; } static SQRESULT sq_XMLPrinter_PushUnknown(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); SQ_GET_STRING(v, 2, value); printer->PushUnknown(value); return 0; } static SQRESULT sq_XMLPrinter_tostring(HSQUIRRELVM v) { SQ_FUNC_VARS_NO_TOP(v); GET_XMLPrinter_INSTANCE(v, 1); sq_pushstring(v, printer->CStr(), printer->CStrSize()); return 1; } #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_XMLPrinter_##name,nparams,tycheck} static SQRegFunction XMLPrinter_methods[] = { _DECL_FUNC(constructor,-1,_SC("xb")), _DECL_FUNC(PushHeader,-1,_SC("xbb")), _DECL_FUNC(OpenElement,2,_SC("xs")), _DECL_FUNC(PushAttribute,3,_SC("xss")), _DECL_FUNC(CloseElement,1,_SC("x")), _DECL_FUNC(PushText,-2,_SC("xsb")), _DECL_FUNC(PushComment,2,_SC("xs")), _DECL_FUNC(PushDeclaration,2,_SC("xs")), _DECL_FUNC(PushUnknown,2,_SC("xs")), _DECL_FUNC(tostring,1,_SC("x")), {0,0} }; #undef _DECL_FUNC static SQRESULT xml_pushnewclass(HSQUIRRELVM v, const SQChar *klass, const SQChar *parent, void *tag, SQRegFunction *obj_funcs, SQBool isStatic){ sq_pushstring(v, klass,-1); if(parent){ sq_pushstring(v, parent,-1); if (SQ_FAILED(sq_get(v, -3))) return sq_throwerror(v, _SC("Missing base class.")); } sq_newclass(v, parent ? SQTrue : SQFalse); sq_settypetag(v,-1,tag); if(obj_funcs) sq_insert_reg_funcs(v, obj_funcs); sq_newslot(v,-3, isStatic); return SQ_OK; } #define PUSH_XML_CLASS0(klass)\ if(xml_pushnewclass(v, #klass, 0, (void*)XML_TAG(klass), klass##_methods, SQFalse) < 0) return SQ_ERROR; #define PUSH_XML_CLASS(klass, parent)\ if(xml_pushnewclass(v, #klass, #parent, (void*)XML_TAG(klass), klass##_methods, SQFalse) < 0) return SQ_ERROR; #define PUSH_XML_CLASS2(klass, parent)\ if(xml_pushnewclass(v, #klass, #parent, (void*)XML_TAG(klass), 0, SQFalse) < 0) return SQ_ERROR; #ifdef __cplusplus extern "C" { #endif #define CONST_INT(num) sq_pushstring(v,_SC(#num),-1);sq_pushinteger(v, tinyxml2::num);sq_newslot(v,-3,SQTrue); SQRESULT sqext_register_tinyxml2(HSQUIRRELVM v) { sq_pushstring(v, sq_tinyxml2_TAG, -1); sq_newtable(v); CONST_INT(XML_NO_ERROR); CONST_INT(XML_SUCCESS); CONST_INT(XML_NO_ATTRIBUTE); CONST_INT(XML_WRONG_ATTRIBUTE_TYPE); CONST_INT(XML_ERROR_FILE_NOT_FOUND); CONST_INT(XML_ERROR_FILE_COULD_NOT_BE_OPENED); CONST_INT(XML_ERROR_FILE_READ_ERROR); CONST_INT(XML_ERROR_ELEMENT_MISMATCH); CONST_INT(XML_ERROR_PARSING_ELEMENT); CONST_INT(XML_ERROR_PARSING_ATTRIBUTE); CONST_INT(XML_ERROR_IDENTIFYING_TAG); CONST_INT(XML_ERROR_PARSING_TEXT); CONST_INT(XML_ERROR_PARSING_CDATA); CONST_INT(XML_ERROR_PARSING_COMMENT); CONST_INT(XML_ERROR_PARSING_DECLARATION); CONST_INT(XML_ERROR_PARSING_UNKNOWN); CONST_INT(XML_ERROR_EMPTY_DOCUMENT); CONST_INT(XML_ERROR_MISMATCHED_ELEMENT); CONST_INT(XML_ERROR_PARSING); CONST_INT(XML_CAN_NOT_CONVERT_TEXT); CONST_INT(XML_NO_TEXT_NODE); CONST_INT(PRESERVE_WHITESPACE); CONST_INT(COLLAPSE_WHITESPACE); sq_pushstring(v,XML_TAG(XMLNode),-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(void*)XML_TAG(XMLNode)); sq_insert_reg_funcs(v, XMLNode_methods); sq_newslot(v,-3,SQTrue); PUSH_XML_CLASS2(XMLComment, XMLNode); PUSH_XML_CLASS(XMLText, XMLNode); PUSH_XML_CLASS2(XMLDeclaration, XMLNode); PUSH_XML_CLASS2(XMLUnknown, XMLNode); PUSH_XML_CLASS0(XMLAttribute); PUSH_XML_CLASS(XMLElement, XMLNode); PUSH_XML_CLASS(XMLDocument, XMLNode); PUSH_XML_CLASS0(XMLPrinter); sq_newslot(v,-3,SQTrue); return 0; } #ifdef __cplusplus } #endif