rebase on 2015
[Vimrc.git] / bundle / webapi-vim-0.1 / autoload / webapi / json.vim
blob8bb0075d98ba40d752bca63323baa6d899276033
1 " json
2 " Last Change: 2012-03-08
3 " Maintainer:   Yasuhiro Matsumoto <mattn.jp@gmail.com>
4 " License:      This file is placed in the public domain.
5 " Reference:
7 let s:save_cpo = &cpo
8 set cpo&vim
10 function! webapi#json#null()
11   return 0
12 endfunction
14 function! webapi#json#true()
15   return 1
16 endfunction
18 function! webapi#json#false()
19   return 0
20 endfunction
22 function! s:nr2byte(nr)
23   if a:nr < 0x80
24     return nr2char(a:nr)
25   elseif a:nr < 0x800
26     return nr2char(a:nr/64+192).nr2char(a:nr%64+128)
27   else
28     return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128)
29   endif
30 endfunction
32 function! s:nr2enc_char(charcode)
33   if &encoding == 'utf-8'
34     return nr2char(a:charcode)
35   endif
36   let char = s:nr2byte(a:charcode)
37   if strlen(char) > 1
38     let char = strtrans(iconv(char, 'utf-8', &encoding))
39   endif
40   return char
41 endfunction
43 function! s:fixup(val, tmp)
44   if type(a:val) == 0
45     return a:val
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')
53     endif
54     return a:val
55   elseif type(a:val) == 2
56     return a:val
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)')
61   else
62     return string(a:val)
63   endif
64 endfunction
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(
69     \ json,
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]*$'
74     throw json
75   endif
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__'
81     while 1
82       if stridx(json, tmp) == -1
83         break
84       endif
85       let tmp .= '_'
86     endwhile
87     let [null,true,false] = [
88     \ tmp.'null',
89     \ tmp.'true',
90     \ tmp.'false']
91     sandbox let ret = eval(json)
92     call s:fixup(ret, tmp)
93   else
94     let [null,true,false] = [0,1,0]
95     sandbox let ret = eval(json)
96   endif
97   return ret
98 endfunction
100 function! webapi#json#encode(val)
101   if type(a:val) == 0
102     return a: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')"
112       return 'null'
113     elseif s == "function('webapi#json#true')"
114       return 'true'
115     elseif s == "function('webapi#json#false')"
116       return 'false'
117     endif
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])'), ',') . '}'
122   else
123     return string(a:val)
124   endif
125 endfunction
127 let &cpo = s:save_cpo
128 unlet s:save_cpo
130 " vim:set et: