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 )