Skip to content

Commit

Permalink
Encode integer NOK scalars as floats
Browse files Browse the repository at this point in the history
This commit outputs a trailing ".0" for scalars that are NOK but have
integer values (that do not require scientific notation).  Doing so
transmits what limited type information we can for consumption by more
strongly-typed languages.

There is one other significant behavior change to note: scalars resulting
from addition of numeric and non-numeric data wind up NOK (e.g. "42" +
"bar").
  • Loading branch information
xdg committed Apr 11, 2016
1 parent a641a9b commit 8a3da11
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 3 deletions.
9 changes: 9 additions & 0 deletions XS.xs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,7 @@ encode_sv (pTHX_ enc_t *enc, SV *sv)
else if (SvNOKp (sv))
{
char *savecur, *saveend;
char inf_or_nan = 0;
/* trust that perl will do the right thing w.r.t. JSON syntax. */
need (aTHX_ enc, NV_DIG + 32);
savecur = enc->cur;
Expand All @@ -1193,6 +1194,7 @@ encode_sv (pTHX_ enc_t *enc, SV *sv)
|| strEQ(enc->cur+1, STR_QNAN)
#endif
))) {
inf_or_nan = 1;
if (enc->json.infnan_mode == 0) {
strncpy(enc->cur, "null\0", 5);
}
Expand All @@ -1218,6 +1220,13 @@ encode_sv (pTHX_ enc_t *enc, SV *sv)
*enc->cur = 0;
}
else {
double intpart;
if (!( inf_or_nan || modf(SvNVX(sv), &intpart) || SvIOK(sv)
|| strchr(enc->cur,'e') || strchr(enc->cur,'E') ) )
{
char *tempend = enc->cur + strlen(enc->cur);
strncpy(tempend, ".0\0", 3);
}
enc->cur += strlen (enc->cur);
}
}
Expand Down
4 changes: 3 additions & 1 deletion t/03_types.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
BEGIN { $| = 1; print "1..84\n"; }
BEGIN { $| = 1; print "1..85\n"; }
use utf8;
use Cpanel::JSON::XS;

Expand Down Expand Up @@ -65,6 +65,8 @@ for $v (1, 2, 3, 5, -1, -2, -3, -4, 100, 1000, 10000, -999, -88, -7, 7, 88, 999,
ok ($v == ((decode_json encode_json [$v])->[0]));
}

ok ('[1.0]' eq encode_json [1.0]);

ok (30123 == ((decode_json encode_json [30123])->[0]));
ok (32123 == ((decode_json encode_json [32123])->[0]));
ok (32456 == ((decode_json encode_json [32456])->[0]));
Expand Down
2 changes: 1 addition & 1 deletion t/117_numbers.t
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ is encode_json({test => [$num, $str]}), '{"test":[1,"0 but true"]}', 'int/string

$str = 'bar';
{ no warnings "numeric"; $num = 23 + $str }
is encode_json({test => [$num, $str]}), '{"test":[23,"bar"]}', , 'int/string dualvar';
is encode_json({test => [$num, $str]}), '{"test":[23.0,"bar"]}', , 'int/string dualvar';
2 changes: 1 addition & 1 deletion t/11_pc_expo.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ $js = q|[-1.234e5]|;
$obj = $pc->decode($js);
is($obj->[0], -123400, 'digit -1.234e5');
$js = $pc->encode($obj);
is($js,'[-123400]', 'digit -1.234e5');
is($js,'[-123400.0]', 'digit -1.234e5');

$js = q|[1.23E-4]|;
$obj = $pc->decode($js);
Expand Down

0 comments on commit 8a3da11

Please sign in to comment.