PageRenderTime 34ms CodeModel.GetById 14ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 2ms

/library/JSONParser.py

http://pyjamas.googlecode.com/
Python | 207 lines | 207 code | 0 blank | 0 comment | 0 complexity | 869c26e35539251cc7e6807f7dd48839 MD5 | raw file
  1JS("""
  2/*
  3JSONEncode:
  4    +---------------+-------------------+---------------+
  5    | PYGWT         | Python            | JSON          |
  6    +===============+===================+===============+
  7    | pyjslib_Dict  | dict              | object        |
  8    +---------------+-------------------+---------------+
  9    | pyjslib_List  | list, tuple       | array         |
 10    +---------------+-------------------+---------------+
 11    | string        | str, unicode      | string        |
 12    +---------------+-------------------+---------------+
 13    | number        | int, long, float  | number        |
 14    +---------------+-------------------+---------------+
 15    | true          | True              | true          |
 16    +---------------+-------------------+---------------+
 17    | false         | False             | false         |
 18    +---------------+-------------------+---------------+
 19    | null          | None              | null          |
 20    +---------------+-------------------+---------------+
 21
 22
 23JSONDecode:
 24    +---------------+-------------------+--------------+
 25    | JSON          | Python            | PYGWT        |
 26    +===============+===================+==============+
 27    | object        | dict              | pyjslib_Dict |
 28    +---------------+-------------------+--------------+
 29    | array         | list              | pyjslib_List |
 30    +---------------+-------------------+--------------+
 31    | string        | unicode           | string       |
 32    +---------------+-------------------+--------------+
 33    | number (int)  | int, long         | number       |
 34    +---------------+-------------------+--------------+
 35    | number (real) | float             | number       |
 36    +---------------+-------------------+--------------+
 37    | true          | True              | true         |
 38    +---------------+-------------------+--------------+
 39    | false         | False             | false        |
 40    +---------------+-------------------+--------------+
 41    | null          | None              | null         |
 42    +---------------+-------------------+--------------+
 43*/
 44""")
 45
 46# toJSONString & parseJSON from http://www.json.org/json.js
 47
 48class JSONParser:
 49    def decode(self, str):
 50        return self.jsObjectToPy(self.parseJSON(str))
 51
 52    def decodeAsObject(self, str):
 53        return self.jsObjectToPyObject(self.parseJSON(str))
 54    
 55    def encode(self, obj):
 56        return self.toJSONString(obj)
 57
 58    def jsObjectToPy(self, obj):
 59        JS("""
 60        if (pyjslib_isArray(obj)) {
 61            for (var i in obj) obj[i] = this.jsObjectToPy(obj[i]);
 62            obj=new pyjslib_List(obj);
 63            }
 64        else if (pyjslib_isObject(obj)) {
 65            for (var i in obj) obj[i]=this.jsObjectToPy(obj[i]);
 66            obj=new pyjslib_Dict(obj);
 67            }
 68        
 69        return obj;
 70        """)
 71    
 72    # TODO: __init__ parameters
 73    def jsObjectToPyObject(self, obj):
 74        JS("""
 75        if (pyjslib_isArray(obj)) {
 76            for (var i in obj) obj[i] = this.jsObjectToPyObject(obj[i]);
 77            obj=new pyjslib_List(obj);
 78            }
 79        else if (pyjslib_isObject(obj)) {
 80            if (obj["__jsonclass__"]) {
 81                var class_name = obj["__jsonclass__"][0];
 82                class_name = class_name.replace(".", "_");
 83                
 84                var new_obj = eval("new " + class_name + "()");
 85                delete obj["__jsonclass__"];
 86                for (var i in obj) new_obj[i] = this.jsObjectToPyObject(obj[i]);
 87                obj = new_obj;
 88                }
 89            else {
 90                for (var i in obj) obj[i]=this.jsObjectToPyObject(obj[i]);
 91                obj=new pyjslib_Dict(obj);
 92                }       
 93            }
 94        
 95        return obj;
 96        """)
 97    
 98    # modified to detect __pyjslib_List & __pyjslib_Dict
 99    def toJSONString(self, obj):
100        JS(r"""
101   var m = {
102            '\b': '\\b',
103            '\t': '\\t',
104            '\n': '\\n',
105            '\f': '\\f',
106            '\r': '\\r',
107            '"' : '\\"',
108            '\\': '\\\\'
109        },
110        s = {
111            array: function (x) {
112                var a = ['['], b, f, i, l = x.length, v;
113                for (i = 0; i < l; i += 1) {
114                    v = x[i];
115                    f = s[typeof v];
116                    if (f) {
117                        v = f(v);
118                        if (typeof v == 'string') {
119                            if (b) {
120                                a[a.length] = ',';
121                            }
122                            a[a.length] = v;
123                            b = true;
124                        }
125                    }
126                }
127                a[a.length] = ']';
128                return a.join('');
129            },
130            'boolean': function (x) {
131                return String(x);
132            },
133            'undefined':function (x) {
134               return "null";
135            },
136            'null': function (x) {
137                return "null";
138            },
139            number: function (x) {
140                return isFinite(x) ? String(x) : 'null';
141            },
142            object: function (x) {
143                if (x) {
144                    if (x instanceof Array) {
145                        return s.array(x);
146                    }
147                    if (x instanceof __pyjslib_List) {
148                        return s.array(x.l);
149                    }
150                    if (x instanceof __pyjslib_Dict) {
151                        return s.object(x.d);
152                    }
153                    var a = ['{'], b, f, i, v;
154                    for (i in x) {
155                        v = x[i];
156                        f = s[typeof v];
157                        if (f) {
158                            v = f(v);
159                            if (typeof v == 'string') {
160                                if (b) {
161                                    a[a.length] = ',';
162                                }
163                                a.push(s.string(i), ':', v);
164                                b = true;
165                            }
166                        }
167                    }
168                    a[a.length] = '}';
169                    return a.join('');
170                }
171                return 'null';
172            },
173            string: function (x) {
174                if (/["\\\x00-\x1f]/.test(x)) {
175                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
176                        var c = m[b];
177                        if (c) {
178                            return c;
179                        }
180                        c = b.charCodeAt();
181                        return '\\u00' +
182                            Math.floor(c / 16).toString(16) +
183                            (c % 16).toString(16);
184                    });
185                }
186                return '"' + x + '"';
187            }
188        };
189
190        f=s[typeof obj];
191        return f(obj);
192        """)
193
194    def parseJSON(self, str):
195        JS(r"""
196        try {
197            return (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(str)) &&
198                eval('(' + str + ')');
199        } catch (e) {
200            return false;
201        }
202        """)
203    
204        
205        
206
207