Mercurial > hg > orthanc
comparison Core/Lua/LuaContext.cpp @ 1051:92f4bf2c5d73
HTTP GET in Lua
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Jul 2014 12:59:28 +0200 |
parents | b067017a8a5b |
children | cc4ff680e2a0 |
comparison
equal
deleted
inserted
replaced
1050:64f1842aae2e | 1051:92f4bf2c5d73 |
---|---|
42 #include <lauxlib.h> | 42 #include <lauxlib.h> |
43 } | 43 } |
44 | 44 |
45 namespace Orthanc | 45 namespace Orthanc |
46 { | 46 { |
47 int LuaContext::PrintToLog(lua_State *state) | 47 LuaContext& LuaContext::GetLuaContext(lua_State *state) |
48 { | 48 { |
49 // Get the pointer to the "LuaContext" underlying object | 49 // Get the pointer to the "LuaContext" underlying object |
50 lua_getglobal(state, "_LuaContext"); | 50 lua_getglobal(state, "_LuaContext"); |
51 assert(lua_type(state, -1) == LUA_TLIGHTUSERDATA); | 51 assert(lua_type(state, -1) == LUA_TLIGHTUSERDATA); |
52 LuaContext* that = const_cast<LuaContext*>(reinterpret_cast<const LuaContext*>(lua_topointer(state, -1))); | 52 LuaContext* that = const_cast<LuaContext*>(reinterpret_cast<const LuaContext*>(lua_topointer(state, -1))); |
53 assert(that != NULL); | 53 assert(that != NULL); |
54 lua_pop(state, 1); | 54 lua_pop(state, 1); |
55 | 55 |
56 return *that; | |
57 } | |
58 | |
59 int LuaContext::PrintToLog(lua_State *state) | |
60 { | |
61 LuaContext& that = GetLuaContext(state); | |
62 | |
56 // http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/ | 63 // http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/ |
57 int nArgs = lua_gettop(state); | 64 int nArgs = lua_gettop(state); |
58 lua_getglobal(state, "tostring"); | 65 lua_getglobal(state, "tostring"); |
59 | 66 |
60 // Make sure you start at 1 *NOT* 0 for arrays in Lua. | 67 // Make sure you start at 1 *NOT* 0 for arrays in Lua. |
78 | 85 |
79 lua_pop(state, 1); | 86 lua_pop(state, 1); |
80 } | 87 } |
81 | 88 |
82 LOG(WARNING) << "Lua says: " << result; | 89 LOG(WARNING) << "Lua says: " << result; |
83 that->log_.append(result); | 90 that.log_.append(result); |
84 that->log_.append("\n"); | 91 that.log_.append("\n"); |
85 | 92 |
86 return 0; | 93 return 0; |
94 } | |
95 | |
96 | |
97 int LuaContext::CallHttpGet(lua_State *state) | |
98 { | |
99 LuaContext& that = GetLuaContext(state); | |
100 | |
101 // Check that there is 1 string argument | |
102 int nArgs = lua_gettop(state); | |
103 if ((nArgs != 1 && nArgs != 2) || | |
104 !lua_isstring(state, 1) || | |
105 (nArgs == 2 && !lua_isboolean(state, 2))) | |
106 { | |
107 LOG(ERROR) << "Lua: Bad URL in HttpGet"; | |
108 | |
109 lua_pushstring(state, "ERROR"); | |
110 return 1; | |
111 } | |
112 | |
113 // Configure the HTTP client class | |
114 const char* url = lua_tostring(state, 1); | |
115 bool isJson = (nArgs == 2 && lua_toboolean(state, 2)); | |
116 that.httpClient_.SetMethod(HttpMethod_Get); | |
117 that.httpClient_.SetUrl(url); | |
118 | |
119 // Do the HTTP GET request | |
120 std::string str; | |
121 Json::Value json; | |
122 | |
123 try | |
124 { | |
125 if (isJson) | |
126 { | |
127 that.httpClient_.Apply(json); | |
128 } | |
129 else | |
130 { | |
131 that.httpClient_.Apply(str); | |
132 } | |
133 } | |
134 catch (OrthancException& e) | |
135 { | |
136 LOG(ERROR) << "Lua: Error in HttpGet for URL " << url << ": " << e.What(); | |
137 | |
138 lua_pushstring(state, "ERROR"); | |
139 return 1; | |
140 } | |
141 | |
142 // Return the result of the HTTP GET | |
143 if (isJson) | |
144 { | |
145 that.PushJson(json); | |
146 } | |
147 else | |
148 { | |
149 lua_pushstring(state, str.c_str()); | |
150 } | |
151 | |
152 return 1; | |
153 } | |
154 | |
155 | |
156 void LuaContext::PushJson(const Json::Value& value) | |
157 { | |
158 if (value.isString()) | |
159 { | |
160 lua_pushstring(lua_, value.asCString()); | |
161 } | |
162 else if (value.isDouble()) | |
163 { | |
164 lua_pushnumber(lua_, value.asDouble()); | |
165 } | |
166 else if (value.isInt()) | |
167 { | |
168 lua_pushinteger(lua_, value.asInt()); | |
169 } | |
170 else if (value.isUInt()) | |
171 { | |
172 lua_pushinteger(lua_, value.asUInt()); | |
173 } | |
174 else if (value.isBool()) | |
175 { | |
176 lua_pushboolean(lua_, value.asBool()); | |
177 } | |
178 else if (value.isNull()) | |
179 { | |
180 lua_pushnil(lua_); | |
181 } | |
182 else if (value.isArray()) | |
183 { | |
184 lua_newtable(lua_); | |
185 | |
186 // http://lua-users.org/wiki/SimpleLuaApiExample | |
187 for (Json::Value::ArrayIndex i = 0; i < value.size(); i++) | |
188 { | |
189 // Push the table index (note the "+1" because of Lua conventions) | |
190 lua_pushnumber(lua_, i + 1); | |
191 | |
192 // Push the value of the cell | |
193 PushJson(value[i]); | |
194 | |
195 // Stores the pair in the table | |
196 lua_rawset(lua_, -3); | |
197 } | |
198 } | |
199 else if (value.isObject()) | |
200 { | |
201 lua_newtable(lua_); | |
202 | |
203 Json::Value::Members members = value.getMemberNames(); | |
204 | |
205 for (Json::Value::Members::const_iterator | |
206 it = members.begin(); it != members.end(); ++it) | |
207 { | |
208 // Push the index of the cell | |
209 lua_pushstring(lua_, it->c_str()); | |
210 | |
211 // Push the value of the cell | |
212 PushJson(value[*it]); | |
213 | |
214 // Stores the pair in the table | |
215 lua_rawset(lua_, -3); | |
216 } | |
217 } | |
218 else | |
219 { | |
220 throw LuaException("Unsupported JSON conversion"); | |
221 } | |
87 } | 222 } |
88 | 223 |
89 | 224 |
90 LuaContext::LuaContext() | 225 LuaContext::LuaContext() |
91 { | 226 { |
95 throw LuaException("Unable to create the Lua context"); | 230 throw LuaException("Unable to create the Lua context"); |
96 } | 231 } |
97 | 232 |
98 luaL_openlibs(lua_); | 233 luaL_openlibs(lua_); |
99 lua_register(lua_, "print", PrintToLog); | 234 lua_register(lua_, "print", PrintToLog); |
235 lua_register(lua_, "HttpGet", CallHttpGet); | |
100 | 236 |
101 lua_pushlightuserdata(lua_, this); | 237 lua_pushlightuserdata(lua_, this); |
102 lua_setglobal(lua_, "_LuaContext"); | 238 lua_setglobal(lua_, "_LuaContext"); |
103 } | 239 } |
104 | 240 |