diff --git a/FU.xs b/FU.xs index 9392677..146d7e7 100644 --- a/FU.xs +++ b/FU.xs @@ -10,10 +10,6 @@ MODULE = FU PACKAGE = FU::XS PROTOTYPES: DISABLE -void json_format(SV *val) +void json_format(SV *val, ...) CODE: - fustr buf; - fustr_init(&buf, 128); - fujson_fmt(aTHX_ &buf, val); - ST(0) = fustr_done(&buf); - SvUTF8_on(ST(0)); + ST(0) = fujson_fmt_xs(aTHX_ ax, items, val); diff --git a/FU/Benchmarks.pod b/FU/Benchmarks.pod index 35c16c3..7366387 100644 --- a/FU/Benchmarks.pod +++ b/FU/Benchmarks.pod @@ -43,8 +43,7 @@ The following module versions were used: These benchmarks run on large-ish arrays with repeated values. JSON encoding is sufficiently fast that Perl function calling overhead tends to dominate for -smaller inputs, but I don't find that overhead very interesting. Other modules -will likely do better in benchmarks on small inputs. +smaller inputs, but I don't find that overhead very interesting. Also worth noting that JSON::SIMD formatting code is forked from JSON::XS, the SIMD parts are only used for parsing. diff --git a/FU/Util.pm b/FU/Util.pm index 1b40b45..32533b9 100644 --- a/FU/Util.pm +++ b/FU/Util.pm @@ -6,12 +6,6 @@ use Exporter 'import'; our @EXPORT_OK = qw/json_format/; - -sub json_format($val, %opt) { - my $r = FU::XS::json_format($val); - # XXX: Does this go over the bytes? If so, not setting SvUTF8_on() in the first place would be much faster. - utf8::encode($r) if $opt{utf8}; - $r -} +*json_format = *FU::XS::json_format; 1; diff --git a/bench.PL b/bench.PL index 0319540..5a8b236 100755 --- a/bench.PL +++ b/bench.PL @@ -159,8 +159,7 @@ The following module versions were used: These benchmarks run on large-ish arrays with repeated values. JSON encoding is sufficiently fast that Perl function calling overhead tends to dominate for -smaller inputs, but I don't find that overhead very interesting. Other modules -will likely do better in benchmarks on small inputs. +smaller inputs, but I don't find that overhead very interesting. Also worth noting that JSON::SIMD formatting code is forked from JSON::XS, the SIMD parts are only used for parsing. diff --git a/c/jsonfmt.c b/c/jsonfmt.c index c4c8594..6276d05 100644 --- a/c/jsonfmt.c +++ b/c/jsonfmt.c @@ -172,6 +172,35 @@ static void fujson_fmt(pTHX_ fustr *out, SV *val) { } } + +static SV *fujson_fmt_xs(pTHX_ I32 ax, I32 argc, SV *val) { + I32 i = 1; + int encutf8 = 0; + char *arg; + SV *r; + + while (i < argc) { + arg = SvPV_nolen(ST(i)); + i++; + if (i == argc) croak("Odd name/value argument for json_format()"); + r = ST(i); + i++; + + if (strcmp(arg, "utf8") == 0) { + encutf8 = SvPVXtrue(r); + } else { + croak("Unknown flag: '%s'", arg); + } + } + + fustr buf; + fustr_init(&buf, 128); + fujson_fmt(aTHX_ &buf, val); + r = fustr_done(&buf); + if (!encutf8) SvUTF8_on(r); + return r; +} + /* TODO: canonical */ /* TODO: pretty */ /* TODO: max depth? */ diff --git a/t/json_format.t b/t/json_format.t index 8493dec..f525572 100644 --- a/t/json_format.t +++ b/t/json_format.t @@ -58,12 +58,17 @@ my @errors = ( do { no warnings 'portable'; "\x{ffffffff}" }, qr/invalid codepoint encountered in string/, ); -plan tests => @tests + @errors/2 + 6; +plan tests => @tests*2 + @errors/2 + 6; for my($in, $exp) (@tests) { my $out = json_format $in; is $out, $exp; ok utf8::is_utf8($out); + + $out = json_format $in, utf8 => 1; + utf8::encode(my $uexp = $exp); + is $out, $uexp; + ok !utf8::is_utf8($out); } for my ($in, $exp) (@errors) {