+urlencode = protocol.urlencode
+
+--- Send the given data as JSON encoded string.
+-- @param data Data to send
+function write_json(x)
+ if x == nil then
+ write("null")
+ elseif type(x) == "table" then
+ local k, v
+ if type(next(x)) == "number" then
+ write("[ ")
+ for k, v in ipairs(x) do
+ write_json(v)
+ if next(x, k) then
+ write(", ")
+ end
+ end
+ write(" ]")
+ else
+ write("{ ")
+ for k, v in pairs(x) do
+ write("%q: " % k)
+ write_json(v)
+ if next(x, k) then
+ write(", ")
+ end
+ end
+ write(" }")
+ end
+ elseif type(x) == "number" or type(x) == "boolean" then
+ if (x ~= x) then
+ -- NaN is the only value that doesn't equal to itself.
+ write("Number.NaN")
+ else
+ write(tostring(x))
+ end
+ else
+ write('"%s"' % tostring(x):gsub('["%z\1-\31]', function(c)
+ return '\\u%04x' % c:byte(1)
+ end))
+ end
+end