+=func int64
+
+ $int = int64($string);
+
+Get a scalar integer capable of holding 64-bit values, initialized with a given default value. On a 64-bit
+perl, it will return a regular SvIV. On a 32-bit perl it will return a L<Math::BigInt>.
+
+=cut
+
+sub int64 {
+ require Config;
+ if ($Config::Config{ivsize} < 8) {
+ require Math::BigInt;
+ return Math::BigInt->new(@_);
+ }
+ return 0 + shift;
+}
+
+=func pack_Ql
+
+ $bytes = pack_Ql($int);
+
+Like C<pack('QE<lt>', $int)>, but also works on 32-bit perls.
+
+=cut
+
+sub pack_Ql {
+ my $num = shift;
+ require Config;
+ if ($Config::Config{ivsize} < 8) {
+ if (blessed $num && $num->can('to_hex')) {
+ return "\xff\xff\xff\xff\xff\xff\xff\xff" if Math::BigInt->new('18446744073709551615') <= $num;
+ return "\x00\x00\x00\x00\x00\x00\x00\x80" if $num <= Math::BigInt->new('-9223372036854775808');
+ my $neg;
+ if ($num < 0) {
+ $neg = 1;
+ $num = -$num;
+ }
+ my $bytes = reverse pack('H16', substr(('0' x 15) . $num->to_hex, -16));
+ $bytes .= "\0" x (8 - length $bytes) if length $bytes < 8;
+ if ($neg) {
+ # two's compliment
+ $bytes = join('', map { chr(~ord($_) & 0xff) } split(//, $bytes));
+ substr($bytes, 0, 1, chr(ord(substr($bytes, 0, 1)) + 1));
+ }
+ return $bytes;
+ }
+ else {
+ my $pad = $num < 0 ? "\xff" : "\0";
+ return pack('L<', $num) . ($pad x 4);
+ };
+ }
+ return pack('Q<', $num);
+}
+
+=func pack_ql
+
+ $bytes = pack_ql($int);