Cpanel-JSON-XS

 view release on metacpan or  search on metacpan

XS.pm  view on Meta::CPAN

JSON in Perl silently ignores duplicate names, using the last value
found.

See L<http://seriot.ch/projects/parsing_json.php#24>:
RFC 7159 section 4: "The names within an object should be unique."

=item $json = $json->dupkeys_as_arrayref ([$enable])

=item $enabled = $json->get_dupkeys_as_arrayref

If enabled, allow decoding of duplicate keys in hashes and store the
values as arrayref in the hash instead.  By default duplicate keys are
forbidden.  Enabling this also enables the L</allow_dupkeys> option,
but disabling this does not disable the L</allow_dupkeys> option.

Example:

    $json->dupkeys_as_arrayref;
    print encode_json ($json->decode ('{"a":"b","a":"c"}'));

      => {"a":["b","c"]}

This changes the result structure, thus cannot be enabled by default.
The client must be aware of it. The resulting arrayref is not yet marked somehow
(blessed or such).

=item $json = $json->allow_blessed ([$enable])

=item $enabled = $json->get_allow_blessed

If C<$enable> is true (or missing), then the C<encode> method will not
barf when it encounters a blessed reference. Instead, the value of the
B<convert_blessed> option will decide whether C<null> (C<convert_blessed>
disabled or no C<TO_JSON> method found) or a representation of the
object (C<convert_blessed> enabled and C<TO_JSON> method found) is being
encoded. Has no effect on C<decode>.

If C<$enable> is false (the default), then C<encode> will throw an
exception when it encounters a blessed object without C<convert_blessed>
and a C<TO_JSON> method.

This setting has no effect on C<decode>.

=item $json = $json->convert_blessed ([$enable])

=item $enabled = $json->get_convert_blessed

If C<$enable> is true (or missing), then C<encode>, upon encountering a
blessed object, will check for the availability of the C<TO_JSON> method
on the object's class. If found, it will be called in scalar context
and the resulting scalar will be encoded instead of the object. If no
C<TO_JSON> method is found, a stringification overload method is tried next.
If both are not found, the value of C<allow_blessed> will decide what
to do.

The C<TO_JSON> method may safely call die if it wants. If C<TO_JSON>
returns other blessed objects, those will be handled in the same
way. C<TO_JSON> must take care of not causing an endless recursion
cycle (== crash) in this case. The same care must be taken with
calling encode in stringify overloads (even if this works by luck in
older perls) or other callbacks.  The name of C<TO_JSON> was chosen
because other methods called by the Perl core (== not by the user of
the object) are usually in upper case letters and to avoid collisions
with any C<to_json> function or method.

If C<$enable> is false (the default), then C<encode> will not consider
this type of conversion.

This setting has no effect on C<decode>.

=item $json = $json->allow_tags ([$enable])

=item $enabled = $json->get_allow_tags

See L<OBJECT SERIALIZATION> for details.

If C<$enable> is true (or missing), then C<encode>, upon encountering a
blessed object, will check for the availability of the C<FREEZE> method on
the object's class. If found, it will be used to serialize the object into
a nonstandard tagged JSON value (that JSON decoders cannot decode).

It also causes C<decode> to parse such tagged JSON values and deserialize
them via a call to the C<THAW> method.

If C<$enable> is false (the default), then C<encode> will not consider
this type of conversion, and tagged JSON values will cause a parse error
in C<decode>, as if tags were not part of the grammar.

=item $json = $json->filter_json_object ([$coderef->($hashref)])

When C<$coderef> is specified, it will be called from C<decode> 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 deserialized data structure. If it returns
an empty list (NOTE: I<not> C<undef>, which is a valid scalar), the
original deserialized 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<decode> will not change the deserialized hash in any
way.

Example, convert all JSON objects into the integer 5:

   my $js = Cpanel::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<filter_json_object>, 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<filter_json_object>, 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<undef> but the empty list),

XS.pm  view on Meta::CPAN

e.g.:

   ("URI")["http://www.google.com/"]
   ("MyDate")[2013,10,29]
   ("ImageData::JPEG")["Z3...VlCg=="]

