use strict;
use MIME::Base64;

sub mustENC($) {
    return ( $_[0] =~ /[\x00-\x1f]/ ) || ( $_[0] =~ /[\x7f-\xff]/ );
}

sub utf7_encode($) {
    # see rfc 2060
    my $str = shift;

    my $nstr = "";
    for(my $i=0; $i<length($str); $i++) {
	my $l = substr($str,$i,1);
	if( mustENC($l) ) {
	    my $allenc = "";
	    while( mustENC($l) ) {
		$allenc .= "\0".$l;
		$l = substr($str,++$i,1);
	    }
	    $i--;
	    my $enc = encode_base64($allenc, "");
	    $enc =~ s/=//g;
	    $nstr .= "&".$enc."-";
	} elsif( $l eq "&" ) {
	    $nstr .= $l."-";
	} else {
	    $nstr .= $l;
	}
    }

    return $nstr;
}

sub utf7_decode($) {
    my $str = shift;

    my $nstr = "";
    foreach my $token ( split(/-/, $str, -1) ) {
        if( $token =~ /&/ ) {
	    $token =~ /(.*)&(.*)/;
	    if( ! defined $2 || $2 eq "" ) {
		$token = $1."&";
	    } else {
		$token = $1.decode_base64($2);
	    }
        } else {
	    $token .= "-";
        }
        $nstr .= $token;
    }
    if( substr($nstr, length($nstr)-1, 1) eq "-" ) {
        $nstr = substr($nstr,0,length($nstr)-1);
    }
    $nstr =~ s/\0//g;
    # remove binary \0 trash
    return $nstr;
}
