ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
(Generate patch)

Comparing JSON-XS/XS.xs (file contents):
Revision 1.103 by root, Wed Jan 6 08:01:39 2010 UTC vs.
Revision 1.104 by root, Tue Jan 19 00:31:13 2010 UTC

187 return SvUTF8 (sv) 187 return SvUTF8 (sv)
188 ? utf8_distance (offset, SvPVX (sv)) 188 ? utf8_distance (offset, SvPVX (sv))
189 : offset - SvPVX (sv); 189 : offset - SvPVX (sv);
190} 190}
191 191
192/////////////////////////////////////////////////////////////////////////////
193// fp hell
194
195// scan a group of digits, and a trailing exponent
196static void
197json_atof_scan1 (const char *s, NV *accum, int *expo, int postdp)
198{
199 UV uaccum = 0;
200 int eaccum = 0;
201
202 for (;;)
203 {
204 U8 dig = (U8)*s - '0';
205
206 if (expect_false (dig >= 10))
207 {
208 if (dig == (U8)((U8)'.' - (U8)'0'))
209 {
210 ++s;
211 json_atof_scan1 (s, accum, expo, 1);
212 }
213 else if ((dig | ' ') == 'e' - '0')
214 {
215 int exp2 = 0;
216 int neg = 0;
217
218 ++s;
219
220 if (*s == '-')
221 {
222 ++s;
223 neg = 1;
224 }
225 else if (*s == '+')
226 ++s;
227
228 while ((dig = (U8)*s - '0') < 10)
229 exp2 = exp2 * 10 + *s++ - '0';
230
231 *expo += neg ? -exp2 : exp2;
232 }
233
234 break;
235 }
236
237 ++s;
238
239 uaccum = uaccum * 10 + dig;
240 ++eaccum;
241
242 // if we have too many digits, then recurse for more
243 // we actually do this for rather few digits
244 if (uaccum >= (UV_MAX - 9) / 10)
245 {
246 if (postdp) *expo -= eaccum;
247 json_atof_scan1 (s, accum, expo, postdp);
248 if (postdp) *expo += eaccum;
249
250 break;
251 }
252 }
253
254 if (postdp) *expo -= eaccum;
255 *accum += uaccum * pow (10., *expo);
256 *expo += eaccum;
257}
258
259static NV
260json_atof (const char *s)
261{
262 NV accum = 0.;
263 int expo = 0;
264 int neg = 0;
265
266 if (*s == '-')
267 {
268 ++s;
269 neg = 1;
270 }
271
272 json_atof_scan1 (s, &accum, &expo, 0);
273
274 return neg ? -accum : accum;
275}
192///////////////////////////////////////////////////////////////////////////// 276/////////////////////////////////////////////////////////////////////////////
193// encoder 277// encoder
194 278
195// structure used for encoding JSON 279// structure used for encoding JSON
196typedef struct 280typedef struct
1119 } 1203 }
1120 1204
1121 len -= *start == '-' ? 1 : 0; 1205 len -= *start == '-' ? 1 : 0;
1122 1206
1123 // does not fit into IV or UV, try NV 1207 // does not fit into IV or UV, try NV
1124 if ((sizeof (NV) == sizeof (double) && DBL_DIG >= len) 1208 if (len <= NV_DIG)
1125 #if defined (LDBL_DIG)
1126 || (sizeof (NV) == sizeof (long double) && LDBL_DIG >= len)
1127 #endif
1128 )
1129 // fits into NV without loss of precision 1209 // fits into NV without loss of precision
1130 return newSVnv (Atof (start)); 1210 return newSVnv (json_atof (start));
1131 1211
1132 // everything else fails, convert it to a string 1212 // everything else fails, convert it to a string
1133 return newSVpvn (start, dec->cur - start); 1213 return newSVpvn (start, dec->cur - start);
1134 } 1214 }
1135 1215
1136 // loss of precision here 1216 // loss of precision here
1137 return newSVnv (Atof (start)); 1217 return newSVnv (json_atof (start));
1138 1218
1139fail: 1219fail:
1140 return 0; 1220 return 0;
1141} 1221}
1142 1222
1963 json_init (&json); 2043 json_init (&json);
1964 json.flags |= ix; 2044 json.flags |= ix;
1965 XPUSHs (decode_json (jsonstr, &json, 0)); 2045 XPUSHs (decode_json (jsonstr, &json, 0));
1966} 2046}
1967 2047
1968

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines