Cpanel-JSON-XS

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

        die when it encounters duplicate keys in a hash. "allow_dupkeys" is
        also enabled in the "relaxed" mode.

        The JSON spec allows duplicate name in objects but recommends to
        disable it, however with Perl hashes they are impossible, parsing
        JSON in Perl silently ignores duplicate names, using the last value
        found.

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

    $json = $json->dupkeys_as_arrayref ([$enable])
    $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 "allow_dupkeys"
        option, but disabling this does not disable the "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).

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

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

        This setting has no effect on "decode".

    $json = $json->convert_blessed ([$enable])
    $enabled = $json->get_convert_blessed
        If $enable is true (or missing), then "encode", upon encountering a
        blessed object, will check for the availability of the "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 "TO_JSON" method is found, a stringification overload
        method is tried next. If both are not found, the value of
        "allow_blessed" will decide what to do.

        The "TO_JSON" method may safely call die if it wants. If "TO_JSON"
        returns other blessed objects, those will be handled in the same
        way. "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 "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 "to_json" function or method.

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

        This setting has no effect on "decode".

    $json = $json->allow_tags ([$enable])
    $enabled = $json->get_allow_tags
        See "OBJECT SERIALIZATION" for details.

        If $enable is true (or missing), then "encode", upon encountering a
        blessed object, will check for the availability of the "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 "decode" to parse such tagged JSON values and
        deserialize them via a call to the "THAW" method.

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

    $json = $json->filter_json_object ([$coderef->($hashref)])
        When $coderef is specified, it will be called from "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: *not* "undef",
        which is a valid scalar), the original deserialized hash will be
        inserted. This setting can slow down decoding considerably.

        When $coderef is omitted or undefined, any existing callback will be
        removed and "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}');

    $json = $json->filter_json_single_key_object ($key [=>
    $coderef->($value)])
        Works remotely similar to "filter_json_object", but is only called
        for JSON objects having a single key named $key.

        This $coderef is called before the one specified via
        "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 "undef" but the
        empty list), the callback from "filter_json_object" will be called
        next, as if no single-key callback were specified.

README  view on Meta::CPAN

        The "FREEZE" method can return any number of values (i.e. zero or
        more). These values and the paclkage/classname of the object will
        then be encoded as a tagged JSON value in the following format:

           ("classname")[FREEZE return values...]

        e.g.:

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

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

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

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

    2. "convert_blessed" is enabled and the object has a "TO_JSON" method.
        In this case, the "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 "TO_JSON" method will convert all URI
        objects to JSON strings when serialized. The fact that these values
        originally were URI objects is lost.

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

    3. "convert_blessed" is enabled and the object has a stringification
    overload.
        In this case, the overloaded "" 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 "" method will convert all URI objects to
        JSON strings when serialized. The fact that these values originally
        were URI objects is lost.

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

    4. "allow_blessed" is enabled.
        The object will be serialized as a JSON null value.

    5. none of the above
        If none of the settings are enabled or the respective methods are
        missing, "Cpanel::JSON::XS" throws an exception.

   DESERIALIZATION
    For deserialization there are only two cases to consider: either
    nonstandard tagging was used, in which case "allow_tags" decides, or
    objects cannot be automatically be deserialized, in which case you can
    use postprocessing or the "filter_json_object" or
    "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 "allow_tags" is disabled, a
    parse error will result (as if tagged values were not part of the
    grammar).

    If "allow_tags" is enabled, "Cpanel::JSON::XS" will look up the "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 "THAW" method is invoked with the classname as first
    argument, the constant string "JSON" as second argument, and all the
    values from the JSON array (the values originally returned by the
    "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 "enable_nonref" setting to
    make that work in all cases, so better return an actual blessed
    reference.

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

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

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

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

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

    "utf8" controls whether the JSON text created by "encode" (and expected
    by "decode") is UTF-8 encoded or not, while "latin1" and "ascii" only
    control whether "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
    "encode" and "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 *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 *and*
    encodings at the same time, which can be confusing.

    "utf8" flag disabled



( run in 0.738 second using v1.01-cache-2.11-cpan-39bf76dae61 )