/* * Baltisot * Copyright (C) 1999-2007 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "tinyxml.h" #include #include class LuaXML : public Base { public: static void ParseNode (lua_State *L,TiXmlNode* pNode) { if (!pNode) return; // resize stack if neccessary luaL_checkstack(L, 5, "LuaXML_ParseNode : recursion too deep"); TiXmlElement* pElem = pNode->ToElement(); if (pElem) { // element name lua_pushstring(L,"name"); lua_pushstring(L,pElem->Value()); lua_settable(L,-3); // parse attributes TiXmlAttribute* pAttr = pElem->FirstAttribute(); if (pAttr) { lua_pushstring(L,"attr"); lua_newtable(L); for (;pAttr;pAttr = pAttr->Next()) { lua_pushstring(L,pAttr->Name()); lua_pushstring(L,pAttr->Value()); lua_settable(L,-3); } lua_settable(L,-3); } } // children TiXmlNode *pChild = pNode->FirstChild(); if (pChild) { int iChildCount = 0; for(;pChild;pChild = pChild->NextSibling()) { switch (pChild->Type()) { case TiXmlNode::DOCUMENT: break; case TiXmlNode::ELEMENT: // normal element, parse recursive lua_newtable(L); ParseNode(L,pChild); lua_rawseti(L,-2,++iChildCount); break; case TiXmlNode::COMMENT: break; case TiXmlNode::TEXT: // plaintext, push raw lua_pushstring(L,pChild->Value()); lua_rawseti(L,-2,++iChildCount); break; case TiXmlNode::DECLARATION: break; case TiXmlNode::UNKNOWN: break; }; } lua_pushstring(L,"n"); lua_pushnumber(L,iChildCount); lua_settable(L,-3); } } static int ParseFile (lua_State *L) { const char* sFileName = luaL_checkstring(L,1); TiXmlDocument doc(sFileName); doc.LoadFile(); lua_newtable(L); ParseNode(L,&doc); return 1; } static int ParseString(lua_State *L) { const char * xml_string = luaL_checkstring(L, 1); TiXmlDocument doc; doc.Parse(xml_string); lua_newtable(L); ParseNode(L, &doc); return 1; } #define XMLBUFSIZ 81920 static int ParseHandle(lua_State *__L) { Lua * L = Lua::find(__L); Handle * h = (Handle *) LuaObject::getme(L, 1); TiXmlDocument doc; char buffer[XMLBUFSIZ + 1]; int l; while (!h->IsClosed()) { l = h->read(buffer, XMLBUFSIZ); if (l) { buffer[l] = 0; doc.Parse(buffer); } } lua_newtable(__L); ParseNode(__L, &doc); return 1; } }; static const luaL_reg xmllib[] = { { "LoadString", LuaXML::ParseString }, { "LoadHandle", LuaXML::ParseHandle }, { NULL, NULL } }; int luaopen_xml(Lua *L) { L->openlib("xml", xmllib, 0); return 1; }