annotate mod_couchdb/couchdb/json.lib.lua @ 5448:9d542e86e19a

mod_http_oauth2: Allow requesting a subset of scopes on token refresh This enables clients to request access tokens with fewer permissions than the grant they were given, reducing impact of token leak. Clients could e.g. request access tokens with some privileges and immediately revoke them after use, or other strategies.
author Kim Alvefur <zash@zash.se>
date Thu, 11 May 2023 21:40:09 +0200
parents 316d7c8e1fb0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
204
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
1
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
2 local type = type;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
3 local t_insert, t_concat, t_remove = table.insert, table.concat, table.remove;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
4 local s_char = string.char;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
5 local tostring, tonumber = tostring, tonumber;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
6 local pairs, ipairs = pairs, ipairs;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
7 local next = next;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
8 local error = error;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
9 local newproxy, getmetatable = newproxy, getmetatable;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
10 local print = print;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
11
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
12 --module("json")
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
13 local _M = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
14
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
15 local null = newproxy and newproxy(true) or {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
16 if getmetatable and getmetatable(null) then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
17 getmetatable(null).__tostring = function() return "null"; end;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
18 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
19 _M.null = null;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
20
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
21 local escapes = {
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
22 ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b",
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
23 ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
24 local unescapes = {
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
25 ["\""] = "\"", ["\\"] = "\\", ["/"] = "/",
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
26 b = "\b", f = "\f", n = "\n", r = "\r", t = "\t"};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
27 for i=0,31 do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
28 local ch = s_char(i);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
29 if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
30 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
31
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
32 local valid_types = {
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
33 number = true,
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
34 string = true,
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
35 table = true,
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
36 boolean = true
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
37 };
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
38 local special_keys = {
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
39 __array = true;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
40 __hash = true;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
41 };
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
42
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
43 local simplesave, tablesave, arraysave, stringsave;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
44
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
45 function stringsave(o, buffer)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
46 -- FIXME do proper utf-8 and binary data detection
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
47 t_insert(buffer, "\""..(o:gsub(".", escapes)).."\"");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
48 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
49
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
50 function arraysave(o, buffer)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
51 t_insert(buffer, "[");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
52 if next(o) then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
53 for i,v in ipairs(o) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
54 simplesave(v, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
55 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
56 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
57 t_remove(buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
58 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
59 t_insert(buffer, "]");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
60 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
61
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
62 function tablesave(o, buffer)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
63 local __array = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
64 local __hash = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
65 local hash = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
66 for i,v in ipairs(o) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
67 __array[i] = v;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
68 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
69 for k,v in pairs(o) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
70 local ktype, vtype = type(k), type(v);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
71 if valid_types[vtype] or v == null then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
72 if ktype == "string" and not special_keys[k] then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
73 hash[k] = v;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
74 elseif (valid_types[ktype] or k == null) and __array[k] == nil then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
75 __hash[k] = v;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
76 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
77 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
78 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
79 if next(__hash) ~= nil or next(hash) ~= nil or next(__array) == nil then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
80 t_insert(buffer, "{");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
81 local mark = #buffer;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
82 for k,v in pairs(hash) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
83 stringsave(k, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
84 t_insert(buffer, ":");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
85 simplesave(v, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
86 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
87 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
88 if next(__hash) ~= nil then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
89 t_insert(buffer, "\"__hash\":[");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
90 for k,v in pairs(__hash) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
91 simplesave(k, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
92 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
93 simplesave(v, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
94 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
95 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
96 t_remove(buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
97 t_insert(buffer, "]");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
98 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
99 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
100 if next(__array) then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
101 t_insert(buffer, "\"__array\":");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
102 arraysave(__array, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
103 t_insert(buffer, ",");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
104 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
105 if mark ~= #buffer then t_remove(buffer); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
106 t_insert(buffer, "}");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
107 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
108 arraysave(__array, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
109 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
110 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
111
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
112 function simplesave(o, buffer)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
113 local t = type(o);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
114 if t == "number" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
115 t_insert(buffer, tostring(o));
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
116 elseif t == "string" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
117 stringsave(o, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
118 elseif t == "table" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
119 tablesave(o, buffer);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
120 elseif t == "boolean" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
121 t_insert(buffer, (o and "true" or "false"));
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
122 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
123 t_insert(buffer, "null");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
124 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
125 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
126
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
127 function _M.encode(obj)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
128 local t = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
129 simplesave(obj, t);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
130 return t_concat(t);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
131 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
132
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
133 -----------------------------------
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
134
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
135
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
136 function _M.decode(json)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
137 local pos = 1;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
138 local current = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
139 local stack = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
140 local ch, peek;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
141 local function next()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
142 ch = json:sub(pos, pos);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
143 pos = pos+1;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
144 peek = json:sub(pos, pos);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
145 return ch;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
146 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
147
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
148 local function skipwhitespace()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
149 while ch and (ch == "\r" or ch == "\n" or ch == "\t" or ch == " ") do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
150 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
151 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
152 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
153 local function skiplinecomment()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
154 repeat next(); until not(ch) or ch == "\r" or ch == "\n";
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
155 skipwhitespace();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
156 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
157 local function skipstarcomment()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
158 next(); next(); -- skip '/', '*'
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
159 while peek and ch ~= "*" and peek ~= "/" do next(); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
160 if not peek then error("eof in star comment") end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
161 next(); next(); -- skip '*', '/'
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
162 skipwhitespace();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
163 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
164 local function skipstuff()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
165 while true do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
166 skipwhitespace();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
167 if ch == "/" and peek == "*" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
168 skipstarcomment();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
169 elseif ch == "/" and peek == "*" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
170 skiplinecomment();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
171 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
172 return;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
173 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
174 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
175 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
176
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
177 local readvalue;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
178 local function readarray()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
179 local t = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
180 next(); -- skip '['
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
181 skipstuff();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
182 if ch == "]" then next(); return t; end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
183 t_insert(t, readvalue());
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
184 while true do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
185 skipstuff();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
186 if ch == "]" then next(); return t; end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
187 if not ch then error("eof while reading array");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
188 elseif ch == "," then next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
189 elseif ch then error("unexpected character in array, comma expected"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
190 if not ch then error("eof while reading array"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
191 t_insert(t, readvalue());
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
192 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
193 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
194
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
195 local function checkandskip(c)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
196 local x = ch or "eof";
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
197 if x ~= c then error("unexpected "..x..", '"..c.."' expected"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
198 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
199 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
200 local function readliteral(lit, val)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
201 for c in lit:gmatch(".") do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
202 checkandskip(c);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
203 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
204 return val;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
205 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
206 local function readstring()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
207 local s = "";
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
208 checkandskip("\"");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
209 while ch do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
210 while ch and ch ~= "\\" and ch ~= "\"" do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
211 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
212 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
213 if ch == "\\" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
214 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
215 if unescapes[ch] then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
216 s = s..unescapes[ch];
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
217 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
218 elseif ch == "u" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
219 local seq = "";
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
220 for i=1,4 do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
221 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
222 if not ch then error("unexpected eof in string"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
223 if not ch:match("[0-9a-fA-F]") then error("invalid unicode escape sequence in string"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
224 seq = seq..ch;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
225 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
226 s = s..s.char(tonumber(seq, 16)); -- FIXME do proper utf-8
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
227 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
228 else error("invalid escape sequence in string"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
229 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
230 if ch == "\"" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
231 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
232 return s;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
233 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
234 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
235 error("eof while reading string");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
236 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
237 local function readnumber()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
238 local s = "";
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
239 if ch == "-" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
240 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
241 if not ch:match("[0-9]") then error("number format error"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
242 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
243 if ch == "0" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
244 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
245 if ch:match("[0-9]") then error("number format error"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
246 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
247 while ch and ch:match("[0-9]") do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
248 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
249 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
250 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
251 if ch == "." then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
252 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
253 if not ch:match("[0-9]") then error("number format error"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
254 while ch and ch:match("[0-9]") do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
255 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
256 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
257 if ch == "e" or ch == "E" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
258 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
259 if ch == "+" or ch == "-" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
260 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
261 if not ch:match("[0-9]") then error("number format error"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
262 while ch and ch:match("[0-9]") do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
263 s = s..ch; next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
264 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
265 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
266 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
267 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
268 return tonumber(s);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
269 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
270 local function readmember(t)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
271 local k = readstring();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
272 checkandskip(":");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
273 t[k] = readvalue();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
274 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
275 local function fixobject(obj)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
276 local __array = obj.__array;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
277 if __array then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
278 obj.__array = nil;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
279 for i,v in ipairs(__array) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
280 t_insert(obj, v);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
281 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
282 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
283 local __hash = obj.__hash;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
284 if __hash then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
285 obj.__hash = nil;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
286 local k;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
287 for i,v in ipairs(__hash) do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
288 if k ~= nil then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
289 obj[k] = v; k = nil;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
290 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
291 k = v;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
292 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
293 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
294 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
295 return obj;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
296 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
297 local function readobject()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
298 local t = {};
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
299 next(); -- skip '{'
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
300 skipstuff();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
301 if ch == "}" then next(); return t; end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
302 if not ch then error("eof while reading object"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
303 readmember(t);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
304 while true do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
305 skipstuff();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
306 if ch == "}" then next(); return fixobject(t); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
307 if not ch then error("eof while reading object");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
308 elseif ch == "," then next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
309 elseif ch then error("unexpected character in object, comma expected"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
310 if not ch then error("eof while reading object"); end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
311 readmember(t);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
312 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
313 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
314
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
315 function readvalue()
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
316 skipstuff();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
317 while ch do
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
318 if ch == "{" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
319 return readobject();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
320 elseif ch == "[" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
321 return readarray();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
322 elseif ch == "\"" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
323 return readstring();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
324 elseif ch:match("[%-0-9%.]") then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
325 return readnumber();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
326 elseif ch == "n" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
327 return readliteral("null", null);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
328 elseif ch == "t" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
329 return readliteral("true", true);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
330 elseif ch == "f" then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
331 return readliteral("false", false);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
332 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
333 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
334 error("eof while reading value");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
335 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
336 next();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
337 return readvalue();
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
338 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
339
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
340 function _M.test(object)
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
341 local encoded = encode(object);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
342 local decoded = decode(encoded);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
343 local recoded = encode(decoded);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
344 if encoded ~= recoded then
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
345 print("FAILED");
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
346 print("encoded:", encoded);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
347 print("recoded:", recoded);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
348 else
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
349 print(encoded);
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
350 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
351 return encoded ~= recoded;
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
352 end
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
353
316d7c8e1fb0 mod_couchdb: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
354 return _M;