diff options
Diffstat (limited to 'server')
| -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"/>  | 
