lugre_luaxml.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_luaxml.h"
00003 #include "tinyxml.h"
00004 #include <string>
00005 
00006 
00007 namespace Lugre {
00008 
00009 /*
00010 lua array manipulation from c :
00011 
00012 lua_rawseti
00013           void lua_rawseti (lua_State *L, int index, int n);
00014 Does the equivalent of t[n] = v, where t is the value at the given valid index index and v is the value at the top of the stack,
00015 This function pops the value from the stack. The assignment is raw; that is, it does not invoke metamethods. 
00016 
00017 lua_setfield
00018           void lua_setfield (lua_State *L, int index, const char *k);
00019 Does the equivalent to t[k] = v, where t is the value at the given valid index index and v is the value at the top of the stack,
00020 This function pops the value from the stack. As in Lua, this function may trigger a metamethod for the "newindex" event (see 2.8). 
00021 
00022 lua_settable
00023           void lua_settable (lua_State *L, int index);
00024 Does the equivalent to t[k] = v, where t is the value at the given valid index index, v is the value at the top of the stack, 
00025 and k is the value just below the top.
00026 This function pops both the key and the value from the stack. As in Lua, 
00027 this function may trigger a metamethod for the "newindex" event (see 2.8). 
00028 
00029 lua_rawset
00030           void lua_rawset (lua_State *L, int index);
00031 Similar to lua_settable, but does a raw assignment (i.e., without metamethods). 
00032 
00033 lua_pushstring
00034           void lua_pushstring (lua_State *L, const char *s);
00035 
00036 lua_createtable
00037           void lua_createtable (lua_State *L, int narr, int nrec);
00038 Creates a new empty table and pushes it onto the stack. The new table has space pre-allocated 
00039 for narr array elements and nrec non-array elements. 
00040 This pre-allocation is useful when you know exactly how many elements the table will have. 
00041 Otherwise you can use the function lua_newtable. 
00042 
00043 */
00044 
00045 
00046 extern "C" {
00047     #include "lua.h"
00048     #include "lauxlib.h"
00049     #include "lualib.h"
00050 }
00051 
00070 void LuaXML_FillNode (lua_State *L,int iTableIndex,TiXmlNode* pParent) { PROFILE
00071     // resize stack if neccessary
00072     luaL_checkstack(L, 5, "LuaXML_ParseNode : recursion too deep");
00073     if (!lua_istable(L,iTableIndex)) { printf("LuaXML_FillNode : no table\n"); return; }
00074     
00075     /*
00076         TiXmlDocument doc;
00077     TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
00078     TiXmlElement * element = new TiXmlElement( "Hello" );
00079     TiXmlText * text = new TiXmlText( "World" );
00080     element->LinkEndChild( text );
00081     doc.LinkEndChild( decl );
00082     doc.LinkEndChild( element );
00083     doc.SaveFile( "madeByHand.xml" );
00084 
00085     */
00086     
00087     // name
00088     lua_getfield(L,iTableIndex,"name");
00089     //~ printf("LuaXML_FillNode:got name (pushed)\n");
00090     std::string sName = lua_tostring(L,-1);
00091     //~ printf("LuaXML_FillNode:name=%s\n",sName.c_str());
00092     lua_pop(L,1); // pop 1 elements
00093     
00094     TiXmlElement* pElem = new TiXmlElement(sName.c_str());
00095     
00096     // attr
00097     lua_getfield(L,iTableIndex,"attr");
00098     //~ printf("LuaXML_FillNode:attr 1\n");
00099     if (lua_istable(L,-1)) { // iterate over attributes
00100         lua_pushnil(L);  // first key
00101         while (lua_next(L,-2) != 0) { // table is at stack idx -1
00102                    //~ printf("%s - %s\n",
00103               //~ lua_typename(L, lua_type(L, -2)),
00104               //~ lua_typename(L, lua_type(L, -1)));
00105 
00106             std::string sAttrName   = lua_tostring(L,-2);
00107             //~ printf("attr:name=%s\n",sAttrName.c_str());
00108             std::string sAttrValue  = lua_tostring(L,-1);
00109             //~ printf("attr:value=%s\n",sAttrValue.c_str());
00110             pElem->SetAttribute(sAttrName.c_str(),sAttrValue.c_str());
00111             lua_pop(L, 1); // removes 'value'; keeps 'key' for next iteration
00112         }
00113     }
00114     //~ printf("LuaXML_FillNode:attr 2\n");
00115     lua_pop(L,1); // pop 1 elements
00116     
00117     
00118     // n
00119     lua_getfield(L,iTableIndex,"n");
00120     int n = (int)lua_tonumber(L,-1);
00121     //~ printf("LuaXML_FillNode:n=%d\n",n);
00122     lua_pop(L,1); // pop 1 elements
00123     
00124     // childs
00125     for (int i=1;i<=n;++i) {
00126         lua_rawgeti(L,iTableIndex,i); // table is at index 1
00127         //~ printf("LuaXML_FillNode:child1 %d %s\n",i,lua_typename(L, lua_type(L, -1))); 
00128 
00129         if (lua_isstring(L,-1)) {
00130             //~ printf(" LuaXML_FillNode:txt1\n");
00131             std::string sText = lua_tostring(L,-1);
00132             //~ printf(" LuaXML_FillNode:txt2 %s\n",sText.c_str());
00133             pElem->LinkEndChild( new TiXmlText( sText.c_str() ) );
00134         }
00135         if (lua_istable(L,-1)) {
00136             //~ printf(" LuaXML_FillNode:childnode1\n");
00137             LuaXML_FillNode(L,-1,pElem);
00138             //~ printf(" LuaXML_FillNode:childnode2\n");
00139         }
00140         //~ printf("LuaXML_FillNode:child2\n");
00141         lua_pop(L,1); // pop 1 elements
00142     }
00143     
00144     pParent->LinkEndChild( pElem );
00145 }
00146 
00147 void LuaXML_ParseNode (lua_State *L,TiXmlNode* pNode) { PROFILE
00148     if (!pNode) return;
00149     // resize stack if neccessary
00150     luaL_checkstack(L, 5, "LuaXML_ParseNode : recursion too deep");
00151     
00152     TiXmlElement* pElem = pNode->ToElement();
00153     if (pElem) {
00154         // element name
00155         lua_pushstring(L,"name");
00156         lua_pushstring(L,pElem->Value());
00157         lua_settable(L,-3);
00158         //lua_setfield(L,-2,"name");
00159         
00160         // parse attributes
00161         TiXmlAttribute* pAttr = pElem->FirstAttribute();
00162         if (pAttr) {
00163             lua_pushstring(L,"attr");
00164             lua_newtable(L);
00165             for (;pAttr;pAttr = pAttr->Next()) {
00166                 lua_pushstring(L,pAttr->Name());
00167                 lua_pushstring(L,pAttr->Value());
00168                 //lua_setfield(L,-2,pAttr->Name());
00169                 lua_settable(L,-3);
00170                 
00171             }
00172             //lua_setfield(L,-2,"attr");
00173             lua_settable(L,-3);
00174         }
00175     }
00176     
00177     // children
00178     TiXmlNode *pChild = pNode->FirstChild();
00179     if (pChild) {
00180         int iChildCount = 0;
00181         for(;pChild;pChild = pChild->NextSibling()) {
00182             switch (pChild->Type()) {
00183                 case TiXmlNode::DOCUMENT: break;
00184                 case TiXmlNode::ELEMENT: 
00185                     // normal element, parse recursive
00186                     lua_newtable(L);
00187                     LuaXML_ParseNode(L,pChild);
00188                     lua_rawseti(L,-2,++iChildCount);
00189                 break;
00190                 case TiXmlNode::COMMENT: break;
00191                 case TiXmlNode::TEXT: 
00192                     // plaintext, push raw
00193                     lua_pushstring(L,pChild->Value());
00194                     lua_rawseti(L,-2,++iChildCount);
00195                 break;
00196                 case TiXmlNode::DECLARATION: break;
00197                 case TiXmlNode::UNKNOWN: break;
00198             };
00199         }
00200         lua_pushstring(L,"n");
00201         lua_pushnumber(L,iChildCount);
00202         //lua_setfield(L,-2,"n");
00203         lua_settable(L,-3);
00204     }
00205 }
00206 
00207 static int LuaXML_ParseFile (lua_State *L) { PROFILE
00208     const char* sFileName = luaL_checkstring(L,1);
00209     TiXmlDocument doc(sFileName);
00210     doc.LoadFile();
00211     lua_newtable(L);
00212     LuaXML_ParseNode(L,&doc);
00213     return 1;
00214 }
00215 
00216 static int LuaXML_ParseString (lua_State *L) { PROFILE
00217     const char* sString = luaL_checkstring(L,1);
00218     TiXmlDocument doc;
00219     doc.Parse(sString,0,TIXML_DEFAULT_ENCODING);
00220     lua_newtable(L);
00221     LuaXML_ParseNode(L,&doc);
00222     return 1;
00223 }
00224 
00226 static int  LuaXML_SaveFile (lua_State *L) { PROFILE
00227     std::string sFileName = luaL_checkstring(L,1);
00228     TiXmlDocument doc;
00229     LuaXML_FillNode(L,2,&doc);
00230     doc.SaveFile(sFileName.c_str());
00231     return 1;
00232 }
00233 
00234 void    RegisterLuaXML (lua_State *L) {
00235     lua_register(L,"LuaXML_ParseFile",LuaXML_ParseFile);
00236     lua_register(L,"LuaXML_ParseString",LuaXML_ParseString);
00237     lua_register(L,"LuaXML_SaveFile",LuaXML_SaveFile);
00238 }
00239 
00240 };

Generated on Wed May 23 06:00:14 2012 for cpp by  doxygen 1.5.6