@@ -588,3 +588,137 @@ class HotY; end
588588
589589 assert_raise ( IndexError ) { lazy . at_pointer ( "/a/999" ) }
590590end
591+
592+ assert ( "MessagePack::TimestampExt roundtrip" ) do
593+ # 32-bit format: nsec = 0, sec < 2^32
594+ t32 = Time . at ( 1_234_567_890 , 0 )
595+ packed = MessagePack . pack ( t32 )
596+ unpacked = MessagePack . unpack ( packed )
597+ assert_equal t32 . to_i , unpacked . to_i
598+ assert_equal t32 . nsec , unpacked . nsec
599+
600+ # 64-bit format: sec < 2^34, nsec < 1e9
601+ t64 = Time . at ( ( 1 << 33 ) + 123 , 456_789 )
602+ packed = MessagePack . pack ( t64 )
603+ unpacked = MessagePack . unpack ( packed )
604+ assert_equal t64 . to_i , unpacked . to_i
605+ assert_equal t64 . nsec , unpacked . nsec
606+
607+ # 96-bit format: sec >= 2^34
608+ t96 = Time . at ( ( 1 << 40 ) + 5 , 123_456 )
609+ packed = MessagePack . pack ( t96 )
610+ unpacked = MessagePack . unpack ( packed )
611+ assert_equal t96 . to_i , unpacked . to_i
612+ assert_equal t96 . nsec , unpacked . nsec
613+
614+ # negative times → always 96-bit
615+ tneg = Time . at ( -123456789 , 987654 )
616+ packed = MessagePack . pack ( tneg )
617+ unpacked = MessagePack . unpack ( packed )
618+ assert_equal tneg . to_i , unpacked . to_i
619+ assert_equal tneg . nsec , unpacked . nsec
620+
621+
622+ # registering a packer for Time must raise
623+ assert_raise ( RangeError ) do
624+ MessagePack . register_pack_type ( -1 , Time ) { |t | "nope" }
625+ end
626+ end
627+
628+ assert ( "MessagePack::TimestampExt: 32/64/96-bit formats" ) do
629+ #
630+ # 32‑bit timestamp (fixext 4)
631+ # sec fits in uint32, nsec == 0
632+ #
633+ t32 = Time . at ( 1454932800 , 0 ) # 2016-02-08 12:00:00 UTC
634+ vec32 = MessagePack . pack ( t32 )
635+ assert_equal 6 , vec32 . bytesize
636+ assert_equal 0xd6 , vec32 . bytes [ 0 ] # fixext 4
637+ assert_equal 0xff , vec32 . bytes [ 1 ] # type -1
638+ t32u = MessagePack . unpack ( vec32 )
639+ assert_equal t32 . to_i , t32u . to_i
640+ assert_equal t32 . nsec , t32u . nsec
641+
642+ #
643+ # 64‑bit timestamp (fixext 8)
644+ # sec < 2^34, nsec < 1e9, but nsec != 0
645+ #
646+ t64 = Time . at ( 1454932800 , 123_456 ) # force 64-bit (nsec != 0)
647+ vec64 = MessagePack . pack ( t64 )
648+ assert_equal 10 , vec64 . bytesize
649+ assert_equal 0xd7 , vec64 . bytes [ 0 ] # fixext 8
650+ assert_equal 0xff , vec64 . bytes [ 1 ] # type -1
651+ t64u = MessagePack . unpack ( vec64 )
652+ assert_equal t64 . to_i , t64u . to_i
653+ assert_equal t64 . nsec , t64u . nsec
654+
655+ #
656+ # 96‑bit timestamp (ext 12)
657+ # sec >= 2^34 OR negative OR nsec >= 1e9
658+ #
659+ t96 = Time . at ( ( 1 << 40 ) + 5 , 987_654 ) # sec forces 96-bit
660+ vec96 = MessagePack . pack ( t96 )
661+ assert_equal 15 , vec96 . bytesize
662+ assert_equal 0xc7 , vec96 . bytes [ 0 ] # ext 8/16/32 header
663+ assert_equal 0x0c , vec96 . bytes [ 1 ] # 12 bytes body
664+ assert_equal 0xff , vec96 . bytes [ 2 ] # type -1
665+ t96u = MessagePack . unpack ( vec96 )
666+ assert_equal t96 . to_i , t96u . to_i
667+ assert_equal t96 . nsec , t96u . nsec
668+ end
669+
670+ assert ( "MessagePack::TimestampExt vectors from file" ) do
671+ path = File . join ( File . dirname ( __FILE__ ) , "timestamp_vectors.bin" )
672+ data = File . read ( path )
673+
674+ # Die Datei enthält:
675+ # ts32_body (4 bytes)
676+ # ts64_body (8 bytes)
677+ # ts96_body (12 bytes)
678+ #
679+ # Reihenfolge exakt wie im Python-Script
680+
681+ off = 0
682+
683+ # --- 32-bit Timestamp ---
684+ body32 = data [ off , 4 ]
685+ off += 4
686+
687+ vec32 = [
688+ 0xD6 , # fixext 4
689+ 0xFF # type -1
690+ ] . pack ( "C*" ) + body32
691+
692+ t32 = MessagePack . unpack ( vec32 )
693+ assert_equal 1 , t32 . to_i
694+ assert_equal 0 , t32 . nsec
695+
696+
697+ # --- 64-bit Timestamp ---
698+ body64 = data [ off , 8 ]
699+ off += 8
700+
701+ vec64 = [
702+ 0xD7 , # fixext 8
703+ 0xFF # type -1
704+ ] . pack ( "C*" ) + body64
705+
706+ t64 = MessagePack . unpack ( vec64 )
707+ assert_equal 1 , t64 . to_i
708+ assert_equal 500_000_000 , t64 . nsec
709+
710+
711+ # --- 96-bit Timestamp ---
712+ body96 = data [ off , 12 ]
713+ off += 12
714+
715+ vec96 = [
716+ 0xC7 , # ext
717+ 0x0C , # size = 12
718+ 0xFF # type -1
719+ ] . pack ( "C*" ) + body96
720+
721+ t96 = MessagePack . unpack ( vec96 )
722+ assert_equal ( -1 , t96 . to_i )
723+ assert_equal 999_999_000 , t96 . nsec
724+ end
0 commit comments