5
5
"fmt"
6
6
"math"
7
7
"math/big"
8
+ "net/url"
8
9
"reflect"
9
10
"runtime/debug"
10
11
"strings"
@@ -95,13 +96,22 @@ func (j *jsHandleImpl) JSONValue() (interface{}, error) {
95
96
}
96
97
97
98
func parseValue (result interface {}, refs map [float64 ]interface {}) interface {} {
98
- vMap := result .(map [string ]interface {})
99
+ vMap , ok := result .(map [string ]interface {})
100
+ if ! ok {
101
+ return result
102
+ }
99
103
if v , ok := vMap ["n" ]; ok {
100
104
if math .Ceil (v .(float64 ))- v .(float64 ) == 0 {
101
105
return int (v .(float64 ))
102
106
}
103
107
return v .(float64 )
104
108
}
109
+
110
+ if v , ok := vMap ["u" ]; ok {
111
+ u , _ := url .Parse (v .(string ))
112
+ return u
113
+ }
114
+
105
115
if v , ok := vMap ["bi" ]; ok {
106
116
n := new (big.Int )
107
117
n .SetString (v .(string ), 0 )
@@ -135,11 +145,12 @@ func parseValue(result interface{}, refs map[float64]interface{}) interface{} {
135
145
return math .Inf (- 1 )
136
146
}
137
147
if v == "-0" {
138
- return - 0
148
+ return math . Copysign ( 0 , - 1 )
139
149
}
150
+ return v
140
151
}
141
152
if v , ok := vMap ["d" ]; ok {
142
- t , _ := time .Parse (time .RFC3339 , v .(string ))
153
+ t , _ := time .Parse (time .RFC3339Nano , v .(string ))
143
154
return t
144
155
}
145
156
if v , ok := vMap ["a" ]; ok {
@@ -152,8 +163,8 @@ func parseValue(result interface{}, refs map[float64]interface{}) interface{} {
152
163
}
153
164
if v , ok := vMap ["o" ]; ok {
154
165
aV := v .([]interface {})
155
- refs [vMap ["id" ].(float64 )] = v
156
166
out := map [string ]interface {}{}
167
+ refs [vMap ["id" ].(float64 )] = out
157
168
for key := range aV {
158
169
entry := aV [key ].(map [string ]interface {})
159
170
out [entry ["k" ].(string )] = parseValue (entry ["v" ], refs )
@@ -178,6 +189,12 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
178
189
"h" : h ,
179
190
}
180
191
}
192
+ if u , ok := value .(* url.URL ); ok {
193
+ return map [string ]interface {}{
194
+ "u" : u .String (),
195
+ }
196
+ }
197
+
181
198
if depth > 100 {
182
199
panic (errors .New ("Maximum argument depth exceeded" ))
183
200
}
@@ -191,8 +208,30 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
191
208
"bi" : n .String (),
192
209
}
193
210
}
211
+
212
+ switch v := value .(type ) {
213
+ case time.Time :
214
+ return map [string ]interface {}{
215
+ "d" : v .Format (time .RFC3339Nano ),
216
+ }
217
+ case int :
218
+ return map [string ]interface {}{
219
+ "n" : v ,
220
+ }
221
+ case string :
222
+ return map [string ]interface {}{
223
+ "s" : v ,
224
+ }
225
+ case bool :
226
+ return map [string ]interface {}{
227
+ "b" : v ,
228
+ }
229
+ }
230
+
194
231
refV := reflect .ValueOf (value )
195
- if refV .Kind () == reflect .Float32 || refV .Kind () == reflect .Float64 {
232
+
233
+ switch refV .Kind () {
234
+ case reflect .Float32 , reflect .Float64 :
196
235
floatV := refV .Float ()
197
236
if math .IsInf (floatV , 1 ) {
198
237
return map [string ]interface {}{
@@ -204,7 +243,8 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
204
243
"v" : "-Infinity" ,
205
244
}
206
245
}
207
- if floatV == - 0 {
246
+ // https://github.com/golang/go/issues/2196
247
+ if floatV == math .Copysign (0 , - 1 ) {
208
248
return map [string ]interface {}{
209
249
"v" : "-0" ,
210
250
}
@@ -214,46 +254,39 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
214
254
"v" : "NaN" ,
215
255
}
216
256
}
217
- }
218
- if refV .Kind () == reflect .Slice {
219
- aV := value .([]interface {})
220
- for i := range aV {
221
- aV [i ] = serializeValue (aV [i ], handles , depth + 1 )
257
+ return map [string ]interface {}{
258
+ "n" : floatV ,
222
259
}
223
- return aV
224
- }
225
- if refV .Kind () == reflect .Map {
260
+ case reflect .Slice :
261
+ aV := make ([]interface {}, refV .Len ())
262
+ for i := 0 ; i < refV .Len (); i ++ {
263
+ aV [i ] = serializeValue (refV .Index (i ).Interface (), handles , depth + 1 )
264
+ }
265
+ return map [string ]interface {}{
266
+ "a" : aV ,
267
+ }
268
+ case reflect .Map :
226
269
out := []interface {}{}
227
270
vM := value .(map [string ]interface {})
228
271
for key := range vM {
272
+ v := serializeValue (vM [key ], handles , depth + 1 )
273
+ // had key, so convert "undefined" to "null"
274
+ if reflect .DeepEqual (v , map [string ]interface {}{
275
+ "v" : "undefined" ,
276
+ }) {
277
+ v = map [string ]interface {}{
278
+ "v" : "null" ,
279
+ }
280
+ }
229
281
out = append (out , map [string ]interface {}{
230
282
"k" : key ,
231
- "v" : serializeValue ( vM [ key ], handles , depth + 1 ) ,
283
+ "v" : v ,
232
284
})
233
285
}
234
286
return map [string ]interface {}{
235
287
"o" : out ,
236
288
}
237
289
}
238
- switch v := value .(type ) {
239
- case time.Time :
240
- return map [string ]interface {}{
241
- "d" : v .Format (time .RFC3339 ) + "Z" ,
242
- }
243
- case int :
244
- return map [string ]interface {}{
245
- "n" : v ,
246
- }
247
- case string :
248
- return map [string ]interface {}{
249
- "s" : v ,
250
- }
251
- case bool :
252
- return map [string ]interface {}{
253
- "b" : v ,
254
- }
255
- }
256
-
257
290
return map [string ]interface {}{
258
291
"v" : "undefined" ,
259
292
}
0 commit comments