/[Biblio-Isis]/trunk/lib/Biblio/Isis.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/lib/Biblio/Isis.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3 by dpavlin, Tue Dec 28 01:48:44 2004 UTC revision 11 by dpavlin, Wed Dec 29 17:03:52 2004 UTC
# Line 7  use Data::Dumper; Line 7  use Data::Dumper;
7  BEGIN {  BEGIN {
8          use Exporter ();          use Exporter ();
9          use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);          use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
10          $VERSION     = 0.01;          $VERSION     = 0.03;
11          @ISA         = qw (Exporter);          @ISA         = qw (Exporter);
12          #Give a hoot don't pollute, do not export more than needed by default          #Give a hoot don't pollute, do not export more than needed by default
13          @EXPORT      = qw ();          @EXPORT      = qw ();
# Line 22  IsisDB - Read CDS/ISIS database Line 22  IsisDB - Read CDS/ISIS database
22    
23  =head1 SYNOPSIS  =head1 SYNOPSIS
24    
25    use IsisDB    use IsisDB;
26    
27    my $isis = new IsisDB(    my $isis = new IsisDB(
28          isisdb => './cds/cds',          isisdb => './cds/cds',
29    );    );
30    
31      for(my $mfn = 1; $mfn <= $isis->{'maxmfn'}; $mfn++) {
32            print $isis->to_ascii($mfn),"\n";
33      }
34    
35  =head1 DESCRIPTION  =head1 DESCRIPTION
36    
37  This module will read CDS/ISIS databases and create hash values out of it.  This module will read CDS/ISIS databases and create hash values out of it.
38  It can be used as perl-only alternative to OpenIsis module.  It can be used as perl-only alternative to OpenIsis module.
39    
40    This will module will always be slower that OpenIsis module which use C
41    library. However, since it's written in perl, it's platform independent (so
42    you don't need C compiler), and can be easily modified.
43    
44    Unique feature of this module is ability to C<include_deleted> records.
45    It will also skip zero sized fields (OpenIsis has a bug in XS bindings, so
46    fields which are zero sized will be filled with random junk from memory).
47    
48  =head1 METHODS  =head1 METHODS
49    
50  =cut  =cut
# Line 50  It can be used as perl-only alternative Line 63  It can be used as perl-only alternative
63  # some binary reads  # some binary reads
64  #  #
65    
 sub Read32 {  
         my $self = shift;  
   
         my $f = shift || die "Read32 needs file handle";  
         read($$f,$b,4) || die "can't read 4 bytes from $$f from position ".tell($f);  
         return unpack("l",$b);  
 }  
   
66  =head2 new  =head2 new
67    
68  Open CDS/ISIS database  Open CDS/ISIS database
# Line 66  Open CDS/ISIS database Line 71  Open CDS/ISIS database
71          isisdb => './cds/cds',          isisdb => './cds/cds',
72          read_fdt => 1,          read_fdt => 1,
73          debug => 1,          debug => 1,
74            include_deleted => 1,
75   );   );
76    
77  Options are described below:  Options are described below:
# Line 86  by default. Line 92  by default.
92    
93  Dump a C<lot> of debugging output.  Dump a C<lot> of debugging output.
94    
95    =item include_deleted
96    
97    Don't skip logically deleted records in ISIS.
98    
99  =back  =back
100    
101  It will also set C<$isis-E<gt>{'maxmfn'}> which is maximum MFN stored in database.  It will also set C<$isis-E<gt>{'maxmfn'}> which is maximum MFN stored in database.
# Line 97  sub new { Line 107  sub new {
107          my $self = {};          my $self = {};
108          bless($self, $class);          bless($self, $class);
109    
110          $self->{isisdb} = {@_}->{isisdb} || croak "new needs database name as argument!";          croak "new needs database name (isisdb) as argument!" unless ({@_}->{isisdb});
111    
112          $self->{debug} = {@_}->{debug};          foreach my $v (qw{isisdb debug include_deleted}) {
113                    $self->{$v} = {@_}->{$v};
114            }
115    
116          # if you want to read .FDT file use read_fdt argument when creating class!          # if you want to read .FDT file use read_fdt argument when creating class!
117          if ({@_}->{read_fdt} && -e $self->{isisdb}.".FDT") {          if ({@_}->{read_fdt} && -e $self->{isisdb}.".FDT") {
# Line 140  sub new { Line 152  sub new {
152          # NXTMFP        offset to next available position in last block          # NXTMFP        offset to next available position in last block
153          # MFTYPE        always 0 for user db file (1 for system)          # MFTYPE        always 0 for user db file (1 for system)
154          seek(fileMST,4,0);          seek(fileMST,4,0);
155          $self->{'NXTMFN'}=$self->Read32(\*fileMST) || carp "NXTNFN is zero";  
156            my $buff;
157    
158            read(fileMST, $buff, 4);
159            $self->{'NXTMFN'}=unpack("l",$buff) || carp "NXTNFN is zero";
160    
161          # save maximum MFN          # save maximum MFN
162          $self->{'maxmfn'} = $self->{'NXTMFN'} - 1;          $self->{'maxmfn'} = $self->{'NXTMFN'} - 1;
# Line 173  sub new { Line 189  sub new {
189                  my $buff = shift || return;                  my $buff = shift || return;
190                  my @arr = unpack("ssssssllls", $buff);                  my @arr = unpack("ssssssllls", $buff);
191    
192                    print "unpack_cnt: ",join(" ",@arr),"\n" if ($self->{'debug'});
193    
194                  my $IDTYPE = shift @arr;                  my $IDTYPE = shift @arr;
195                  foreach (@flds) {                  foreach (@flds) {
196                          $self->{$IDTYPE}->{$_} = abs(shift @arr);                          $self->{$IDTYPE}->{$_} = abs(shift @arr);
197                  }                  }
198          }          }
199    
         my $buff;  
