#!/usr/bin/env perl # These are the examples provided in RFC 7049. use strict; use warnings; use Config; use Test::More; use Types::Serialiser (); use CBOR::PP; my $is_64bit = eval { pack 'q' }; my $weird_double_yn = $Config::Config{'uselongdouble'} || $Config::Config{'usequadmath'}; my @examples = ( [ 0 => '00' ], [ 1 => '01' ], [ 10 => '0a' ], [ 23 => '17' ], [ 24 => '1818' ], [ 25 => '1819' ], [ 100 => '1864' ], [ 1000 => '1903e8' ], [ 1000000 => '1a000f4240' ], ($is_64bit ? ( [ 1000000000000 => '1b000000e8d4a51000' ], [ 1000000000000 => '1b000000e8d4a51000' ], [ 18446744073709551615 => '1bffffffffffffffff' ], #[ -18446744073709551616 => '3bffffffffffffffff' ], ) : () ), [ Types::Serialiser::false() => 'f4' ], [ Types::Serialiser::true() => 'f5' ], [ undef, 'f6' ], # “undefined” isn’t represented [ q<> => '40' ], [ pack('U', 0xfc) => '62c3bc' ], [ "\x{6c34}" => '63e6b0b4' ], [ [] => '80' ], [ [1,2,3] => '83010203' ], [ [1, [2, 3], [4, 5]] => '8301820203820405' ], [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ], '98190102030405060708090a0b0c0d0e0f101112131415161718181819', ], [ {} => 'a0' ], ); for my $t (@examples) { is( unpack( 'H*', CBOR::PP::encode( $t->[0] ) ), $t->[1], sprintf('Encode to %s', $t->[1]), ); is_deeply( scalar( CBOR::PP::decode( pack( 'H*', $t->[1] ) ) ), $t->[0], sprintf('Decode %s', $t->[1]) ); is_deeply( scalar( CBOR::PP::decode( CBOR::PP::encode( $t->[0] ) ) ), $t->[0], sprintf("Round-trip: $t->[1]"), ); } # NB: Different perls have historically represented these values # using different strings: # - Modern perls all appear to use: inf nan -inf # - Some older perls used Inf NaN -Inf # - Others (e.g., Strawberry 5.12.2) used 1.#INF 1.#QNAN -1.#INF # - Still others (Solaris) used Infinity NaN -Infinity my $inf = unpack("f>", "\x7f\x80\x00\x00"); my $nan = unpack("f>", "\x7f\xc0\x00\x00"); my $neginf = unpack("f>", "\xff\x80\x00\x00"); my @decode = ( [ -1 => '20' ], [ -10 => '29' ], [ -100 => '3863' ], [ -1000 => '3903e7' ], # These appear to decode with no rounding errors # on long-double Perls: [ 1.5 => 'f93e00' ], [ 100000 => 'fa47c35000' ], ); if (!$weird_double_yn) { push @decode, ( [ 1.1 => 'fb3ff199999999999a' ], [ $inf => 'fa7f800000' ], [ $nan => 'fa7fc00000' ], [ $neginf => 'faff800000' ], ); if ($is_64bit) { push @decode, ( [ -4.1 => 'fbc010666666666666' ], [ $inf => 'fb7ff0000000000000' ], [ $nan => 'fb7ff8000000000000' ], [ $neginf => 'fbfff0000000000000' ], ); } } push @decode, ( [ '2013-03-21T20:04:00Z' => 'c074323031332d30332d32315432303a30343a30305a' ], [ 1363896240 => 'c11a514b67b0' ], [ 1363896240.5 => 'c1fb41d452d9ec200000' ], [ "\1\2\3\4" => "4401020304" ], [ "\1\2\3\4" => 'd74401020304' ], [ 'dIETF' => 'd818456449455446' ], [ 'http://www.example.com' => 'd82076687474703a2f2f7777772e6578616d706c652e636f6d' ], [ '' => '60' ], [ 'a' => '6161' ], [ 'IETF' => '6449455446' ], [ q<"\\> => '62225c' ], [ "\x{10151}" => '64f0908591' ], [ { 1 => 2, 3 => 4 } => 'a201020304' ], [["a", {"b" => "c"}] => '826161a161626163' ], [ {a => 1, b => [2, 3]} => 'a26161016162820203' ], [ { qw( a A b B c C d D e E ) } => 'a56161614161626142616361436164614461656145' ], [ "\1\2\3\4\5" => '5f42010243030405ff' ], [ 'streaming' => '7f657374726561646d696e67ff' ], [ [] => '9fff' ], [ [ 1, [2, 3], [4, 5]] => '9f018202039f0405ffff' ], [ [ 1, [2, 3], [4, 5]] => '9f01820203820405ff' ], [ [1, [2, 3], [4, 5]] => '83018202039f0405ff' ], [ [1, [2, 3], [4, 5]] => '83019f0203ff820405' ], [ [ 1 .. 25 ] => '9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff' ], [ { a => 1, b => [2,3] } => 'bf61610161629f0203ffff' ], [ ['a', { b => 'c' }] => '826161bf61626163ff' ], [ { Fun => Types::Serialiser::true(), Amt => -2 } => 'bf6346756ef563416d7421ff' ], ); for my $t (@decode) { my $decoded = CBOR::PP::decode( pack( 'H*', $t->[1] ) ); is_deeply( $decoded, $t->[0], sprintf('Decode %s', $t->[1]) ) or diag explain $decoded; is_deeply( scalar( CBOR::PP::decode( CBOR::PP::encode( $t->[0] ) ) ), $t->[0], sprintf("Round-trip: $t->[1]"), ); } done_testing;