Convert-RACE
view release on metacpan or search on metacpan
lib/Convert/RACE.pm view on Meta::CPAN
use constant DECOMPRESS_EXCEPTION => 'Invalid format to decompress';
my $_prefix_tag = 'bq--';
sub prefix_tag {
my $class = shift;
$_prefix_tag = $_[0] if (@_);
return $_prefix_tag;
}
sub to_race($) {
my $str = shift;
# 2.2.1 Check the input string for disallowed names
unless (_include_disallowed_names($str)) {
Carp::croak('String includes no internationalized characters');
}
# 2.2.2 Compress the pre-converted string
my $compressed = _compress($str);
lib/Convert/RACE.pm view on Meta::CPAN
Carp::croak('String too long');
}
# 2.2.4 Encode the compressed string with Base32
my $encoded = encode_base32($compressed);
# 2.2.5 Prepend "bq--" to the encoded string and finish
return $_prefix_tag . $encoded;
}
sub from_race($) {
my $str = lc(shift);
# 2.3.1 Strip the "bq--"
$str =~ s/^$_prefix_tag// or Carp::croak("String not begin with $_prefix_tag");
# 2.3.2 Decode the stripped string with Base32
my $decoded = decode_base32($str);
# 2.3.3 Decompress the decoded string
my $decompressed = _decompress($decoded);
# 2.3.4 Check the internationalized string for disallowed names
unless (_include_disallowed_names($decompressed)) {
Carp::croak('Decoded string includes no internationalized characters');
}
return $decompressed;
}
sub _compress($) {
my $str = shift;
my @unique_upper_octet = _make_uniq_upper_octet($str);
if (@unique_upper_octet > 2 ||
(@unique_upper_octet == 2 &&
! grep { $_ eq "\x00" } @unique_upper_octet)) {
# from more than 2 rows
# or from 2 rows neither of with is 0
return "\xD8" . $str;
}
lib/Convert/RACE.pm view on Meta::CPAN
$res .= "\xff\x99";
} else {
$res .= "\xff$n1";
}
}
return $res;
}
sub _decompress($) {
my $str = shift;
# 1)
my ($u1, $rest) = (substr($str,0,1), substr($str,1));
if (length($str) == 1) {
Carp::croak(DECOMPRESS_EXCEPTION);
}
if ($u1 eq "\xd8") {
# 8)
lib/Convert/RACE.pm view on Meta::CPAN
# 3)
Carp::croak(DECOMPRESS_EXCEPTION);
}
# 4)
$buffer .= $u1 . $n1;
next;
} continue { $pos++; }
}
sub _make_uniq_upper_octet($) {
my $str = shift;
my %seen;
while ($str =~ m/(.)./gs) {
$seen{$1}++;
}
return keys %seen;
}
sub _include_disallowed_names($) {
# RFC 1035: letter, digit, hyphen
return $_[0] !~ /^(?:\x00[\x30-\x39\x41-\x5a\x61-\x7a\x2d])*$/;
}
1;
__END__
=head1 NAME
( run in 0.271 second using v1.01-cache-2.11-cpan-1f129e94a17 )