200          read(fileCNT, $buff, 26);          read(fileCNT, $buff, 26);
201          $self->unpack_cnt($buff);          $self->unpack_cnt($buff);
202    
# Line 191  sub new { Line 208  sub new {
208    
209          print Dumper($self) if ($self->{debug});          print Dumper($self) if ($self->{debug});
210    
211            # open files for later
212            open($self->{'fileXRF'}, $self->{isisdb}.".XRF") || croak "can't open '$self->{isisdb}.XRF': $!";
213    
214            open($self->{'fileMST'}, $self->{isisdb}.".MST") || croak "can't open '$self->{isisdb}.MST': $!";
215    
216          $self ? return $self : return undef;          $self ? return $self : return undef;
217  }  }
218    
219  =head2 GetMFN  =head2 fetch
220    
221  Read record with selected MFN  Read record with selected MFN
222    
223    my $rec = $isis->GetMFN(55);    my $rec = $isis->fetch(55);
224    
225  Returns hash with keys which are field names and values are unpacked values  Returns hash with keys which are field names and values are unpacked values
226  for that field.  for that field.
227    
228  =cut  =cut
229    
230  sub GetMFN {  sub fetch {
231          my $self = shift;          my $self = shift;
232    
233          my $mfn = shift || croak "GetMFN needs MFN as argument!";          my $mfn = shift || croak "fetch needs MFN as argument!";
234    
235          print "GetMFN: $mfn\n" if ($self->{debug});          print "fetch: $mfn\n" if ($self->{debug});
   
         open(fileXRF, $self->{isisdb}.".XRF") || croak "can't open '$self->{isisdb}.XRF': $!";  
236    
237          # XXX check this?          # XXX check this?
238          my $mfnpos=($mfn+int(($mfn-1)/127))*4;          my $mfnpos=($mfn+int(($mfn-1)/127))*4;
239    
240          print "seeking to $mfnpos in file '$self->{isisdb}.XRF'\n" if ($self->{debug});          print "seeking to $mfnpos in file '$self->{isisdb}.XRF'\n" if ($self->{debug});
241          seek(fileXRF,$mfnpos,0);          seek($self->{'fileXRF'},$mfnpos,0);
242    
243            my $buff;
244    
245          # read XRFMFB abd XRFMFP          # read XRFMFB abd XRFMFP
246          my $pointer=$self->Read32(\*fileXRF);          read($self->{'fileXRF'}, $buff, 4);
247            my $pointer=unpack("l",$buff) || carp "pointer is null";
248    
249          my $XRFMFB = int($pointer/2048);          my $XRFMFB = int($pointer/2048);
250          my $XRFMFP = $pointer - ($XRFMFB*2048);          my $XRFMFP = $pointer - ($XRFMFB*2048);
# Line 242  sub GetMFN { Line 265  sub GetMFN {
265    
266          print "$offset - $offset2 - $offset3 - $offset4\n" if ($self->{debug});          print "$offset - $offset2 - $offset3 - $offset4\n" if ($self->{debug});
267    
         close(fileXRF);  
   
268          # Get Record Information          # Get Record Information
269    
270          open(fileMST, $self->{isisdb}.".MST") || croak "can't open '$self->{isisdb}.MST': $!";          seek($self->{'fileMST'},$offset4,0);
   
         seek(fileMST,$offset4,0);  
271    
272          my $value=$self->Read32(\*fileMST);          read($self->{'fileMST'}, $buff, 4);
273            my $value=unpack("l",$buff);
274    
275          if ($value!=$mfn) {          if ($value!=$mfn) {
276  print ("Error: The MFN:".$mfn." is not found in MST(".$value.")");      print ("Error: The MFN:".$mfn." is not found in MST(".$value.")");    
# Line 264  print ("Error: The MFN:".$mfn." is not f Line 284  print ("Error: The MFN:".$mfn." is not f
284  #       $NVF=$self->Read16($fileMST);  #       $NVF=$self->Read16($fileMST);
285  #       $STATUS=$self->Read16($fileMST);  #       $STATUS=$self->Read16($fileMST);
286    
287          my $buff;          read($self->{'fileMST'}, $buff, 14);
         read(fileMST, $buff, 14);  
288    
289          my ($MFRL,$MFBWB,$MFBWP,$BASE,$NVF,$STATUS) = unpack("slssss", $buff);          my ($MFRL,$MFBWB,$MFBWP,$BASE,$NVF,$STATUS) = unpack("slssss", $buff);
290    
291          print "MFRL: $MFRL MFBWB: $MFBWB MFBWP: $MFBWP BASE: $BASE NVF: $NVF STATUS: $STATUS\n" if ($self->{debug});          print "MFRL: $MFRL MFBWB: $MFBWB MFBWP: $MFBWP BASE: $BASE NVF: $NVF STATUS: $STATUS\n" if ($self->{debug});
292    
293            # delete old record
294            delete $self->{record};
295    
296            if (! $self->{'include_deleted'} && $MFRL < 0) {
297                    print "## logically deleted record $mfn, skipping...\n" if ($self->{debug});
298                    return;
299            }
300    
301          # Get Directory Format          # Get Directory Format
302    
303          my @FieldPOS;          my @FieldPOS;
304          my @FieldLEN;          my @FieldLEN;
305          my @FieldTAG;          my @FieldTAG;
306    
307            read($self->{'fileMST'}, $buff, 6 * $NVF);
308    
309            my $fld_len = 0;
310    
311          for (my $i = 0 ; $i < $NVF ; $i++) {          for (my $i = 0 ; $i < $NVF ; $i++) {
312    
313  #               $TAG=$self->Read16($fileMST);  #               $TAG=$self->Read16($fileMST);
314  #               $POS=$self->Read16($fileMST);  #               $POS=$self->Read16($fileMST);
315  #               $LEN=$self->Read16($fileMST);  #               $LEN=$self->Read16($fileMST);
316    
317                  read(fileMST, $buff, 6);                  my ($TAG,$POS,$LEN) = unpack("sss", substr($buff,$i * 6, 6));
                 my ($TAG,$POS,$LEN) = unpack("sss", $buff);  
318    
319                  print "TAG: $TAG POS: $POS LEN: $LEN\n" if ($self->{debug});                  print "TAG: $TAG POS: $POS LEN: $LEN\n" if ($self->{debug});
320    
# Line 301  print ("Error: The MFN:".$mfn." is not f Line 331  print ("Error: The MFN:".$mfn." is not f
331                  push @FieldTAG,$TAG;                  push @FieldTAG,$TAG;
332                  push @FieldPOS,$POS;                  push @FieldPOS,$POS;
333                  push @FieldLEN,$LEN;                  push @FieldLEN,$LEN;
334    
335                    $fld_len += $LEN;
336          }          }
337    
338          # Get Variable Fields          # Get Variable Fields
339    
340          delete $self->{record};          read($self->{'fileMST'},$buff,$fld_len);
341    
342          for (my $i = 0 ; $i < $NVF ; $i++) {          for (my $i = 0 ; $i < $NVF ; $i++) {
343                  my $rec;                  # skip zero-sized fields
344                  read(fileMST,$rec,$FieldLEN[$i]);                  next if ($FieldLEN[$i] == 0);
                 push @{$self->{record}->{$FieldTAG[$i]}}, $rec;  
         }  
         close(fileMST);  
345    
346          # The record is marked for deletion                  push @{$self->{record}->{$FieldTAG[$i]}}, substr($buff,$FieldPOS[$i],$FieldLEN[$i]);
         if ($STATUS==1) {  
                 return -1;  
347          }          }
348            close(fileMST);
349    
350          print Dumper($self) if ($self->{debug});          print Dumper($self) if ($self->{debug});
351    
# Line 337  sub to_ascii { Line 365  sub to_ascii {
365    
366          my $mfn = shift || croak "need MFN";          my $mfn = shift || croak "need MFN";
367    
368          my $rec = $self->GetMFN($mfn);          my $rec = $self->fetch($mfn);
369    
370          my $out = "0\t$mfn";          my $out = "0\t$mfn";
371    
# Line 350  sub to_ascii { Line 378  sub to_ascii {
378          return $out;          return $out;
379  }  }
380    
 ################# old cruft which is not ported from php to perl  
   
 =begin php  
   
   # Load the dictionary from the $db.L0x files.  
   # Not usefull Yet  
     
   sub LoadDictionary()  
   {  
     $fileL01=fopen($self->{isisdb}.".L01","r");  
     rewind($fileL01);    
   
     do  
     {  
   
       $POS=$self->Read32($fileL01);  
       $OCK=$self->Read16($fileL01);  
       $IT=$self->Read16($fileL01);  
       $PS=$self->Read32($fileL01);  
 print "<br>PS:".$PS." ".$self->{ORDF}->{1}." ";  
       for ($i=0;$i<$OCK;$i++)  
       {  
         $KEY=fread($fileL01,10);  
         
         print $KEY." ### ";  
   
         $INFO1=$self->Read32($fileL01);  
         $INFO2=$self->Read32($fileL01);  
   
         #L01Key->{$key}=array($INFO1,$INFO2);  
       }  
       
       rewind($fileL01);  
       $offset=($PS-1)*(12+$self->{ORDF}->{1}*18*2);  
       fseek($fileL01,$offset);  
   
     } While (!feof($fileL01));  
   
     fclose($fileL01);  
   }  
   
   # self function search through the tree and returns an array of pointers to IFP  
   # The function must be recursive  
   
   sub SearchTree($search,$fileNB,$PUNT)  
   {        
       $offset=(($PUNT-1)*(8+2*$self->{ORDN}->{1}*14));  
   
         rewind($fileNB1);  
   
         fseek($fileNB,$offset);  
   
         $POS=$self->Read32($fileNB);  
         $OCK=$self->Read16($fileNB);  
         $IT=$self->Read16($fileNB);  
   
 #print "<br>".$POS." - ".$OCK." - ".$IT;  
   
         $OLDPUNT=$POS;  
         $j=0;  
         for ($i=0;$i<$OCK;$i++)  
         {  
           $KEY=fread($fileNB,10);  
         
           $PUNT=$self->Read32($fileNB);  
   
 #print " ## ".chop($KEY)."(".$PUNT."-".$OLDPUNT.") ## ";  
   
           If (strcmp($search,chop($KEY))<0)  
           {  
             break;  
           }  
           $OLDPUNT=$PUNT;    
         }          
 #print $OLDPUNT;  
         Return $OLDPUNT;  
   }  
   
   # Search ISIS for record containing search  
   # Return a sorted array of MFN  
   
   sub Search($search)  
   {  
   
   $search=strtoupper($search);  
 #print "Searching....".$search." - ".$self->{POSRX}->{1}."<br>";  
     # first search .x01  
       
   
     # Search in .N01    
   
   
     $fileN01=fopen($self->{isisdb}.".N01","r");  
     $offset=(($self->{POSRX}->{1}-1)*(8+2*$self->{ORDN}->{1}*14));  
   
       do  
       {  
         rewind($fileN01);  
   
         fseek($fileN01,$offset);  
   
         $POS=$self->Read32($fileN01);  
         $OCK=$self->Read16($fileN01);  
         $IT=$self->Read16($fileN01);  
   
 #print "<br>".$POS." - ".$OCK." - ".$IT;  
   
         $OLDPUNT=$POS;  
         for ($i=0;$i<$OCK;$i++)  
         {  
           $KEY=fread($fileN01,10);  
         
           $PUNT=$self->Read32($fileN01);  
   
 #print " ## ".chop($KEY)."(".$PUNT."-".$OLDPUNT.") ## ";  
   
           If (strcmp($search,chop($KEY))<0)  
           {  
             break;  
           }  
           $OLDPUNT=$PUNT;    
         }  
         $offset=(($OLDPUNT-1)*(8+2*$self->{ORDN}->{1}*14));        
       } while ($OLDPUNT>0);  
 #print $OLDPUNT;  
   
   
     fclose($fileN01);  
   
     # Now look for records in .L01 file  
     $fileL01=fopen($self->{isisdb}.".L01","r");  
     rewind($fileL01);  
   
     $offset=(-$OLDPUNT-1)*(12+$self->{ORDF}->{1}*18*2);  
     fseek($fileL01,$offset);  
   
     $POS=$self->Read32($fileL01);  
     $OCK=$self->Read16($fileL01);  
     $IT=$self->Read16($fileL01);  
     $PS=$self->Read32($fileL01);  
 #print "<br>POS:".$POS." ".$self->{ORDF}->{1}." ";  
     for ($i=0;$i<$OCK;$i++)  
     {  
       $KEY=fread($fileL01,10);  
         
 #print $KEY." ### ";  
   
       $INFO1=$self->Read32($fileL01);  
       $INFO2=$self->Read32($fileL01);  
   
       If (strcmp($search,chop($KEY))==0)  
       {  
         break;  
       }  
     }      
   
     fclose($fileL01);  
   
 #print $INFO1."--".$INFO2;  
   
     # Now look in .IFP for the MFN  
     $fileIFP=fopen($self->{isisdb}.".IFP","r");  
     rewind($fileIFP);  
     $offset=($INFO1-1)*512+($INFO2*4);  
     fseek($fileIFP,$offset);    
   
     $IFPBLK=$self->Read32($fileIFP);  
   
     $IFPNXTB=$self->Read32($fileIFP);  
     $IFPNXTP=$self->Read32($fileIFP);  
     $IFPTOTP=$self->Read32($fileIFP);  
     $IFPSEGP=$self->Read32($fileIFP);  
     $IFPSEGC=$self->Read32($fileIFP);  
   
   
 #print "<br>IFP:".$IFPBLK." # ".$IFPNXTB." - ".$IFPNXTP." - ".$IFPTOTP." - ".$IFPSEGP." - ".$IFPSEGC;  
   
     rewind($fileIFP);  
     $offset=($INFO1-1)*512+24+($INFO2*4);  
     fseek($fileIFP,$offset);      
       
     $j=24+($INFO2*4);  
     $k=0;  
     $l=1;  
     $OLDPMFN="";  
     for ($i=0;$i<$IFPSEGP;$i++)  
     {  
       $B1=$self->Read8($fileIFP);  
       $B2=$self->Read8($fileIFP);  
       $B3=$self->Read8($fileIFP);  
       $B4=$self->Read8($fileIFP);  
       $B5=$self->Read8($fileIFP);  
       $B6=$self->Read8($fileIFP);  
       $B7=$self->Read8($fileIFP);  
       $B8=$self->Read8($fileIFP);  
   
       $PMFN=$B1*65536+$B2*256+$B3;  
       $PTAG=$B4*256+$B5;  
       $POCC=$B6;  
       $PCNT=$B7*256+$B8;  
   
       if ($OLDPMFN!=$PMFN)  
       {  
         if ($PMFN!=0)  
         {  
           $self->{MFNArray}->{$l}=$PMFN;  
           $OLDPMFN=$PMFN;  
           $l+=1;  
         }  
       }  
   
       $j=$j+8;  
 #print "<br>".$PMFN."-".$PTAG." - ".$POCC." - ".$PCNT;  
 #print "@@".$j."@@@@";  
       if ($j>=504)  
       {  
         if ($IFPNXTB==0 && $IFPNXTP==0)  
         {  
           $k=$k+1;  
           rewind($fileIFP);  
           $offset=($INFO1-1+$k)*512;    
           fseek($fileIFP,$offset);        
           $B=$self->Read32($fileIFP);  
 #print "<br>-".$B."-<br>";  
           $j=0;  
         } else  
         {  
           rewind($fileIFP);  
           $offset=($IFPNXTB-1)*512;    
           fseek($fileIFP,$offset);  
   
           $OLDIFPNXTB=$IFPNXTB;  
           $OLDIFPNXTP=$IFPNXTP;  
   
           $IFPBLK=$self->Read32($fileIFP);  
   
           $IFPNXTB=$self->Read32($fileIFP);  
           $IFPNXTP=$self->Read32($fileIFP);  
           $IFPTOTP=$self->Read32($fileIFP);  
           $IFPSEGP=$self->Read32($fileIFP);  
           $IFPSEGC=$self->Read32($fileIFP);  
   
           rewind($fileIFP);  
           $offset=($OLDIFPNXTB-1)*512+24+($OLDIFPNXTP*4);  
           fseek($fileIFP,$offset);      
       
           $j=24+($OLDIFPNXTP*4);  
           $k=0;  
           $j=0;  
         }  
       }  
   
     }      
     fclose($fileIFP);  
     return $l-1;  
   }  
   
 =cut  
   
381  #  #
382  # XXX porting from php left-over:  # XXX porting from php left-over:
383  #  #
# Line 618  print "<br>PS:".$PS." ".$self->{ORDF}->{ Line 387  print "<br>PS:".$PS." ".$self->{ORDF}->{
387  # Probably direct usage is better!  # Probably direct usage is better!
388  #  #
389    
390  sub GetFieldName {  sub TagName {
         my $self = shift;  
         return $self->{FieldName};  
 }  
   
 sub GetTagName {  
391          my $self = shift;          my $self = shift;
392          return $self->{TagName};          return $self->{TagName};
393  }  }
394    
395  sub GetFieldTag {  sub NextMFN {
         my $self = shift;  
         return $self->{FieldTAG};  
 }  
   
 sub GetNextMFN {  
396          my $self = shift;          my $self = shift;
397          return $self->{NXTMFN};          return $self->{NXTMFN};
398  }  }
399    
 sub GetMFNArray {  
         my $self = shift;  
         return $self->{MFNArray};  
 }  
 =begin php  
   
   sub Read32($fileNB)  
   {  
     $B1=ord(fread($fileNB,1));  
     $B2=ord(fread($fileNB,1));  
     $B3=ord(fread($fileNB,1));  
     $B4=ord(fread($fileNB,1));  
   
     if ($B4<=128)  
     {  
       $value=$B1+$B2*256+$B3*65536+$B4*16777216;  
     } else  
     {  
       $value=$self->Not8($B1)+$self->Not8($B2)*256+$self->Not8($B3)*65536+$self->Not8($B4)*16777216;  
       $value=-($value+1);  
     }  
 #    print "(".$B1.",".$B2.",".$B3.",".$B4.":".$value.")";  
   
     return $value;    
   }  
   
   sub Read24($fileNB)  
   {  
     $B1=ord(fread($fileNB,1));  
     $B2=ord(fread($fileNB,1));  
     $B3=ord(fread($fileNB,1));  
   
     $value=$B1+$B2*256+$B3*65536;  
   
 #    print "(".$B1.",".$B2.",".$B3.":".$value.")";  
   
     return $value;    
   }  
   
   sub Read16($fileNB)  
   {  
     $B1=ord(fread($fileNB,1));  
     $B2=ord(fread($fileNB,1));  
   
     $value=$B1+$B2*256;  
 #    print "(".$B1.",".$B2.":".$value.")";  
   
     return $value;    
   }  
   
   sub Read8($fileNB)  
   {  
     $B1=ord(fread($fileNB,1));  
   
     $value=$B1;  
 #    print "(".$value.")";  
   
     return $value;    
   }  
   
   sub Not8($value)  
   {  
     $value=decbin($value);  
     if (strlen($value)<8)  
     {  
       $buffer="";  
       for($i=0;$i<(8-strlen($value));$i++)  
       {  
         $buffer.="0";  
       }  
       $value=$buffer.$value;  
     }  
     $value=ereg_replace("0","3",$value);  
     $value=ereg_replace("1","0",$value);  
     $value=ereg_replace("3","1",$value);  
     $value=bindec($value);  
     return $value;  
   }  
 }  
   
 =cut  
   
400  1;  1;
 __END__  
401    
402  =head1 BUGS  =head1 BUGS
403    

Legend:
Removed from v.3  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26