summaryrefslogtreecommitdiff
path: root/plugins/MirLua/src/Modules
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2018-06-06 00:34:46 +0300
committeraunsane <aunsane@gmail.com>2018-06-06 00:35:01 +0300
commita7034dc19a8849bf82d2eb420b150ac54dc079d8 (patch)
tree75eb7818df9cc9d707bf2c5a010b31ae2340f971 /plugins/MirLua/src/Modules
parent3c13c94d636ce2c38ca64bbe3febbad68296c661 (diff)
MirLua:
- add new helper function luaM_isarray - fix print of decimal point m_json module - add __pairs metamethod support - simplify code m_http module - send function should create copy of request object to prevent side effects in async calls - fix lua functions call - fix memory leaks
Diffstat (limited to 'plugins/MirLua/src/Modules')
-rw-r--r--plugins/MirLua/src/Modules/m_http.cpp74
-rw-r--r--plugins/MirLua/src/Modules/m_json.cpp218
2 files changed, 152 insertions, 140 deletions
diff --git a/plugins/MirLua/src/Modules/m_http.cpp b/plugins/MirLua/src/Modules/m_http.cpp
index f15ebd7fd7..006c7e9876 100644
--- a/plugins/MirLua/src/Modules/m_http.cpp
+++ b/plugins/MirLua/src/Modules/m_http.cpp
@@ -277,10 +277,11 @@ static void __cdecl SendHttpRequestThread(HttpRequestParam *param)
lua_rawgeti(param->L, LUA_REGISTRYINDEX, param->callbackRef);
response_Create(param->L, param->request);
- luaM_pcall(param->L, 0, 1);
+ luaM_pcall(param->L, 1, 0);
luaL_unref(param->L, LUA_REGISTRYINDEX, param->callbackRef);
luaL_unref(param->L, LUA_REGISTRYINDEX, param->threadRef);
+ Netlib_FreeHttpRequest(param->request);
delete param;
}
@@ -401,12 +402,30 @@ static int request_Send(lua_State *L)
{
NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ NETLIBHTTPREQUEST *newRequest = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST));
+ newRequest->cbSize = sizeof(NETLIBHTTPREQUEST);
+ newRequest->flags = request->flags;
+ newRequest->requestType = request->requestType;
+ newRequest->szUrl = mir_strdup(request->szUrl);
+ newRequest->headersCount = request->headersCount;
+ newRequest->headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
+ for (int i = 0; i < request->headersCount; i++) {
+ newRequest->headers[i].szName = mir_strdup(request->headers[i].szName);
+ newRequest->headers[i].szValue = mir_strdup(request->headers[i].szValue);
+ }
+ newRequest->dataLength = request->dataLength;
+ newRequest->pData = (char*)mir_calloc(request->dataLength + 1);
+ memcpy(newRequest->pData, request->pData, request->dataLength);
+ newRequest->timeout = request->timeout;
+
if (lua_isfunction(L, 2)) {
- SendRequestAsync(L, 2, request);
+ SendRequestAsync(L, 2, newRequest);
return 0;
}
- response_Create(L, request);
+ response_Create(L, newRequest);
+ Netlib_FreeHttpRequest(newRequest);
+
return 1;
}
@@ -437,16 +456,8 @@ static int request__index(lua_State *L)
static int request__gc(lua_State *L)
{
- NETLIBHTTPREQUEST **request = (NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
-
- mir_free((*request)->szUrl);
- for (int i = 0; i < (*request)->headersCount; i++) {
- mir_free((*request)->headers[i].szName);
- mir_free((*request)->headers[i].szValue);
- }
- mir_free((*request)->headers);
- mir_free((*request)->pData);
-
+ NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ Netlib_FreeHttpRequest(request);
return 0;
}
@@ -486,6 +497,8 @@ static int http_Get(lua_State *L)
}
response_Create(L, request);
+ Netlib_FreeHttpRequest(request);
+
return 1;
}
@@ -497,20 +510,24 @@ static int http_Post(lua_State *L)
const char *url = luaL_checkstring(L, 1);
SetUrl(request, url);
- lua_pushvalue(L, 2);
lua_pushcfunction(L, request_SetContent);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 2);
luaM_pcall(L, 2, 1);
- lua_pushvalue(L, 3);
lua_pushcfunction(L, request_SetContentType);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 3);
luaM_pcall(L, 2, 1);
- if (lua_isfunction(L, 2)) {
- SendRequestAsync(L, 2, request);
+ if (lua_isfunction(L, 4)) {
+ SendRequestAsync(L, 4, request);
return 0;
}
response_Create(L, request);
+ Netlib_FreeHttpRequest(request);
+
return 1;
}
@@ -522,20 +539,24 @@ static int http_Put(lua_State *L)
const char *url = luaL_checkstring(L, 1);
SetUrl(request, url);
- lua_pushvalue(L, 2);
lua_pushcfunction(L, request_SetContent);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 2);
luaM_pcall(L, 2, 1);
- lua_pushvalue(L, 3);
lua_pushcfunction(L, request_SetContentType);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 3);
luaM_pcall(L, 2, 1);
- if (lua_isfunction(L, 2)) {
- SendRequestAsync(L, 2, request);
+ if (lua_isfunction(L, 4)) {
+ SendRequestAsync(L, 4, request);
return 0;
}
response_Create(L, request);
+ Netlib_FreeHttpRequest(request);
+
return 1;
}
@@ -547,20 +568,23 @@ static int http_Delete(lua_State *L)
const char *url = luaL_checkstring(L, 1);
SetUrl(request, url);
- lua_pushvalue(L, 2);
lua_pushcfunction(L, request_SetContent);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 2);
luaM_pcall(L, 2, 1);
- lua_pushvalue(L, 3);
lua_pushcfunction(L, request_SetContentType);
+ lua_pushvalue(L, -1);
+ lua_pushvalue(L, 3);
luaM_pcall(L, 2, 1);
- if (lua_isfunction(L, 2)) {
- SendRequestAsync(L, 2, request);
+ if (lua_isfunction(L, 4)) {
+ SendRequestAsync(L, 4, request);
return 0;
}
response_Create(L, request);
+
return 1;
}
diff --git a/plugins/MirLua/src/Modules/m_json.cpp b/plugins/MirLua/src/Modules/m_json.cpp
index 907e0f582b..db45f77065 100644
--- a/plugins/MirLua/src/Modules/m_json.cpp
+++ b/plugins/MirLua/src/Modules/m_json.cpp
@@ -2,67 +2,92 @@
#define MT_JSON "JSON"
-static void lua2json(lua_State *L, JSONNode &node)
+static void json2lua(lua_State *L, const JSONNode &node)
{
- switch (lua_type(L, -1)) {
+ switch (node.type()) {
+ case JSON_NULL:
+ lua_pushnil(L);
+ break;
+ case JSON_STRING:
+ lua_pushstring(L, node.as_string().c_str());
+ break;
+ case JSON_NUMBER:
+ {
+ lua_getglobal(L, "tonumber");
+ lua_pushstring(L, node.as_string().c_str());
+ luaM_pcall(L, 1, 1);
+ break;
+ }
+ case JSON_BOOL:
+ lua_pushboolean(L, node.as_bool());
+ break;
+ case JSON_ARRAY:
+ case JSON_NODE:
+ JSONNode * *udata = (JSONNode**)lua_newuserdata(L, sizeof(JSONNode*));
+ *udata = json_copy(&node);
+ luaL_setmetatable(L, MT_JSON);
+ }
+}
+
+static void lua2json(lua_State *L, int idx, JSONNode &node)
+{
+ switch (lua_type(L, idx)) {
case LUA_TNIL:
node.nullify();
break;
case LUA_TSTRING:
- node = lua_tostring(L, -1);
+ node = lua_tostring(L, idx);
break;
case LUA_TBOOLEAN:
- node = lua_toboolean(L, -1) != 0;
+ node = lua_toboolean(L, idx) != 0;
break;
case LUA_TNUMBER:
{
- lua_Integer val = lua_tointeger(L, -1);
- if (lua_isinteger(L, -1) && val >= LONG_MIN && val <= LONG_MAX)
- node = (long)val;
- else
- node = lua_tonumber(L, -1);
+ if (!lua_isinteger(L, idx)) {
+ node = lua_tonumber(L, idx);
+ break;
+ }
+ lua_Integer val = lua_tointeger(L, idx);
+ node = val >= LONG_MIN && val <= LONG_MAX
+ ? (long)val
+ : lua_tonumber(L, idx);
break;
}
case LUA_TTABLE:
{
ptrA name(mir_strdup(node.name()));
- node.cast(JSON_ARRAY);
- node.set_name((char*)name);
+ if (luaM_isarray(L, idx)) {
+ node.cast(JSON_ARRAY);
+ node.set_name((char*)name);
+ }
- lua_pushnil(L);
- while (lua_next(L, -2) != 0) {
+ for (lua_pushnil(L); lua_next(L, idx); lua_pop(L, 1)) {
JSONNode child;
- if (!lua_isnumber(L, -2)) {
- if (node.type() == JSON_ARRAY) {
- node.cast(JSON_NODE);
- node.set_name((char*)name);
- }
+ if (node.type() != JSON_ARRAY) {
const char *key = lua_tostring(L, -2);
child.set_name(key);
}
- lua2json(L, child);
+ lua2json(L, lua_absindex(L, -1), child);
node << child;
-
- lua_pop(L, 1);
}
break;
}
case LUA_TLIGHTUSERDATA:
- if (lua_touserdata(L, -1))
- luaL_argerror(L, -1, luaL_typename(L, -1));
+ if (lua_touserdata(L, idx))
+ luaL_argerror(L, idx, luaL_typename(L, idx));
node.nullify();
break;
case LUA_TUSERDATA:
{
ptrA name(mir_strdup(node.name()));
- JSONNode *other = *(JSONNode**)luaL_checkudata(L, -1, MT_JSON);
+ JSONNode *other = *(JSONNode**)luaL_checkudata(L, idx, MT_JSON);
node = other->duplicate();
node.set_name((char*)name);
break;
}
default:
- luaL_argerror(L, -1, luaL_typename(L, -1));
+ luaL_argerror(L, idx, luaL_typename(L, idx));
}
}
@@ -73,7 +98,7 @@ static int json__index(lua_State *L)
JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
JSONNode *child;
- if (node->type() == JSON_ARRAY) {
+ if (node->type() == JSON_ARRAY || lua_isinteger(L, 2)) {
int idx = lua_tointeger(L, 2);
child = &node->at(idx - 1);
}
@@ -82,26 +107,7 @@ static int json__index(lua_State *L)
child = &node->at(key);
}
- switch (child->type())
- {
- case JSON_NULL:
- lua_pushnil(L);
- break;
- case JSON_STRING:
- lua_pushstring(L, child->as_string().c_str());
- break;
- case JSON_NUMBER:
- lua_pushnumber(L, child->as_int());
- break;
- case JSON_BOOL:
- lua_pushboolean(L, child->as_bool());
- break;
- case JSON_ARRAY:
- case JSON_NODE:
- JSONNode **udata = (JSONNode**)lua_newuserdata(L, sizeof(JSONNode*));
- *udata = child;
- luaL_setmetatable(L, MT_JSON);
- }
+ json2lua(L, *child);
return 1;
}
@@ -109,28 +115,68 @@ static int json__index(lua_State *L)
static int json__newindex(lua_State *L)
{
JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
- const char *key = lua_tostring(L, 2);
- if (json_type(node) == JSON_ARRAY) {
+ if (json_type(node) == JSON_ARRAY || lua_isinteger(L, 2)) {
int idx = lua_tointeger(L, 2);
JSONNode *child = json_at(node, idx - 1);
- lua2json(L, *child);
+ lua2json(L, 3, *child);
return 0;
}
+ const char *key = lua_tostring(L, 2);
JSONNode *child = json_get(node, key);
if (json_type(child) == JSON_NULL) {
json_set_name(child, key);
- lua2json(L, *child);
+ lua2json(L, 3, *child);
json_push_back(node, child);
return 0;
}
- lua2json(L, *child);
+ lua2json(L, 3, *child);
return 0;
}
+static int json__pairsIterator(lua_State *L)
+{
+ JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
+ int i = lua_tointeger(L, lua_upvalueindex(1));
+
+ setlocale(LC_NUMERIC, "C");
+
+ if (i < node->size()) {
+ JSONNode *child = json_at(node, i);
+ if (json_type(node) == JSON_ARRAY)
+ lua_pushinteger(L, i + 1);
+ else
+ lua_pushstring(L, child->name());
+
+ json2lua(L, *child);
+ setlocale(LC_NUMERIC, "");
+
+ lua_pushinteger(L, (i + 1));
+ lua_replace(L, lua_upvalueindex(1));
+
+ return 2;
+ }
+
+ setlocale(LC_NUMERIC, "");
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int json__pairs(lua_State *L)
+{
+ JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
+
+ lua_pushinteger(L, 0);
+ lua_pushcclosure(L, json__pairsIterator, 1);
+ lua_pushvalue(L, 1);
+
+ return 2;
+}
+
static int json__len(lua_State *L)
{
JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
@@ -142,9 +188,7 @@ static int json__len(lua_State *L)
static int json__tostring(lua_State *L)
{
JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
-
lua_pushstring(L, node->write().c_str());
-
return 1;
}
@@ -161,6 +205,7 @@ const struct luaL_Reg jsonApi[] =
{
{ "__index", json__index },
{ "__newindex", json__newindex },
+ { "__pairs", json__pairs },
{ "__len", json__len },
{ "__tostring", json__tostring },
{ "__gc", json__gc },
@@ -182,70 +227,13 @@ static int lua_Decode(lua_State *L)
return 1;
}
-/***********************************************/
-
static int lua_Encode(lua_State *L)
{
- //JSONNode node;
- //lua_pushnil(L);
- //lua_pushvalue(L, 1);
- //lua2json(L, node);
- //lua_pop(L, 2);
- //lua_pushstring(L, node.write().c_str());
-
- switch (lua_type(L, 1)) {
- case LUA_TNIL:
- lua_pushliteral(L, "null");
- break;
- case LUA_TBOOLEAN:
- lua_pushstring(L, lua_toboolean(L, 1) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- {
- if (lua_isinteger(L, 1)) {
- lua_pushfstring(L, "%I", lua_tointeger(L, 1));
- break;
- }
- char decpoint = lua_getlocaledecpoint();
- if (decpoint != '.') {
- char p[2] = { decpoint };
- luaL_gsub(L, lua_tostring(L, 1), p, ".");
- }
- else
- lua_pushfstring(L, "%f", lua_tonumber(L, 1));
- break;
- }
- case LUA_TSTRING:
- lua_pushfstring(L, "\"%s\"", lua_tostring(L, 1));
- break;
- case LUA_TTABLE:
- {
- JSONNode node;
- lua_pushnil(L);
- lua_pushvalue(L, 1);
- lua2json(L, node);
- lua_pop(L, 2);
- lua_pushstring(L, node.write().c_str());
- break;
- }
- case LUA_TUSERDATA:
- {
- JSONNode *node = *(JSONNode**)luaL_checkudata(L, 1, MT_JSON);
- lua_pushstring(L, node->write().c_str());
- break;
- }
- case LUA_TLIGHTUSERDATA:
- if (lua_touserdata(L, 1) == nullptr)
- {
- lua_pushliteral(L, "null");
- break;
- }
- default:
- luaL_argerror(L, 1, luaL_typename(L, 1));
- }
-
- return 1;
- }
+ JSONNode node;
+ lua2json(L, 1, node);
+ lua_pushstring(L, node.write().c_str());
+ return 1;
+}
static const luaL_Reg methods[] =
{