projects/aports·blob master · refs

358 lines · 10.9 KiB

1From 42064f63d05edf0769814734ada8ab1ce3435931 Mon Sep 17 00:00:00 2001
2From: Brian Maher <[email protected]>
3Date: Mon, 1 Jun 2015 12:37:01 -0700
4Subject: [PATCH 1/3] Allow empty array to be encoded with a metatable
5 containing __is_cjson_array=true.
6
7---
8 lua_cjson.c | 30 ++++++++++++++++++++++++++++--
9 1 file changed, 28 insertions(+), 2 deletions(-)
10
11diff --git a/lua_cjson.c b/lua_cjson.c
12index c14a1c5..283e3af 100644
13--- a/lua_cjson.c
14+++ b/lua_cjson.c
15@@ -494,9 +494,25 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
16 int max;
17 int items;
18
19- max = 0;
20+ max = -1;
21 items = 0;
22
23+ if ( lua_getmetatable(l, -1) ) {
24+ int is_array, has_is_array;
25+
26+ lua_pushliteral(l, "__is_cjson_array");
27+ lua_rawget(l, -2);
28+ has_is_array = lua_isboolean(l, -1);
29+ is_array = has_is_array && lua_toboolean(l, -1);
30+ lua_pop(l, 2);
31+
32+ if ( has_is_array && ! is_array ) {
33+ return -1;
34+ } else {
35+ max = 0;
36+ }
37+ }
38+
39 lua_pushnil(l);
40 /* table, startkey */
41 while (lua_next(l, -2) != 0) {
42@@ -685,7 +701,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
43 current_depth++;
44 json_check_encode_depth(l, cfg, current_depth, json);
45 len = lua_array_length(l, cfg, json);
46- if (len > 0)
47+ if (len >= 0)
48 json_append_array(l, cfg, current_depth, json, len);
49 else
50 json_append_object(l, cfg, current_depth, json);
51@@ -1204,6 +1220,16 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json)
52
53 /* Handle empty arrays */
54 if (token.type == T_ARR_END) {
55+ // Mark as array:
56+ luaL_getmetatable(l, "cjson.array");
57+ if ( lua_isnil(l, -1) ) {
58+ lua_pop(l, 1);
59+ luaL_newmetatable(l, "cjson.array");
60+ lua_pushboolean(l, 1);
61+ lua_setfield(l, -2, "__is_cjson_array");
62+ }
63+ lua_setmetatable(l, -2);
64+
65 json_decode_ascend(json);
66 return;
67 }
68--
692.6.3
70
71
72From 514c4b4761ac0552182acbf25039930ddca70070 Mon Sep 17 00:00:00 2001
73From: Brian Maher <[email protected]>
74Date: Thu, 3 Sep 2015 12:33:33 -0700
75Subject: [PATCH 2/3] Replace __is_cjson_array with check for __name="array"
76 and replace lightuserdata NULL with __name="null" meatable. This will allow
77 better interchange with other modules that need to define "array" and "null"
78 types. Note that you can also define custom implementations of "array" and
79 "null" if you have access to the registry.
80
81---
82 lua_cjson.c | 65 ++++++++++++++++++++++++++++++++++++++++---------------------
83 1 file changed, 43 insertions(+), 22 deletions(-)
84
85diff --git a/lua_cjson.c b/lua_cjson.c
86index 283e3af..2140743 100644
87--- a/lua_cjson.c
88+++ b/lua_cjson.c
89@@ -497,20 +497,13 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
90 max = -1;
91 items = 0;
92
93- if ( lua_getmetatable(l, -1) ) {
94- int is_array, has_is_array;
95-
96- lua_pushliteral(l, "__is_cjson_array");
97+ if (lua_getmetatable(l, -1)) {
98+ lua_pushliteral(l, "__name");
99 lua_rawget(l, -2);
100- has_is_array = lua_isboolean(l, -1);
101- is_array = has_is_array && lua_toboolean(l, -1);
102- lua_pop(l, 2);
103-
104- if ( has_is_array && ! is_array ) {
105- return -1;
106- } else {
107+ if (lua_isstring(l, -1) && strcmp("array", lua_tostring(l, -1)) == 0) {
108 max = 0;
109 }
110+ lua_pop(l, 2);
111 }
112
113 lua_pushnil(l);
114@@ -698,6 +691,16 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
115 strbuf_append_mem(json, "false", 5);
116 break;
117 case LUA_TTABLE:
118+ if (lua_getmetatable(l, -1)) {
119+ lua_pushliteral(l, "__name");
120+ lua_rawget(l, -2);
121+ if (lua_isstring(l, -1) && strcmp("null", lua_tostring(l, -1)) == 0) {
122+ strbuf_append_mem(json, "null", 4);
123+ lua_pop(l, 2);
124+ break;
125+ }
126+ lua_pop(l, 2);
127+ }
128 current_depth++;
129 json_check_encode_depth(l, cfg, current_depth, json);
130 len = lua_array_length(l, cfg, json);
131@@ -1221,13 +1224,7 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json)
132 /* Handle empty arrays */
133 if (token.type == T_ARR_END) {
134 // Mark as array:
135- luaL_getmetatable(l, "cjson.array");
136- if ( lua_isnil(l, -1) ) {
137- lua_pop(l, 1);
138- luaL_newmetatable(l, "cjson.array");
139- lua_pushboolean(l, 1);
140- lua_setfield(l, -2, "__is_cjson_array");
141- }
142+ luaL_getmetatable(l, "array");
143 lua_setmetatable(l, -2);
144
145 json_decode_ascend(json);
146@@ -1274,9 +1271,9 @@ static void json_process_value(lua_State *l, json_parse_t *json,
147 break;;
148 case T_NULL:
149 /* In Lua, setting "t[k] = nil" will delete k from the table.
150- * Hence a NULL pointer lightuserdata object is used instead */
151- lua_pushlightuserdata(l, NULL);
152- break;;
153+ * Hence a NULL userdata object is used instead */
154+ luaL_getmetatable(l, "null");
155+ break;
156 default:
157 json_throw_parse_error(l, json, "value", token);
158 }
159@@ -1372,6 +1369,12 @@ static int json_protect_conversion(lua_State *l)
160 return luaL_error(l, "Memory allocation error in CJSON protected call");
161 }
162
163+static int json_null_tostring(lua_State *l)
164+{
165+ lua_pushliteral(l, "null");
166+ return 1;
167+}
168+
169 /* Return cjson module table */
170 static int lua_cjson_new(lua_State *l)
171 {
172@@ -1392,6 +1395,24 @@ static int lua_cjson_new(lua_State *l)
173 /* Initialise number conversions */
174 fpconv_init();
175
176+ /* Initialize "null" */
177+ if ( luaL_newmetatable(l, "null") ) {
178+ lua_createtable(l, 0, 2);
179+ lua_pushliteral(l, "null");
180+ lua_setfield(l, -2, "__name");
181+ lua_pushcfunction(l, json_null_tostring);
182+ lua_setfield(l, -2, "__tostring");
183+ lua_setmetatable(l, -2);
184+ }
185+ lua_pop(l, 1);
186+
187+ /* Initialize "array" metatable */
188+ if ( luaL_newmetatable(l, "array") ) {
189+ lua_pushliteral(l, "array");
190+ lua_setfield(l, -2, "__name");
191+ }
192+ lua_pop(l, 1);
193+
194 /* cjson module table */
195 lua_newtable(l);
196
197@@ -1400,7 +1421,7 @@ static int lua_cjson_new(lua_State *l)
198 luaL_setfuncs(l, reg, 1);
199
200 /* Set cjson.null */
201- lua_pushlightuserdata(l, NULL);
202+ luaL_getmetatable(l, "null");
203 lua_setfield(l, -2, "null");
204
205 /* Set module name / version fields */
206--
2072.6.3
208
209
210From 438a71d35417453e2207f64f706d02f199525c7d Mon Sep 17 00:00:00 2001
211From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
212Date: Tue, 8 Dec 2015 09:16:18 +0200
213Subject: [PATCH 3/3] fix empty array default encoding, and add meta __name for
214 objects
215
216---
217 lua_cjson.c | 52 +++++++++++++++++++++++++++++++++-------------------
218 1 file changed, 33 insertions(+), 19 deletions(-)
219
220diff --git a/lua_cjson.c b/lua_cjson.c
221index 2140743..25952ec 100644
222--- a/lua_cjson.c
223+++ b/lua_cjson.c
224@@ -493,17 +493,20 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
225 double k;
226 int max;
227 int items;
228+ int is_array = 0;
229+ const char *mt_name;
230
231- max = -1;
232+ max = 0;
233 items = 0;
234
235 if (lua_getmetatable(l, -1)) {
236 lua_pushliteral(l, "__name");
237 lua_rawget(l, -2);
238- if (lua_isstring(l, -1) && strcmp("array", lua_tostring(l, -1)) == 0) {
239- max = 0;
240- }
241+ mt_name = lua_isstring(l, -1) ? lua_tostring(l, -1) : "";
242 lua_pop(l, 2);
243+ if (strcmp("object", mt_name) == 0)
244+ return -1;
245+ is_array = strcmp("array", mt_name) == 0;
246 }
247
248 lua_pushnil(l);
249@@ -521,6 +524,10 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
250 continue;
251 }
252 }
253+ if (is_array) {
254+ lua_pop(l, 1);
255+ continue;
256+ }
257
258 /* Must not be an array (non integer key) */
259 lua_pop(l, 2);
260@@ -537,6 +544,10 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
261 return -1;
262 }
263
264+ /* Backwards compatibility - encode untyped zero length table as object */
265+ if (!is_array && max == 0)
266+ return -1;
267+
268 return max;
269 }
270
271@@ -1166,6 +1177,8 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json)
272 json_decode_descend(l, json, 3);
273
274 lua_newtable(l);
275+ luaL_getmetatable(l, "cjson.object");
276+ lua_setmetatable(l, -2);
277
278 json_next_token(json, &token);
279
280@@ -1218,15 +1231,13 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json)
281 json_decode_descend(l, json, 2);
282
283 lua_newtable(l);
284+ luaL_getmetatable(l, "cjson.array");
285+ lua_setmetatable(l, -2);
286
287 json_next_token(json, &token);
288
289 /* Handle empty arrays */
290 if (token.type == T_ARR_END) {
291- // Mark as array:
292- luaL_getmetatable(l, "array");
293- lua_setmetatable(l, -2);
294-
295 json_decode_ascend(json);
296 return;
297 }
298@@ -1272,7 +1283,7 @@ static void json_process_value(lua_State *l, json_parse_t *json,
299 case T_NULL:
300 /* In Lua, setting "t[k] = nil" will delete k from the table.
301 * Hence a NULL userdata object is used instead */
302- luaL_getmetatable(l, "null");
303+ luaL_getmetatable(l, "cjson.null");
304 break;
305 default:
306 json_throw_parse_error(l, json, "value", token);
307@@ -1395,8 +1406,11 @@ static int lua_cjson_new(lua_State *l)
308 /* Initialise number conversions */
309 fpconv_init();
310
311+ /* cjson module table */
312+ lua_newtable(l);
313+
314 /* Initialize "null" */
315- if ( luaL_newmetatable(l, "null") ) {
316+ if ( luaL_newmetatable(l, "cjson.null") ) {
317 lua_createtable(l, 0, 2);
318 lua_pushliteral(l, "null");
319 lua_setfield(l, -2, "__name");
320@@ -1404,26 +1418,26 @@ static int lua_cjson_new(lua_State *l)
321 lua_setfield(l, -2, "__tostring");
322 lua_setmetatable(l, -2);
323 }
324- lua_pop(l, 1);
325+ lua_setfield(l, -2, "null");
326
327 /* Initialize "array" metatable */
328- if ( luaL_newmetatable(l, "array") ) {
329+ if ( luaL_newmetatable(l, "cjson.array") ) {
330 lua_pushliteral(l, "array");
331 lua_setfield(l, -2, "__name");
332 }
333- lua_pop(l, 1);
334+ lua_setfield(l, -2, "array");
335
336- /* cjson module table */
337- lua_newtable(l);
338+ /* Initialize "object" metatable */
339+ if ( luaL_newmetatable(l, "cjson.object") ) {
340+ lua_pushliteral(l, "object");
341+ lua_setfield(l, -2, "__name");
342+ }
343+ lua_setfield(l, -2, "object");
344
345 /* Register functions with config data as upvalue */
346 json_create_config(l);
347 luaL_setfuncs(l, reg, 1);
348
349- /* Set cjson.null */
350- luaL_getmetatable(l, "null");
351- lua_setfield(l, -2, "null");
352-
353 /* Set module name / version fields */
354 lua_pushliteral(l, CJSON_MODNAME);
355 lua_setfield(l, -2, "_NAME");
356--
3572.6.3
358