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.60 by root, Mon Aug 13 16:19:13 2007 UTC vs.
Revision 1.61 by root, Sun Aug 26 21:56:47 2007 UTC

335 --enc->indent; 335 --enc->indent;
336 encode_indent (enc); encode_ch (enc, ']'); 336 encode_indent (enc); encode_ch (enc, ']');
337} 337}
338 338
339static void 339static void
340encode_he (enc_t *enc, HE *he) 340encode_hk (enc_t *enc, HE *he)
341{ 341{
342 encode_ch (enc, '"'); 342 encode_ch (enc, '"');
343 343
344 if (HeKLEN (he) == HEf_SVKEY) 344 if (HeKLEN (he) == HEf_SVKEY)
345 { 345 {
358 encode_ch (enc, '"'); 358 encode_ch (enc, '"');
359 359
360 if (enc->json.flags & F_SPACE_BEFORE) encode_space (enc); 360 if (enc->json.flags & F_SPACE_BEFORE) encode_space (enc);
361 encode_ch (enc, ':'); 361 encode_ch (enc, ':');
362 if (enc->json.flags & F_SPACE_AFTER ) encode_space (enc); 362 if (enc->json.flags & F_SPACE_AFTER ) encode_space (enc);
363 encode_sv (enc, HeVAL (he));
364} 363}
365 364
366// compare hash entries, used when all keys are bytestrings 365// compare hash entries, used when all keys are bytestrings
367static int 366static int
368he_cmp_fast (const void *a_, const void *b_) 367he_cmp_fast (const void *a_, const void *b_)
373 HE *b = *(HE **)b_; 372 HE *b = *(HE **)b_;
374 373
375 STRLEN la = HeKLEN (a); 374 STRLEN la = HeKLEN (a);
376 STRLEN lb = HeKLEN (b); 375 STRLEN lb = HeKLEN (b);
377 376
378 if (!(cmp = memcmp (HeKEY (a), HeKEY (b), la < lb ? la : lb))) 377 if (!(cmp = memcmp (HeKEY (b), HeKEY (a), lb < la ? lb : la)))
379 cmp = la - lb; 378 cmp = lb - la;
380 379
381 return cmp; 380 return cmp;
382} 381}
383 382
384// compare hash entries, used when some keys are sv's or utf-x 383// compare hash entries, used when some keys are sv's or utf-x
385static int 384static int
386he_cmp_slow (const void *a, const void *b) 385he_cmp_slow (const void *a, const void *b)
387{ 386{
388 return sv_cmp (HeSVKEY_force (*(HE **)a), HeSVKEY_force (*(HE **)b)); 387 return sv_cmp (HeSVKEY_force (*(HE **)b), HeSVKEY_force (*(HE **)a));
389} 388}
390 389
391static void 390static void
392encode_hv (enc_t *enc, HV *hv) 391encode_hv (enc_t *enc, HV *hv)
393{ 392{
393 HE *he;
394 int count, i; 394 int count;
395 395
396 if (enc->indent >= enc->maxdepth) 396 if (enc->indent >= enc->maxdepth)
397 croak ("data structure too deep (hit recursion limit)"); 397 croak ("data structure too deep (hit recursion limit)");
398 398
399 encode_ch (enc, '{'); encode_nl (enc); ++enc->indent; 399 encode_ch (enc, '{'); encode_nl (enc); ++enc->indent;
400 400
401 if ((count = hv_iterinit (hv)))
402 {
403 // for canonical output we have to sort by keys first 401 // for canonical output we have to sort by keys first
404 // actually, this is mostly due to the stupid so-called 402 // actually, this is mostly due to the stupid so-called
405 // security workaround added somewhere in 5.8.x. 403 // security workaround added somewhere in 5.8.x.
406 // that randomises hash orderings 404 // that randomises hash orderings
407 if (enc->json.flags & F_CANONICAL) 405 if (enc->json.flags & F_CANONICAL)
406 {
407 int count = hv_iterinit (hv);
408
409 if (SvMAGICAL (hv))
408 { 410 {
411 // need to count by iterating. could improve by dynamically building the vector below
412 // but I don't care for the speed of this special case.
413 // note also that we will run into undefined behaviour when the two iterations
414 // do not result in the same count, something I might care for in some later release.
415
416 count = 0;
417 while (hv_iternext (hv))
418 ++count;
419
420 hv_iterinit (hv);
421 }
422
423 if (count)
424 {
409 int fast = 1; 425 int i, fast = 1;
410 HE *he;
411#if defined(__BORLANDC__) || defined(_MSC_VER) 426#if defined(__BORLANDC__) || defined(_MSC_VER)
412 HE **hes = _alloca (count * sizeof (HE)); 427 HE **hes = _alloca (count * sizeof (HE));
413#else 428#else
414 HE *hes [count]; // if your compiler dies here, you need to enable C99 mode 429 HE *hes [count]; // if your compiler dies here, you need to enable C99 mode
415#endif 430#endif
442 457
443 FREETMPS; 458 FREETMPS;
444 LEAVE; 459 LEAVE;
445 } 460 }
446 461
447 for (i = 0; i < count; ++i) 462 while (count--)
448 { 463 {
449 encode_indent (enc); 464 encode_indent (enc);
465 he = hes [count];
450 encode_he (enc, hes [i]); 466 encode_hk (enc, he);
467 encode_sv (enc, SvMAGICAL (hv) ? hv_iterval (hv, he) : HeVAL (he));
451 468
452 if (i < count - 1) 469 if (count)
453 encode_comma (enc); 470 encode_comma (enc);
454 } 471 }
455
456 encode_nl (enc);
457 } 472 }
473 }
458 else 474 else
459 { 475 {
476 if (hv_iterinit (hv) || SvMAGICAL (hv))
460 HE *he = hv_iternext (hv); 477 if ((he = hv_iternext (hv)))
461
462 for (;;) 478 for (;;)
463 { 479 {
464 encode_indent (enc); 480 encode_indent (enc);
465 encode_he (enc, he); 481 encode_hk (enc, he);
482 encode_sv (enc, SvMAGICAL (hv) ? hv_iterval (hv, he) : HeVAL (he));
466 483
467 if (!(he = hv_iternext (hv))) 484 if (!(he = hv_iternext (hv)))
468 break; 485 break;
469 486
470 encode_comma (enc); 487 encode_comma (enc);
471 } 488 }
489 }
472 490
473 encode_nl (enc); 491 encode_nl (enc);
474 }
475 }
476 492
477 --enc->indent; encode_indent (enc); encode_ch (enc, '}'); 493 --enc->indent; encode_indent (enc); encode_ch (enc, '}');
478} 494}
479 495
480// encode objects, arrays and special \0=false and \1=true values. 496// encode objects, arrays and special \0=false and \1=true values.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines