2013/yue/60595411.yue

384 lines
6.6 KiB
Plaintext

t = {}
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------JSON Functions Begin----------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
--JSON Encoder and Parser for Lua 5.1
--
--2007 Shaun Brown (http://www.chipmunkav.com)
assert = assert
Null = -> Null
StringBuilder = {
buffer: {}
}
StringBuilder.New ==>
o = <>: @
@__index = @
o.buffer = {}
o
StringBuilder.Append = (s) =>
@buffer[] = s
StringBuilder.ToString ==> table.concat @buffer
JsonWriter =
backslashes:
["\b"]: "\\b",
["\t"]: "\\t",
["\n"]: "\\n",
["\f"]: "\\f",
["\r"]: "\\r",
['"']: '\\"',
["\\"]: "\\\\",
["/"]: "\\/",
JsonWriter.New ==>
o = <>: @
o.writer = StringBuilder\New!
@__index = @
o
JsonWriter.Append = (s) =>
@writer\Append s
JsonWriter.ToString ==> @writer\ToString!
JsonWriter.Write = (o) =>
switch type o
when "nil"
@\WriteNil!
when "boolean", "number"
@\WriteString o
when "string"
@\ParseString o
when "table"
@\WriteTable o
when "function"
@\WriteFunction o
when "thread", "userdata"
@\WriteError o
JsonWriter.WriteNil ==> @\Append "null"
JsonWriter.WriteString = (o) => @\Append "#{o}"
JsonWriter.ParseString = (s) =>
@\Append '"'
@\Append string.gsub s, '[%z%c\\"/]', (n) ->
c = @backslashes[n]
if c
return c
return string.format "\\u%.4X", string.byte n
@\Append '"'
JsonWriter.IsArray = (t) =>
count = 0
isindex = (k) ->
if type(k) == "number" and
k > 0 and
math.floor(k) == k
return true
return false
for k, _ in pairs t
if not isindex k
return false, "{", "}"
else
count = math.max count, k
return true, "[", "]", count
JsonWriter.WriteTable = (t) =>
ba, st, et, n = @\IsArray t
@\Append st
if ba
for i = 1, n
@\Write t[i]
if i < n
@\Append ","
else
first = true
for k, v in pairs t
if not first
@\Append ","
first = false
@\ParseString k
@\Append ":"
@\Write v
@\Append et
JsonWriter.WriteError = (o) =>
error string.format "Encoding of %s unsupported", "#{o}"
JsonWriter.WriteFunction = (o) =>
if o == Null
@\WriteNil!
else
@\WriteError o
StringReader =
s: "",
i: 0,
StringReader.New = (s) =>
o = <>: @
@__index = @
o.s = s or o.s
o
StringReader.Peek ==>
i = @i + 1
if i <= #@s
return string.sub @s, i, i
nil
StringReader.Next ==>
@i = @i + 1
if @i <= #@s
return string.sub @s, @i, @i
nil
StringReader.All ==> @s
JsonReader =
escapes:
["t"]: "\t",
["n"]: "\n",
["f"]: "\f",
["r"]: "\r",
["b"]: "\b",
JsonReader.New = (s) =>
o = <>: @
o.reader = StringReader\New s
@__index = @
o
JsonReader.Read ==>
@\SkipWhiteSpace!
peek = @\Peek!
return if not peek?
error string.format "Nil string: '%s'", @\All!
elseif peek == "{"
@\ReadObject!
elseif peek == "["
@\ReadArray!
elseif peek == '"'
@\ReadString!
elseif string.find peek, "[%+%-%d]"
@\ReadNumber!
elseif peek == "t"
@\ReadTrue!
elseif peek == "f"
@\ReadFalse!
elseif peek == "n"
@\ReadNull!
elseif peek == "/"
@\ReadComment!
@\Read!
else
nil
JsonReader.ReadTrue ==>
@\TestReservedWord { "t", "r", "u", "e" }
true
JsonReader.ReadFalse ==>
@\TestReservedWord { "f", "a", "l", "s", "e" }
false
JsonReader.ReadNull ==>
@\TestReservedWord { "n", "u", "l", "l" }
nil
JsonReader.TestReservedWord = (t) =>
for _, v in ipairs t
if @\Next! ~= v
error string.format "Error reading '%s': %s", table.concat(t), @\All!
JsonReader.ReadNumber ==>
result = @\Next!
peek = @\Peek!
while peek? and string.find peek, "[%+%-%d%.eE]"
result ..= @\Next!
peek = @\Peek!
result = tonumber result
if not result?
error string.format "Invalid number: '%s'", result
else
return result
JsonReader.ReadString ==>
result = ""
assert @\Next! == '"'
while @\Peek! ~= '"'
ch = @\Next!
if ch == "\\"
ch = @\Next!
if @escapes[ch]
ch = @escapes[ch]
result ..= ch
assert @\Next! == '"'
fromunicode = (m) -> string.char tonumber m, 16
string.gsub result, "u%x%x(%x%x)", fromunicode
JsonReader.ReadComment ==>
assert @\Next! == "/"
second = @\Next!
if second == "/"
@\ReadSingleLineComment!
elseif second == "*"
@\ReadBlockComment!
else
error string.format "Invalid comment: %s", @\All!
JsonReader.ReadBlockComment ==>
done = false
until done
ch = @\Next!
if ch == "*" and @\Peek! == "/"
done = true
if not done and ch == "/" and @\Peek! == "*"
error string.format "Invalid comment: %s, '/*' illegal.", @\All!
@\Next!
JsonReader.ReadSingleLineComment ==>
ch = @\Next!
while ch ~= "\r" and ch ~= "\n"
ch = @\Next!
JsonReader.ReadArray ==>
result = {}
assert @\Next! == "["
done = false
if @\Peek! == "]"
done = true
until done
item = @\Read!
result[] = item
@\SkipWhiteSpace!
if @\Peek! == "]"
done = true
if not done
ch = @\Next!
if ch ~= ","
error string.format "Invalid array: '%s' due to: '%s'", @\All!, ch
assert "]" == @\Next!
result
JsonReader.ReadObject ==>
result = {}
assert @\Next! == "{"
done = false
if @\Peek! == "}"
done = true
until done
key = @\Read!
if type(key) ~= "string"
error string.format "Invalid non-string object key: %s", key
@\SkipWhiteSpace!
ch = @\Next!
if ch ~= ":"
error string.format "Invalid object: '%s' due to: '%s'", @\All!, ch
@\SkipWhiteSpace!
val = @\Read!
result[key] = val
@\SkipWhiteSpace!
if @\Peek! == "}"
done = true
if not done
ch = @\Next!
if ch ~= ","
error string.format "Invalid array: '%s' near: '%s'", @\All!, ch
assert @\Next! == "}"
result
JsonReader.SkipWhiteSpace ==>
p = @\Peek!
while p? and string.find p, "[%s/]"
if p == "/"
@\ReadComment!
else
@\Next!
p = @\Peek!
JsonReader.Peek ==> @reader\Peek!
JsonReader.Next ==> @reader\Next!
JsonReader.All ==> @reader\All!
Encode = (o) ->
with JsonWriter\New!
\Write o
\ToString!
Decode = (s) ->
with JsonReader\New s
\Read!
-------------------- End JSON Parser ------------------------
-- TODO