--- JSON-XS/XS.pm 2007/07/02 00:29:38 1.50 +++ JSON-XS/XS.pm 2007/10/11 23:57:24 1.64 @@ -1,7 +1,12 @@ +=encoding utf-8 + =head1 NAME JSON::XS - JSON serialising/deserialising, done correctly and fast +JSON::XS - 正しくて高速な JSON シリアライザ/デシリアライザ + (http://fleur.hio.jp/perldoc/mix/lib/JSON/XS.html) + =head1 SYNOPSIS use JSON::XS; @@ -83,7 +88,7 @@ use strict; -our $VERSION = '1.4'; +our $VERSION = '1.5'; our @ISA = qw(Exporter); our @EXPORT = qw(to_json from_json); @@ -100,9 +105,8 @@ =item $json_text = to_json $perl_scalar -Converts the given Perl data structure (a simple scalar or a reference to -a hash or array) to a UTF-8 encoded, binary string (that is, the string contains -octets only). Croaks on error. +Converts the given Perl data structure to a UTF-8 encoded, binary string +(that is, the string contains octets only). Croaks on error. This function call is functionally identical to: @@ -112,9 +116,9 @@ =item $perl_scalar = from_json $json_text -The opposite of C: expects an UTF-8 (binary) string and tries to -parse that as an UTF-8 encoded JSON text, returning the resulting simple -scalar or reference. Croaks on error. +The opposite of C: expects an UTF-8 (binary) string and tries +to parse that as an UTF-8 encoded JSON text, returning the resulting +reference. Croaks on error. This function call is functionally identical to: @@ -134,6 +138,54 @@ =back +=head1 A FEW NOTES ON UNICODE AND PERL + +Since this often leads to confusion, here are a few very clear words on +how Unicode works in Perl, modulo bugs. + +=over 4 + +=item 1. Perl strings can store characters with ordinal values > 255. + +This enables you to store unicode characters as single characters in a +Perl string - very natural. + +=item 2. Perl does I associate an encoding with your strings. + +Unless you force it to, e.g. when matching it against a regex, or printing +the scalar to a file, in which case Perl either interprets your string as +locale-encoded text, octets/binary, or as Unicode, depending on various +settings. In no case is an encoding stored together with your data, it is +I that decides encoding, not any magical metadata. + +=item 3. The internal utf-8 flag has no meaning with regards to the +encoding of your string. + +Just ignore that flag unless you debug a Perl bug, a module written in +XS or want to dive into the internals of perl. Otherwise it will only +confuse you, as, despite the name, it says nothing about how your string +is encoded. You can have unicode strings with that flag set, with that +flag clear, and you can have binary data with that flag set and that flag +clear. Other possibilities exist, too. + +If you didn't know about that flag, just the better, pretend it doesn't +exist. + +=item 4. A "Unicode String" is simply a string where each character can be +validly interpreted as a Unicode codepoint. + +If you have UTF-8 encoded data, it is no longer a Unicode string, but a +Unicode string encoded in UTF-8, giving you a binary string. + +=item 5. A string containing "high" (> 255) character values is I a UTF-8 string. + +Its a fact. Learn to live with it. + +=back + +I hope this helps :) + + =head1 OBJECT-ORIENTED INTERFACE The object oriented interface lets you configure your own encoding or @@ -280,6 +332,51 @@ {"key": "value"} +=item $json = $json->relaxed ([$enable]) + +If C<$enable> is true (or missing), then C will accept some +extensions to normal JSON syntax (see below). C will not be +affected in anyway. I. I suggest only to use this option to +parse application-specific files written by humans (configuration files, +resource files etc.) + +If C<$enable> is false (the default), then C will only accept +valid JSON texts. + +Currently accepted extensions are: + +=over 4 + +=item * list items can have an end-comma + +JSON I array elements and key-value pairs with commas. This +can be annoying if you write JSON texts manually and want to be able to +quickly append elements, so this extension accepts comma at the end of +such items not just between them: + + [ + 1, + 2, <- this comma not normally allowed + ] + { + "k1": "v1", + "k2": "v2", <- this comma not normally allowed + } + +=item * shell-style '#'-comments + +Whenever JSON allows whitespace, shell-style comments are additionally +allowed. They are terminated by the first carriage-return or line-feed +character, after which more white-space and comments are allowed. + + [ + 1, # this comment not allowed in JSON + # neither this one... + ] + +=back + =item $json = $json->canonical ([$enable]) If C<$enable> is true (or missing), then the C method will output JSON objects @@ -350,6 +447,82 @@ If C<$enable> is false, then the C setting will decide what to do when a blessed object is found. +=item $json = $json->filter_json_object ([$coderef->($hashref)]) + +When C<$coderef> is specified, it will be called from C each +time it decodes a JSON object. The only argument is a reference to the +newly-created hash. If the code references returns a single scalar (which +need not be a reference), this value (i.e. a copy of that scalar to avoid +aliasing) is inserted into the deserialised data structure. If it returns +an empty list (NOTE: I C, which is a valid scalar), the +original deserialised hash will be inserted. This setting can slow down +decoding considerably. + +When C<$coderef> is omitted or undefined, any existing callback will +be removed and C will not change the deserialised hash in any +way. + +Example, convert all JSON objects into the integer 5: + + my $js = JSON::XS->new->filter_json_object (sub { 5 }); + # returns [5] + $js->decode ('[{}]') + # throw an exception because allow_nonref is not enabled + # so a lone 5 is not allowed. + $js->decode ('{"a":1, "b":2}'); + +=item $json = $json->filter_json_single_key_object ($key [=> $coderef->($value)]) + +Works remotely similar to C, but is only called for +JSON objects having a single key named C<$key>. + +This C<$coderef> is called before the one specified via +C, if any. It gets passed the single value in the JSON +object. If it returns a single value, it will be inserted into the data +structure. If it returns nothing (not even C but the empty list), +the callback from C will be called next, as if no +single-key callback were specified. + +If C<$coderef> is omitted or undefined, the corresponding callback will be +disabled. There can only ever be one callback for a given key. + +As this callback gets called less often then the C +one, decoding speed will not usually suffer as much. Therefore, single-key +objects make excellent targets to serialise Perl objects into, especially +as single-key JSON objects are as close to the type-tagged value concept +as JSON gets (its basically an ID/VALUE tuple). Of course, JSON does not +support this in any way, so you need to make sure your data never looks +like a serialised Perl hash. + +Typical names for the single object key are C<__class_whatever__>, or +C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even +things like C<__class_md5sum(classname)__>, to reduce the risk of clashing +with real hashes. + +Example, decode JSON objects of the form C<< { "__widget__" => } >> +into the corresponding C<< $WIDGET{} >> object: + + # return whatever is in $WIDGET{5}: + JSON::XS + ->new + ->filter_json_single_key_object (__widget__ => sub { + $WIDGET{ $_[0] } + }) + ->decode ('{"__widget__": 5') + + # this can be used with a TO_JSON method in some "widget" class + # for serialisation to json: + sub WidgetBase::TO_JSON { + my ($self) = @_; + + unless ($self->{id}) { + $self->{id} = ..get..some..id..; + $WIDGET{$self->{id}} = $self; + } + + { __widget__ => $self->{id} } + } + =item $json = $json->shrink ([$enable]) Perl usually over-allocates memory a bit when allocating space for @@ -479,11 +652,23 @@ =item number -A JSON number becomes either an integer or numeric (floating point) -scalar in perl, depending on its range and any fractional parts. On the -Perl level, there is no difference between those as Perl handles all the -conversion details, but an integer may take slightly less memory and might -represent more values exactly than (floating point) numbers. +A JSON number becomes either an integer, numeric (floating point) or +string scalar in perl, depending on its range and any fractional parts. On +the Perl level, there is no difference between those as Perl handles all +the conversion details, but an integer may take slightly less memory and +might represent more values exactly than (floating point) numbers. + +If the number consists of digits only, JSON::XS will try to represent +it as an integer value. If that fails, it will try to represent it as +a numeric (floating point) value if that is possible without loss of +precision. Otherwise it will preserve the number as a string value. + +Numbers containing a fractional or exponential part will always be +represented as numeric (floating point) values, possibly at a loss of +precision. + +This might create round-tripping problems as numbers might become strings, +but as Perl is typeless there is no other way to do it. =item true, false @@ -535,7 +720,7 @@ =item JSON::XS::true, JSON::XS::false These special values become JSON true and JSON false values, -respectively. You cna alos use C<\1> and C<\0> directly if you want. +respectively. You can also use C<\1> and C<\0> directly if you want. =item blessed objects @@ -795,6 +980,16 @@ right). +=head1 THREADS + +This module is I guarenteed to be thread safe and there are no +plans to change this until Perl gets thread support (as opposed to the +horribly slow so-called "threads" which are simply slow and bloated +process simulations - use fork, its I faster, cheaper, better). + +(It might actually work, but you ahve ben warned). + + =head1 BUGS While the goal of this module is to be correct, that unfortunately does @@ -802,10 +997,13 @@ still relatively early in its development. If you keep reporting bugs they will be fixed swiftly, though. +Please refrain from using rt.cpan.org or any other bug reporting +service. I put the contact address into my modules for a reason. + =cut -our $true = do { bless \(my $dummy = "1"), "JSON::XS::Boolean" }; -our $false = do { bless \(my $dummy = "0"), "JSON::XS::Boolean" }; +our $true = do { bless \(my $dummy = 1), "JSON::XS::Boolean" }; +our $false = do { bless \(my $dummy = 0), "JSON::XS::Boolean" }; sub true() { $true } sub false() { $false }