diff options
-rw-r--r-- | server/src/database.h | 1 | ||||
-rw-r--r-- | server/src/luaquerymapper.cc | 79 | ||||
-rw-r--r-- | server/src/luaquerymapper.h | 2 | ||||
-rw-r--r-- | server/src/server.cc | 32 | ||||
-rw-r--r-- | server/src/widgetgenerator.cc | 35 | ||||
-rw-r--r-- | server/src/widgetgenerator.h | 7 | ||||
-rw-r--r-- | server/xml/macros/example.xml | 43 |
7 files changed, 111 insertions, 88 deletions
diff --git a/server/src/database.h b/server/src/database.h index 8200129..31d69fc 100644 --- a/server/src/database.h +++ b/server/src/database.h @@ -38,6 +38,7 @@ class Value { public: + Value() : value(""), timestamp(0) {} std::string value; time_t timestamp; }; diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc index df25778..5b66a35 100644 --- a/server/src/luaquerymapper.cc +++ b/server/src/luaquerymapper.cc @@ -28,6 +28,8 @@ #include <sstream> +#include "exception.h" + static std::string loadresultstring(QueryResult &res, std::string group = "") { std::string s; @@ -55,29 +57,24 @@ LUAQueryMapper::LUAQueryMapper(QueryResult &res) { L = luaL_newstate(); if(L == NULL) { - // throw LUADataParserException("Could not create LUA state."); + error("Could not create LUA state."); + return; } luaL_openlibs(L); std::string preload = loadresultstring(res); - int s = luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload"); - switch(s) { - case 0: //no errors; - break; - case LUA_ERRSYNTAX: //syntax error during pre-compilation; - case LUA_ERRMEM: //memory allocation error. - case LUA_ERRFILE: //cannot open/read the file. - //throw LUADataParserException(lua_tostring(L, lua_gettop(L))); - break; - default: - //throw LUADataParserException("Unknown return value of luaL_loadfile."); - break; + if(luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload")) { + error(lua_tostring(L, lua_gettop(L))); + return; } // Run program (init) - lua_pcall(L, 0, LUA_MULTRET, 0); + if(lua_pcall(L, 0, LUA_MULTRET, 0)) { + error(lua_tostring(L, lua_gettop(L))); + return; + } clean_top = lua_gettop(L); } @@ -91,47 +88,61 @@ Value LUAQueryMapper::map(const std::string &mapper) { Value v; + if(L == NULL) { + error("LUA state not initialized!"); + return v; + } + if(mapper == "") { - printf("Empty LUA mapper detected!\n"); - v.timestamp = 0; - v.value = ""; + error("Empty LUA mapper detected in " + mapper); + return v; } - int s = luaL_loadbuffer(L, mapper.c_str(), mapper.size(), "mapper"); - switch(s) { - case 0: //no errors; - break; - case LUA_ERRSYNTAX: //syntax error during pre-compilation; - case LUA_ERRMEM: //memory allocation error. - case LUA_ERRFILE: //cannot open/read the file. - //throw LUADataParserException(lua_tostring(L, lua_gettop(L))); - break; - default: - //throw LUADataParserException("Unknown return value of luaL_loadfile."); - break; + // Load the mapper + if(luaL_loadbuffer(L, mapper.c_str(), mapper.size(), "mapper")) { + error(lua_tostring(L, lua_gettop(L)) + std::string(" in ") + mapper); + return v; } // Run the loaded code - lua_pcall(L, 0, LUA_MULTRET, 0); + if(lua_pcall(L, 0, LUA_MULTRET, 0)) { + error(lua_tostring(L, lua_gettop(L)) + std::string(" in ") + mapper); + return v; + } // Check if app messed up the stack. if(lua_gettop(L) != clean_top + 2) { - printf("LUA mapper messed up the stack (wrong number of return values)!\n"); + error("Wrong number of return values in " + mapper); lua_pop(L, lua_gettop(L) - clean_top); - Value v; - v.timestamp = 0; - v.value = ""; return v; } + // Check if the types are right + if(lua_isnumber(L, lua_gettop(L)) == false) { + error("Timestamp is not an integer in " + mapper); + lua_pop(L, 2); + return v; + } v.timestamp = lua_tointeger(L, lua_gettop(L)); lua_pop(L, 1); + + // Check if the types are right + if(lua_isstring(L, lua_gettop(L)) == false) { + error("Value is not a string in " + mapper); + lua_pop(L, 1); + return v; + } v.value = lua_tostring(L, lua_gettop(L)); lua_pop(L, 1); return v; } +void LUAQueryMapper::error(std::string message) +{ + throw Exception("ERROR in LUAQueryMapper: " + message); +} + #ifdef TEST_LUAQUERYMAPPER #include "queryhandler.h" diff --git a/server/src/luaquerymapper.h b/server/src/luaquerymapper.h index 83866a0..685abe7 100644 --- a/server/src/luaquerymapper.h +++ b/server/src/luaquerymapper.h @@ -50,6 +50,8 @@ public: */ Value map(const std::string &mapper); + void error(std::string message); + private: lua_State *L; int clean_top; diff --git a/server/src/server.cc b/server/src/server.cc index 9708f9f..2ea782d 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -115,6 +115,8 @@ static void connection(TCPSocket &socket) while(i != transaction.requests.end()) { Request &request = *i; + std::string answer; + MacroParser mp(request.macro); mp.parse(); Macro *m = mp.getMacro(); @@ -156,51 +158,47 @@ static void connection(TCPSocket &socket) // Map the results LUAQueryMapper lqm(qp.result); - socket.write(" <course name=\""); - socket.write(templ->course.attributes["name"]); - socket.write("\">\n"); + answer += " <course name=\""; + answer += templ->course.attributes["name"]; + answer += "\">\n"; // Generate the macro and return it to the client std::vector< Macro >::iterator mi2 = templ->course.macroes.begin(); while(mi2 != templ->course.macroes.end()) { Macro ¯o = (*mi2); - socket.write(" <macro name=\""); - socket.write(macro.attributes["name"]); - socket.write("\">\n"); + answer += " <macro name=\"" + macro.attributes["name"] + "\">\n"; if(macro.attributes["name"] == request.macro) { // Handle lua programs if(m->luaprograms.size()) { - socket.write(" <luaprograms>\n"); + answer += " <luaprograms>\n"; std::vector< LUAProgram >::iterator lpi = m->luaprograms.begin(); while(lpi != m->luaprograms.end()) { - socket.write(" <luaprogram name=\""); - socket.write(lpi->attributes["name"]); - socket.write("\">\n"); + answer += " <luaprogram name=\"" + lpi->attributes["name"] + "\">\n"; - socket.write(lpi->attributes["lua"]); + answer += lpi->attributes["lua"]; - socket.write("\n </luaprogram>\n"); + answer += "\n </luaprogram>\n"; lpi++; } - socket.write(" </luaprograms>\n"); + answer += " </luaprograms>\n"; } - widgetgenerator(socket, *m, lqm, db); + answer += widgetgenerator(*m, lqm, db); } - socket.write(" </macro>\n"); + answer += " </macro>\n"; mi2++; } - socket.write(" </course>\n"); - + answer += " </course>\n"; + socket.write(answer); i++; } } catch(std::exception &e) { diff --git a/server/src/widgetgenerator.cc b/server/src/widgetgenerator.cc index 6234513..43b202f 100644 --- a/server/src/widgetgenerator.cc +++ b/server/src/widgetgenerator.cc @@ -26,17 +26,18 @@ */ #include "widgetgenerator.h" -static void send_macro_widget(Macro ¯o, - Widget &widget, - TCPSocket &socket, - std::string tabs, - LUAQueryMapper &mapper, - Values &values) +static std::string send_macro_widget(Macro ¯o, + Widget &widget, + std::string tabs, + LUAQueryMapper &mapper, + Values &values) { + std::string result; + std::string prefilled; time_t timestamp = 0; - socket.write(tabs + "<" + widget.attributes["type"]); + result = tabs + "<" + widget.attributes["type"]; std::map< std::string, std::string >::iterator p = widget.attributes.begin(); // Check if the field has a map, and fill in the value if it has... @@ -72,26 +73,28 @@ static void send_macro_widget(Macro ¯o, while(p != widget.attributes.end()) { if(p->first != "type" && p->first != "map") { - socket.write(" " + p->first + "=\"" + p->second + "\""); + result += " " + p->first + "=\"" + p->second + "\""; } p++; } - if(prefilled != "") socket.write(" prefilled=\"" + prefilled + "\""); + if(prefilled != "") result += " prefilled=\"" + prefilled + "\""; if(widget.widgets.size() == 0) { // If node is empty, use short tag form - socket.write("/>\n"); - return; + result += "/>\n"; + return result; } - socket.write(">\n"); + result += ">\n"; std::vector< Widget >::iterator w = widget.widgets.begin(); while(w != widget.widgets.end()) { - send_macro_widget(macro, *w, socket, tabs + " ", mapper, values); + result += send_macro_widget(macro, *w, tabs + " ", mapper, values); w++; } - socket.write(tabs + "</" + widget.attributes["type"] + ">\n"); + result += tabs + "</" + widget.attributes["type"] + ">\n"; + + return result; } static void get_fields(Widget &widget, Fieldnames &fields) @@ -107,12 +110,12 @@ static void get_fields(Widget &widget, Fieldnames &fields) } } -void widgetgenerator(TCPSocket &socket, Macro ¯o, LUAQueryMapper &mapper, Database &db) +std::string widgetgenerator(Macro ¯o, LUAQueryMapper &mapper, Database &db) { Fieldnames fields; get_fields(macro.window, fields); Values values = db.getValues("2003791613", fields); - send_macro_widget(macro, macro.window, socket, " ", mapper, values); + return send_macro_widget(macro, macro.window, " ", mapper, values); } diff --git a/server/src/widgetgenerator.h b/server/src/widgetgenerator.h index 2ed77df..66d3690 100644 --- a/server/src/widgetgenerator.h +++ b/server/src/widgetgenerator.h @@ -34,9 +34,8 @@ #include "luaquerymapper.h" #include "database.h" -void widgetgenerator(TCPSocket &socket, - Macro ¯o, - LUAQueryMapper &mapper, - Database &db); +std::string widgetgenerator(Macro ¯o, + LUAQueryMapper &mapper, + Database &db); #endif/*__PRACRO_WIDGETGENERATOR_H__*/ diff --git a/server/xml/macros/example.xml b/server/xml/macros/example.xml index ce6e2c0..635dea2 100644 --- a/server/xml/macros/example.xml +++ b/server/xml/macros/example.xml @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='UTF-8'?> -<macro name="example" version="1.0" resume="${linse1}${linse2}"> +<macro name="example" version="1.0" resume="Axis: ${axis}\nCylinder: ${cyl}\nSphere: ${sphere}\n"> <queries> <query class="lensmeter" ttl="10000" automap="true"/> </queries> @@ -8,12 +8,6 @@ -- LUA program return math.pi, 1234567890 </map> - <map name="right.axis" uses="lensmeter, lensmeter.right.axis"> - -- LUA program - right_axis = 0 - if( lensmeter.right.axis ) right_axis = lensmeter.right.axis.value - return right_axis, lensmeter.right.sphere.timestamp - </map> <map name="cyl"> -- LUA program return lensmeter.right.cyl.value, lensmeter.right.cyl.timestamp @@ -21,10 +15,11 @@ </maps> <luaprograms> <luaprogram name="theanswer"> - fisk = getValue('sphere') - if( tonumber(fisk) == tonumber(value) ) + sphere = tonumber(getValue('sphere')) + axis = tonumber(getValue('axis')) + if( sphere == axis ) then - setValue('cyl', value) + setValue('cyl', name) return true else return false @@ -32,24 +27,38 @@ </luaprogram> </luaprograms> <window name="mainwindow" - caption="Fundus" - width="500" - height="560" + caption="Example Window" + width="300" + height="400" layout="vbox"> <frame name="linse_frame" caption="Linser:" layout="vbox"> <frame name="linse_framea" layout="hbox"> - <label name="a" width="300" caption="Akse rotation:"/> + <label name="a" width="100" caption="Akse rotation:"/> <lineedit name="axis" regexp="[24]*" map="axis" lua="theanswer" value="244"/> </frame> <frame name="linse_frameb" layout="hbox"> - <label name="b" width="300" caption="Sphere:"/> - <lineedit name="sphere" regexp="[24]*" map="sphere" value="42"/> + <label name="b" width="100" caption="Sphere:"/> + <lineedit name="sphere" regexp="[24]*" lua="theanswer" value="42"/> </frame> <frame name="linse_framec" layout="hbox"> - <label name="c" width="300" caption="Cyl:"/> + <label name="c" width="100" caption="Cyl:"/> <lineedit name="cyl" regexp="[24]*" map="cyl" value=""/> </frame> </frame> + <frame name="linse_frame" caption="FlereLinser:" layout="vbox"> + <frame name="linse_framea" layout="hbox"> + <label name="a" width="100" caption="Akse rotation2:"/> + <lineedit name="axis2" regexp="[24]*" map="axis" lua="theanswer" value="244"/> + </frame> + <frame name="linse_frameb" layout="hbox"> + <label name="b" width="100" caption="Sphere2:"/> + <lineedit name="sphere2" regexp="[24]*" lua="theanswer" value="42"/> + </frame> + <frame name="linse_framec" layout="hbox"> + <label name="c" width="100" caption="Cyl2:"/> + <lineedit name="cyl2" regexp="[24]*" map="cyl" value=""/> + </frame> + </frame> <frame name="buttons" layout="hbox"> <button name="cancel" caption="Annuller" action="cancel"/> <button name="commit" caption="Godkend" action="commit"/> |