- 论坛徽章:
- 0
|
unpack和pack不是很难理解的!
不知道是自己的习惯还是真的阅读能力上有问题。我认为好的/有可读性的代码是从变量命名就开始做起的。大量无意义的变量名,令人很头痛。即使我能像机器一样分析出代码执行的结果,但那时对于代码的物理理解,不是对于它解决问题的算法的理解。最近我在用perl重写CNPRINT,一个中国人写得很好的一个解决UNIX下汉字/日文/韩文打印的程序。他的源代码是公布出来的,但是可读性很差。我不能责备他,因为这只是一个医学博士的业余爱好而已。不过,这么好的解决方法没有被推广和被主流linux用于解决CJK打印很大程度上由于代码的可读性。我之所以要用perl重写是想有人能看懂我代码后再用C改写成功能更强大的代码。下面是我代码的片断。可能很不perl化。但是很容易读懂。
<CODE>
#!/usr/bin/perl -w
our @ParameterList;
our $ValidParameters="SioHtc";
our $DEBUG=1;
our $SILENT=0;
our @Input;
our @InputBuff;
our @Output;
our @OutputBuff;
our $Language="auto";
our @CodeTypes=("shiftjis","gb2312","big5","gbk","jis");
our @CharUsage;
our $InUseCode;
sub convert2Unicode
{
my $code=shift;
my $code_type=shift;
local $FileName;
local $CodeType;
foreach $CodeType (@CodeTypes)
{
$FileName="/CNPRN/CODE/".$CodeType.".txt";
next if (($code_type ne "auto") and ($CodeType ne $code_type));
if (!(open(CodeFile,$FileName)))
{
print STDERR "Unicode covert file open error of codetype $CodeType!\nPlease check the file path $FileName!\n";
return 0 if ($code_type ne "auto");
}
my @FileBuff=<CodeFile>;
close(CodeFile);
foreach my $LineBuff (@FileBuff)
{
next if ($LineBuff!~/^0[xX]/);
chomp $LineBuff;
($Code,$Unicode)=(split(/\t/,$LineBuff));
if ($code==hex($Code))
{
$InUseCode=$CodeType;
close(CodeFile);
return hex($Unicode);
}
}
}
return 0;
}
sub updateCharUsage
{
my $Code=shift;
local $i;
for($i=0;$i<@CharUsage;$i++)
{
last if ($CharUsage[$i]{Code}==$Code);
}
$CharUsage[$i]{Code}=$Code;
$CharUsage[$i]{Freq}++;
$CharUsage[$i]{CodeType}=$InUseCode;
}
sub getCharFreq
{
my $Code=shift;
local $i;
for($i=0;$i<@CharUsage;$i++)
{
return $CharUsage[$i]{Freq} if ($CharUsage[$i]{Code}==$Code);
}
return 0;
}
sub getCharOrd
{
my $Code=shift;
local $i;
for($i=0;$i<@CharUsage;$i++)
{
return $i if ($CharUsage[$i]{Code}==$Code);
}
return -1;
}
sub errorHandler
{
my $ErrorMsg=shift;
my @ErrorPrg=caller;
my $DisplayMsg=($SILENT==0)?$ErrorMsg."\n".($DEBUG?"In function $ErrorPrg[0]() of file $ErrorPrg[1] at line #$ErrorPrg[2].\n":""):"";
system("time /T");
die($DisplayMsg);
}
sub getParameterValue
{
my $Item=shift;
for(my $i=0;$i<@ParameterList;$i++)
{
return $ParameterList[$i]{"Value"} if ($ParameterList[$i]{"Parameter"} eq $Item);
}
return -1;
}
sub getInput
{
my $FileName=getParameterValue("i");
if (length($FileName)==0)
{
errorHandler("Can not open the STANDARD or PIPE\n") if (!(open(INPUT,STDIN)));
}
else
{
errorHandler("Can not open the input file $FileName\n") if (!(open(INPUT,$FileName)));
}
@InputBuff=<INPUT>;
close(INPUT);
}
sub unicodeFile
{
local $Index;
for($Index=0;$Index<@InputBuff;$Index++)
{
local $LineBuff=$InputBuff[$Index];
chomp $LineBuff;
local $Counter=1;
for(my $SubIndex=0;$SubIndex<length($LineBuff);$SubIndex++)
{
local $BinaryCode=ord(substr($LineBuff,$SubIndex,1));
local $Unicode;
$Unicode=convert2Unicode($BinaryCode,$Language);
updateCharUsage($Unicode) if (($Unicode!=$BinaryCode) and ($Unicode!=0));
if ($Unicode==0)
{
$SubIndex++;
$BinaryCode=$BinaryCode*256+ord(substr($LineBuff,$SubIndex,1)) ;
$Unicode=convert2Unicode($BinaryCode,$Language);
}
errorHandler("Can not convert $Language code $BinaryCode to Unicode, which is located in line $Index column $SubIndex!\n") if ($Unicode==0);
$Input[$Index][$Counter]=$Unicode;
updateCharUsage($Unicode);
$Counter++;
}
$Input[$Index][0]=$Counter-1;
}
}
</CODE> |
|