Algorithm-GDiffDelta
view release on metacpan or search on metacpan
compile_gdiff view on Meta::CPAN
#!/usr/bin/perl -w
use strict;
use Carp;
# This little program generates GDIFF files from textual version of the
# format. It's only intended purpose is for generating test files for
# this module. See t/data/*.gdiff.txt for example input files.
my %DATA_OPCODE = (
ushort => "\xF7",
int => "\xF8",
);
my %COPY_OPCODE = (
ushort_ubyte => "\xF9",
ushort_ushort => "\xFA",
ushort_int => "\xFB",
int_ubyte => "\xFC",
int_ushort => "\xFD",
int_int => "\xFE",
long_int => "\xFF",
);
binmode STDOUT or die "error setting stdout to binmode: $!";
# The header is always the same.
print "\xD1\xFF\xD1\xFF\x04";
while (<>) {
chomp;
next unless /\S/;
next if /^\s*#/;
my ($opcode, @arg) = split ' ';
@arg = map { parse_arg($_) } @arg;
if ($opcode =~ /^data_(\d+)$/i) {
my $n = $1;
die "line $.: bad 'data_N' command\n"
unless $n >= 1 && $n <= 246 && @arg == 1;
die "line $.: wrong amount of data in 'data_N' command\n"
unless length $arg[0] == $n;
print chr($n), $arg[0];
}
elsif ($opcode =~ /^data_(ushort|int)$/i) {
my $len_type = lc $1;
die "line $.: wrong number of args\n" unless @arg == 2;
die "line $.: wrong amount of data in second arg\n"
unless $arg[0] == length $arg[1];
print $DATA_OPCODE{$len_type};
write_num($len_type, $arg[0]);
print $arg[1];
}
elsif ($opcode =~ /^copy_(ushort|int|long)_(ubyte|ushort|int)$/i) {
my $offset_type = lc $1;
my $len_type = lc $2;
die "line $.: wrong number of args\n" unless @arg == 2;
print $COPY_OPCODE{"${offset_type}_$len_type"};
write_num($offset_type, $arg[0]);
write_num($len_type, $arg[1]);
}
else {
die "line $.: unrecognized command '$opcode'\n";
}
}
# EOF opcode.
print "\x00";
sub parse_arg
{
local $_ = shift;
if (/^"(.*)"\z/) {
$_ = $1;
s/\\n/\n/g;
return $_;
}
elsif (/^0x[\dA-F]+\z/i || /^0\d+\z/) {
return oct;
}
elsif (/^(\d+)\z/) {
return $1;
}
( run in 0.456 second using v1.01-cache-2.11-cpan-3d66aa2751a )