LCOV - code coverage report
Current view: top level - ugbase/bindings/lua - lua_serialization.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 10.2 % 59 6
Test Date: 2025-09-21 23:31:46 Functions: 16.7 % 6 1

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2014:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : /**
      34              :  * \file lua_serialization.cpp
      35              :  *
      36              :  * \author Martin Rupp
      37              :  *
      38              :  * \date 23.06.2014
      39              :  *
      40              :  * Goethe-Center for Scientific Computing 2014.
      41              :  *
      42              :  * Serialization stuff for lua.
      43              :  * not fully developed.
      44              :  * the idea is to call Serialize(obj, serializationObj) for all UserData-Objects, if this Serialize is registered in the registry.
      45              :  */
      46              : 
      47              : #include <iomanip>
      48              : #include "bindings/lua/lua_util.h"
      49              : #include "bindings/lua/bindings_lua.h"
      50              : #include "bridge/bridge.h"
      51              : #include "bridge/util.h"
      52              : #include "registry/class_helper.h"
      53              : #include "common/util/sort_util.h"
      54              : #include "common/util/string_util.h"
      55              : #include "lua_stack_check.h"
      56              : #include "registry/class_name_provider.h"
      57              : #include "common/util/string_util.h"
      58              : 
      59              : #include "common/util/stringify.h"
      60              : //#include "bridge/misc_bridges/serialization.h"
      61              : #include "bindings_lua.h"
      62              : //#include "lua_parsing.h"
      63              : 
      64              : #include "info_commands.h"
      65              : 
      66              : using namespace std;
      67              : 
      68              : namespace ug{
      69              : size_t SerializerGetLastID();
      70              : 
      71              : namespace bridge{
      72              : 
      73            0 : string LUAStringEscape(string s)
      74              : {
      75            0 :         s = ReplaceAll(s, "\\", "\\\\");
      76            0 :         s = ReplaceAll(s, "\"", "\\\"");
      77            0 :         s = ReplaceAll(s, "\n", "\\n");
      78            0 :         return s;
      79              : }
      80              : 
      81              : 
      82              : #if 0
      83              : namespace lua{
      84              : struct MyLuaParsing
      85              : {
      86              :         static bool checkAndGet(std::pair<ConstSmartPtr<void>, const ClassNameNode*>& res,
      87              :                                 lua_State* L, int index, const char* baseClassName){
      88              :                 if(!lua_isuserdata(L, index)) return false;
      89              : 
      90              :                 UserDataWrapper* udata =
      91              :                         reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
      92              : 
      93              :                 if(!udata->is_smart_ptr()) return false;
      94              : 
      95              :                 ConstSmartPtr<void> obj;
      96              :                 if(((UserDataWrapper*)lua_touserdata(L, index))->is_const())
      97              :                         obj = ((ConstSmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
      98              :                 else
      99              :                         obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
     100              : 
     101              :                 if(lua_getmetatable(L, index) == 0) return false;
     102              :                 lua_pushstring(L, "class_name_node");
     103              :                 lua_rawget(L, -2);
     104              :                 const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
     105              :                 lua_pop(L, 2);
     106              : 
     107              :                 if(!classNameNode) return false;
     108              :                 if(classNameNode->empty()) return false;
     109              :                 if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
     110              : 
     111              :                 res.first = obj;
     112              :                 res.second = classNameNode;
     113              : 
     114              :                 return true;
     115              :         }
     116              : 
     117              :         static void push(lua_State* L, ConstSmartPtr<void> data, const char* className){
     118              :                 CreateNewUserData(L, data, className);
     119              :         }
     120              : };
     121              : }
     122              : 
     123              : 
     124              : template <typename T>
     125              : static bool PushLuaStackPointerEntryToParamStack(ParameterStack& ps, lua_State* L,
     126              :                                                  int index, const char* baseClassName,
     127              :                                                  bool bIsVector)
     128              : {
     129              :         typedef std::pair<T, const ClassNameNode*> result_type;
     130              : 
     131              :         result_type res;
     132              :         if(!bIsVector){
     133              : 
     134              :                 UG_LOG(GetLuaTypeString(L, -1) << " " << baseClassName << "\n");
     135              :                 if(lua::MyLuaParsing::checkAndGet(res, L, index, baseClassName)){
     136              :                         ps.push(res.first, res.second);
     137              :                 }
     138              :                 else return false;
     139              :         }
     140              :         else {UG_THROW("ll");
     141              :         }
     142              :         return true;
     143              : }
     144              : 
     145              : const void *getPtr(lua::UserDataWrapper *self)
     146              : {
     147              :         //      raw pointer
     148              :         if(self->is_raw_ptr())
     149              :         {
     150              :         //      cast to the needed base class
     151              :                 return ((lua::RawUserDataWrapper*)self)->obj;
     152              :         }
     153              : //      smart pointer
     154              :         else if(self->is_smart_ptr())
     155              :         {
     156              :                 if(self->is_const())
     157              :                 //      cast to the needed base class
     158              :                         return (void*)((lua::ConstSmartUserDataWrapper*)self)->smartPtr.get();
     159              :                 else
     160              :                         return ((lua::SmartUserDataWrapper*)self)->smartPtr.get();
     161              :         }
     162              : }
     163              : 
     164              : TheSerializer theSerializer;
     165              : #endif
     166              : 
     167            0 : void WriteLUAObject2(lua_State* L, std::string name, std::ostream &s)
     168              : {
     169              :         //UG_LOG(" " << lua_tostring(L, -1) << "\n");
     170            0 :         if(lua_isnil(L, -1))
     171            0 :                 s << name << " = nil\n";
     172            0 :         else if(lua_isboolean(L, -1))
     173            0 :                 s << name << " = " << (lua_toboolean(L, -1)==true ? "true" : "false") << "\n";
     174            0 :         else if(lua_isnumber(L, -1))
     175            0 :                 s << name << " = " << lua_tostring(L, -1) << "\n";
     176            0 :         else if(lua_isstring(L, -1))
     177            0 :                 s << name << " = \"" << LUAStringEscape(lua_tostring(L, -1)) << "\"\n";
     178            0 :         else if(lua_istable(L, -1))
     179              :         {
     180            0 :                 lua_pushvalue(L, -1);
     181              :                 /* table is in the stack at index 't' */
     182            0 :                 s << name << " = " << name << " or {}\n";
     183              :                 //UG_LOG(name << " = " << name << " or {}\n");
     184            0 :                 lua_pushnil(L);
     185            0 :                 while (lua_next(L, -2) != 0)
     186              :                 {
     187              :                         std::string nextname;
     188              :                         // copy the key so that lua_tostring does not modify the original
     189            0 :                         lua_pushvalue(L, -2);
     190            0 :                         if(lua_type(L, -1) == LUA_TNUMBER)
     191            0 :                                 nextname = Stringify() << "\t" << name << "[" << lua_tostring(L, -1) << "]";
     192              :                         else
     193            0 :                                 nextname = Stringify() << "\t" << name << "[\"" << lua_tostring(L, -1) << "\"]";
     194            0 :                         lua_pop(L, 1);
     195              : 
     196              :                         // also copy value
     197            0 :                         lua_pushvalue(L, -1);
     198            0 :                         WriteLUAObject2(L, nextname, s);
     199            0 :                     lua_pop(L, 2);
     200              :                  }
     201            0 :                 lua_pop(L, 1);
     202              : 
     203              :         }
     204            0 :         else if(lua_isuserdata(L, -1))
     205              :         {
     206              : #if 0
     207              :                 const ClassNameNode&  cnn = SerializeObject::class_name_node();
     208              :                 lua::UserDataWrapper* self = (lua::UserDataWrapper*)lua_touserdata(L, 1);
     209              :                 size_t id = theSerializer.is_serialized(self);
     210              :                 if(id == 0)
     211              :                 {
     212              :                         const ExportedFunctionGroup* funcGrp = GetUGRegistry().get_exported_function_group("Serialize");
     213              :                         if(funcGrp)
     214              :                         {
     215              :                         //      we have to try each overload!
     216              :                                 for(size_t i = 0; i < funcGrp->num_overloads(); ++i){
     217              :                                         const ExportedFunction* func = funcGrp->get_overload(i);
     218              : 
     219              :                                         ParameterStack paramsIn;
     220              :                                         ParameterStack paramsOut;
     221              :                                         const ParameterInfo &psInfo = func->params_in();
     222              : 
     223              :                                         if(PushLuaStackPointerEntryToParamStack<ConstSmartPtr<void> >
     224              :                                                         (paramsIn, L, -1, psInfo.class_name(0), false))
     225              :                                         {
     226              :                                                 size_t id = theSerializer.create_id(self);
     227              :                                                 SerializeObject so(theSerializer, id);
     228              : 
     229              : 
     230              :                                                 paramsIn.push(&so, &cnn);
     231              :                                                 func->execute(paramsIn, paramsOut);
     232              : 
     233              :                                                 theSerializer.serialize(so.buffer(), id, psInfo.class_name(0));
     234              :                                                 break;
     235              :                                         }
     236              : 
     237              :                                 }
     238              :                         }
     239              : 
     240              :                 }
     241              : 
     242              : 
     243              :                 if(id == 0)
     244              :                         s << name << " = nil -- no Serialize(" << GetLuaTypeString(L, -1) << ")\n";
     245              :                 else
     246              :                         s << name << " = SerializerGet(" << id << ")\n";
     247              : #else
     248            0 :                 s << name << " = nil -- Userdata serialize not yet supported\n";
     249              : #endif
     250              : 
     251              :         }
     252              :         else
     253              :         {
     254            0 :                 const char *p =lua_tostring(L, -1);
     255            0 :                 s << "-- " << name << " = " << GetLuaTypeString(L, -1) << " ";
     256            0 :                 if(p) s << p;
     257            0 :                 s << "\n";
     258              :         }
     259              : 
     260            0 : }
     261            0 : void WriteLUAObject(lua_State* L, std::string name, std::ostream &s)
     262              : {
     263            0 :         lua_getglobal(L, name.c_str());
     264            0 :         WriteLUAObject2(L, name, s);
     265            0 :         lua_pop(L, 1);
     266            0 : }
     267              : 
     268              : /*void LuaList_writeObjects(const char*filename)
     269              : {
     270              :         fstream file(filename, ios::out);
     271              :         lua_State* L = script::GetDefaultLuaState();
     272              :         std::vector<std::string> luaObjects;
     273              :         GetLuaGlobal_luaObjects(luaObjects);
     274              : 
     275              :         if(luaObjects.empty()) return;
     276              :         int maxLength = (*max_element(luaObjects.begin(), luaObjects.end(), IsLonger)).size();
     277              :         for(size_t i=0; i<luaObjects.size(); i++)
     278              :         {
     279              :                 if(luaObjects[i].compare("_G") == 0) continue;
     280              :                 if(luaObjects[i].compare("package") == 0) continue;
     281              :                 WriteLUAObject(L, luaObjects[i].c_str(), std::cout);
     282              :         }
     283              : }*/
     284              : 
     285            0 : void LuaWrite(const char *filename, const char* obj)
     286              : {
     287            0 :         fstream file(filename, ios::out);
     288            0 :         file << "function LoadTheCheckpoint()\n";
     289            0 :         lua_State* L = script::GetDefaultLuaState();
     290            0 :         WriteLUAObject(L, obj, file);
     291            0 :         file << "return " << obj << "\n";
     292            0 :         file << "end\n";
     293            0 : }
     294              : 
     295            0 : void LuaWriteCout(const char* obj)
     296              : {
     297            0 :         lua_State* L = script::GetDefaultLuaState();
     298            0 :         WriteLUAObject(L, obj, std::cout);
     299            0 : }
     300              : 
     301              : 
     302            1 : bool RegisterSerializationCommands(Registry &reg, const char* parentGroup)
     303              : {
     304            1 :         stringstream grpSS; grpSS << parentGroup << "/Serialization";
     305              :         std::string grp = grpSS.str();
     306              : 
     307              :         try
     308              :         {
     309              : //              reg.add_function("LuaList_writeObjects", &LuaList_writeObjects, grp.c_str());
     310            2 :                 reg.add_function("LuaWrite", &LuaWrite, grp.c_str());
     311            2 :                 reg.add_function("LuaWriteCout", &LuaWriteCout, grp.c_str());
     312              :         }
     313            0 :         UG_REGISTRY_CATCH_THROW(grp);
     314              : 
     315            1 :         return true;
     316            1 : }
     317              : 
     318              : }
     319              : }
        

Generated by: LCOV version 2.0-1