2 " Last Change: 2012-03-08
3 " Maintainer: Yasuhiro Matsumoto <mattn.jp@gmail.com>
4 " License: This file is placed in the public domain.
10 function! webapi#json#null()
14 function! webapi#json#true()
18 function! webapi#json#false()
22 function! s:nr2byte(nr)
26 return nr2char(a:nr/64+192).nr2char(a:nr%64+128)
28 return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128)
32 function! s:nr2enc_char(charcode)
33 if &encoding == 'utf-8'
34 return nr2char(a:charcode)
36 let char = s:nr2byte(a:charcode)
38 let char = strtrans(iconv(char, 'utf-8', &encoding))
43 function! s:fixup(val, tmp)
46 elseif type(a:val) == 1
47 if a:val == a:tmp.'null'
48 return function('webapi#json#null')
49 elseif a:val == a:tmp.'true'
50 return function('webapi#json#true')
51 elseif a:val == a:tmp.'false'
52 return function('webapi#json#false')
55 elseif type(a:val) == 2
57 elseif type(a:val) == 3
58 return map(a:val, 's:fixup(v:val, a:tmp)')
59 elseif type(a:val) == 4
60 return map(a:val, 's:fixup(v:val, a:tmp)')
66 function! webapi#json#decode(json)
67 let json = iconv(a:json, "utf-8", &encoding)
68 if get(g:, 'webapi#json#parse_strict', 1) == 1 && substitute(substitute(substitute(
70 \ '\\\%(["\\/bfnrt]\|u[0-9a-fA-F]\{4}\)', '\@', 'g'),
71 \ '"[^\"\\\n\r]*\"\|true\|false\|null\|-\?\d\+'
72 \ . '\%(\.\d*\)\?\%([eE][+\-]\{-}\d\+\)\?', ']', 'g'),
73 \ '\%(^\|:\|,\)\%(\s*\[\)\+', '', 'g') !~ '^[\],:{} \t\n]*$'
76 let json = substitute(json, '\n', '', 'g')
77 let json = substitute(json, '\\u34;', '\\"', 'g')
78 let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:nr2enc_char("0x".submatch(1))', 'g')
79 if get(g:, 'webapi#json#allow_nil', 0) != 0
80 let tmp = '__WEBAPI_JSON__'
82 if stridx(json, tmp) == -1
87 let [null,true,false] = [
91 sandbox let ret = eval(json)
92 call s:fixup(ret, tmp)
94 let [null,true,false] = [0,1,0]
95 sandbox let ret = eval(json)
100 function! webapi#json#encode(val)
103 elseif type(a:val) == 1
104 let json = '"' . escape(a:val, '\"') . '"'
105 let json = substitute(json, "\r", '\\r', 'g')
106 let json = substitute(json, "\n", '\\n', 'g')
107 let json = substitute(json, "\t", '\\t', 'g')
108 return iconv(json, &encoding, "utf-8")
109 elseif type(a:val) == 2
110 let s = string(a:val)
111 if s == "function('webapi#json#null')"
113 elseif s == "function('webapi#json#true')"
115 elseif s == "function('webapi#json#false')"
118 elseif type(a:val) == 3
119 return '[' . join(map(copy(a:val), 'webapi#json#encode(v:val)'), ',') . ']'
120 elseif type(a:val) == 4
121 return '{' . join(map(keys(a:val), 'webapi#json#encode(v:val).":".webapi#json#encode(a:val[v:val])'), ',') . '}'
127 let &cpo = s:save_cpo