--- CBOR-XS/XS.pm 2020/11/29 21:32:01 1.71 +++ CBOR-XS/XS.pm 2022/12/19 20:31:33 1.87 @@ -66,7 +66,7 @@ use common::sense; -our $VERSION = 1.71; +our $VERSION = 1.86; our @ISA = qw(Exporter); our @EXPORT = qw(encode_cbor decode_cbor); @@ -123,6 +123,7 @@ my $cbor = CBOR::XS ->new + ->validate_utf8 ->forbid_objects ->filter (\&CBOR::XS::safe_filter) ->max_size (1e8); @@ -135,6 +136,7 @@ sub new_safe { CBOR::XS ->new + ->validate_utf8 ->forbid_objects ->filter (\&CBOR::XS::safe_filter) ->max_size (1e8) @@ -473,7 +475,7 @@ if a full CBOR object is available, but is much more efficient. It basically works by parsing as much of a CBOR string as possible - if -the CBOR data is not complete yet, the pasrer will remember where it was, +the CBOR data is not complete yet, the parser will remember where it was, to be able to restart when more data has been accumulated. Once enough data is available to either decode a complete CBOR value or raise an error, a real decode will be attempted. @@ -635,8 +637,7 @@ =item Types::Serialiser::true, Types::Serialiser::false, Types::Serialiser::error These special values become CBOR true, CBOR false and CBOR undefined -values, respectively. You can also use C<\1>, C<\0> and C<\undef> directly -if you want. +values, respectively. =item other blessed objects @@ -706,7 +707,7 @@ =head2 TYPE CASTS B: As an experimental extension, C allows you to -force specific cbor types to be used when encoding. That allows you to +force specific CBOR types to be used when encoding. That allows you to encode types not normally accessible (e.g. half floats) as well as force string types even when C is in effect. @@ -714,10 +715,16 @@ copy of the value and returns a new value that can be handed over to any CBOR encoder function. -The following casts are currently available (all of which are unary operators): +The following casts are currently available (all of which are unary +operators, that is, have a prototype of C<$>): =over +=item CBOR::XS::as_int $value + +Forces the value to be encoded as some form of (basic, not bignum) integer +type. + =item CBOR::XS::as_text $value Forces the value to be encoded as (UTF-8) text values. @@ -726,6 +733,18 @@ Forces the value to be encoded as a (binary) string value. +Example: encode a perl string as binary even though C is in +effect. + + CBOR::XS->new->text_strings->encode ([4, "text", CBOR::XS::bytes "bytevalue"]); + +=item CBOR::XS::as_bool $value + +Converts a Perl boolean (which can be any kind of scalar) into a CBOR +boolean. Strictly the same, but shorter to write, than: + + $value ? Types::Serialiser::true : Types::Serialiser::false + =item CBOR::XS::as_float16 $value Forces half-float (IEEE 754 binary16) encoding of the given value. @@ -738,29 +757,53 @@ Forces double-float (IEEE 754 binary64) encoding of the given value. -=item, CBOR::XS::as_cbor $cbor_text +=item CBOR::XS::as_cbor $cbor_text -Bot a type cast per-se, this type cast forces the argument to eb encoded +Not a type cast per-se, this type cast forces the argument to be encoded as-is. This can be used to embed pre-encoded CBOR data. Note that no checking on the validity of the C<$cbor_text> is done - it's the callers responsibility to correctly encode values. -=back +=item CBOR::XS::as_map [key => value...] -Example: encode a perl string as binary even though C is in -effect. +Treat the array reference as key value pairs and output a CBOR map. This +allows you to generate CBOR maps with arbitrary key types (or, if you +don't care about semantics, duplicate keys or pairs in a custom order), +which is otherwise hard to do with Perl. - CBOR::XS->new->text_strings->encode ([4, "text", CBOR::XS::bytes "bytevalue"]); +The single argument must be an array reference with an even number of +elements. + +Note that only the reference to the array is copied, the array itself is +not. Modifications done to the array before calling an encoding function +will be reflected in the encoded output. + +Example: encode a CBOR map with a string and an integer as keys. + + encode_cbor CBOR::XS::as_map [string => "value", 5 => "value"] + +=back =cut sub CBOR::XS::as_cbor ($) { bless [$_[0], 0, undef], CBOR::XS::Tagged:: } -sub CBOR::XS::as_bytes ($) { bless [$_[0], 1, undef], CBOR::XS::Tagged:: } -sub CBOR::XS::as_text ($) { bless [$_[0], 2, undef], CBOR::XS::Tagged:: } -sub CBOR::XS::as_float16 ($) { bless [$_[0], 3, undef], CBOR::XS::Tagged:: } -sub CBOR::XS::as_float32 ($) { bless [$_[0], 4, undef], CBOR::XS::Tagged:: } -sub CBOR::XS::as_float64 ($) { bless [$_[0], 5, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_int ($) { bless [$_[0], 1, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_bytes ($) { bless [$_[0], 2, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_text ($) { bless [$_[0], 3, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_float16 ($) { bless [$_[0], 4, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_float32 ($) { bless [$_[0], 5, undef], CBOR::XS::Tagged:: } +sub CBOR::XS::as_float64 ($) { bless [$_[0], 6, undef], CBOR::XS::Tagged:: } + +sub CBOR::XS::as_bool ($) { $_[0] ? $Types::Serialiser::true : $Types::Serialiser::false } + +sub CBOR::XS::as_map ($) { + ARRAY:: eq ref $_[0] + and $#{ $_[0] } & 1 + or do { require Carp; Carp::croak ("CBOR::XS::as_map only acepts array references with an even number of elements, caught") }; + + bless [$_[0], 7, undef], CBOR::XS::Tagged:: +} =head2 OBJECT SERIALISATION