a972b099fd8859fc17b0587248e92759587a44aa
[OpenSRF.git] / src / python / osrf / json.py
1 import simplejson, types 
2 from osrf.net_obj import *
3 from osrf.const import OSRF_JSON_PAYLOAD_KEY, OSRF_JSON_CLASS_KEY
4
5 class osrfJSONNetworkEncoder(simplejson.JSONEncoder):
6     def default(self, obj):
7
8         if isinstance(obj, osrfNetworkObject):
9             reg = obj.getRegistry()
10             data = obj.getData()
11
12             # re-encode the object as an array if necessary
13             if reg.wireProtocol == 'array':
14                 d = []
15                 for k in reg.keys:
16                     d.append(data[k]) 
17                 data = d
18
19             return { 
20                 OSRF_JSON_CLASS_KEY: reg.hint,
21                 OSRF_JSON_PAYLOAD_KEY: self.default(data)
22             }   
23         return obj
24
25
26 def osrfObjectToJSON(obj):
27     """Turns a python object into a wrapped JSON object"""
28     return simplejson.dumps(obj, cls=osrfJSONNetworkEncoder)
29
30
31 def osrfJSONToObject(json):
32     """Turns a JSON string into python objects"""
33     obj = simplejson.loads(json)
34     return parseNetObject(obj)
35
36 def osrfParseJSONRaw(json):
37     """Parses JSON the old fashioned way."""
38     return simplejson.loads(json)
39
40 def osrfToJSONRaw(obj):
41     """Stringifies an object as JSON with no additional logic."""
42     return simplejson.dumps(obj)
43
44 def __tabs(t):
45     r=''
46     for i in range(t): r += '   '
47     return r
48
49 def osrfDebugNetworkObject(obj, t=1):
50     """Returns a debug string for a given object.
51
52     If it's an osrfNetworkObject and has registered keys, key/value p
53     pairs are returned.  Otherwise formatted JSON is returned"""
54
55     s = ''
56     if isinstance(obj, osrfNetworkObject):
57         reg = obj.getRegistry()
58         keys = list(reg.keys) # clone it, so sorting won't break the original
59         keys.sort()
60
61         for k in keys:
62
63             key = k
64             while len(key) < 24: key += '.' # pad the names to make the values line up somewhat
65             val = getattr(obj, k)()
66
67             subobj = val and not (isinstance(val,unicode) or \
68                 isinstance(val, int) or isinstance(val, float) or isinstance(val, long))
69
70             s += __tabs(t) + key + ' = '
71
72             if subobj:
73                 s += '\n'
74                 val = osrfDebugNetworkObject(val, t+1)
75
76             s += str(val)
77
78             if not subobj: s += '\n'
79
80     else:
81         s = osrfFormatJSON(osrfObjectToJSON(obj))
82     return s
83
84 def osrfFormatJSON(json):
85     """JSON pretty-printer"""
86     r = ''
87     t = 0
88     instring = False
89     inescape = False
90     done = False
91     eatws = False
92
93     for c in json:
94
95         if eatws: # simpljson adds a pesky after array and object items
96             if c == ' ': 
97                 continue
98
99         eatws = False
100         done = False
101         if (c == '{' or c == '[') and not instring:
102             t += 1
103             r += c + '\n' + __tabs(t)
104             done = True
105
106         if (c == '}' or c == ']') and not instring:
107             t -= 1
108             r += '\n' + __tabs(t) + c
109             done = True
110
111         if c == ',' and not instring:
112             r += c + '\n' + __tabs(t)
113             done = True
114             eatws = True
115
116         if c == ':' and not instring:
117             eatws = True
118
119         if c == '"' and not inescape:
120             instring = not instring
121
122         if inescape: 
123             inescape = False
124
125         if c == '\\':
126             inescape = True
127
128         if not done:
129             r += c
130
131     return r
132
133
134
135
136
137