For example, the hypothetical C<My::Object> C<FREEZE> method might use the
objects C<type> and C<id> members to encode the object:

   sub My::Object::FREEZE {
      my ($self, $serializer) = @_;

      ($self->{type}, $self->{id})
   }

=item 2. C<convert_blessed> is enabled and the object has a C<TO_JSON> method.

In this case, the C<TO_JSON> method of the object is invoked in scalar
context. It must return a single scalar that can be directly encoded into
JSON. This scalar replaces the object in the JSON text.

For example, the following C<TO_JSON> method will convert all L<URI>
objects to JSON strings when serialized. The fact that these values
originally were L<URI> objects is lost.

   sub URI::TO_JSON {
      my ($uri) = @_;
      $uri->as_string
   }

=item 3. C<convert_blessed> is enabled and the object has a stringification overload.

In this case, the overloaded C<""> method of the object is invoked in scalar
context. It must return a single scalar that can be directly encoded into
JSON. This scalar replaces the object in the JSON text.

For example, the following C<""> method will convert all L<URI>
objects to JSON strings when serialized. The fact that these values
originally were L<URI> objects is lost.

    package URI;
    use overload '""' => sub { shift->as_string };

=item 4. C<allow_blessed> is enabled.

The object will be serialized as a JSON null value.

=item 5. none of the above

If none of the settings are enabled or the respective methods are missing,
C<Cpanel::JSON::XS> throws an exception.

=back

=head3 DESERIALIZATION

For deserialization there are only two cases to consider: either
nonstandard tagging was used, in which case C<allow_tags> decides,
or objects cannot be automatically be deserialized, in which
case you can use postprocessing or the C<filter_json_object> or
C<filter_json_single_key_object> callbacks to get some real objects our of
your JSON.

This section only considers the tagged value case: I a tagged JSON object
is encountered during decoding and C<allow_tags> is disabled, a parse
error will result (as if tagged values were not part of the grammar).

If C<allow_tags> is enabled, C<Cpanel::JSON::XS> will look up the C<THAW> method
of the package/classname used during serialization (it will not attempt
to load the package as a Perl module). If there is no such method, the
decoding will fail with an error.

Otherwise, the C<THAW> method is invoked with the classname as first
argument, the constant string C<JSON> as second argument, and all the
values from the JSON array (the values originally returned by the
C<FREEZE> method) as remaining arguments.

The method must then return the object. While technically you can return
any Perl scalar, you might have to enable the C<enable_nonref> setting to
make that work in all cases, so better return an actual blessed reference.

As an example, let's implement a C<THAW> function that regenerates the
C<My::Object> from the C<FREEZE> example earlier:

   sub My::Object::THAW {
      my ($class, $serializer, $type, $id) = @_;

      $class->new (type => $type, id => $id)
   }

See the L</SECURITY CONSIDERATIONS> section below. Allowing external
json objects being deserialized to perl objects is usually a very bad
idea.


=head1 ENCODING/CODESET FLAG NOTES

The interested reader might have seen a number of flags that signify
encodings or codesets - C<utf8>, C<latin1>, C<binary> and
C<ascii>. There seems to be some confusion on what these do, so here
is a short comparison:

C<utf8> controls whether the JSON text created by C<encode> (and expected
by C<decode>) is UTF-8 encoded or not, while C<latin1> and C<ascii> only
control whether C<encode> escapes character values outside their respective
codeset range. Neither of these flags conflict with each other, although
some combinations make less sense than others.

Care has been taken to make all flags symmetrical with respect to
C<encode> and C<decode>, that is, texts encoded with any combination of
these flag values will be correctly decoded when the same flags are used
- in general, if you use different flag settings while encoding vs. when
decoding you likely have a bug somewhere.

Below comes a verbose discussion of these flags. Note that a "codeset" is
simply an abstract set of character-codepoint pairs, while an encoding
takes those codepoint numbers and I<encodes> them, in our case into
octets. Unicode is (among other things) a codeset, UTF-8 is an encoding,
and ISO-8859-1 (= latin 1) and ASCII are both codesets I<and> encodings at
the same time, which can be confusing.



( run in 0.637 second using v1.01-cache-2.11-cpan-140bd7fdf52 )