/[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 1 by dpavlin, Tue Dec 28 00:43:04 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:
78    
79    =over 5
80    
81  =item isisdb  =item isisdb
82    
83  Prefix path to CDS/ISIS. It should contain full or relative path to database  Prefix path to CDS/ISIS. It should contain full or relative path to database
# Line 82  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
100    
101    It will also set C<$isis-E<gt>{'maxmfn'}> which is maximum MFN stored in database.
102    
103  =cut  =cut
104    
105  sub new {  sub new {
# Line 89  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} || 1;    # XXX remove debug always!          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 132  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
162            $self->{'maxmfn'} = $self->{'NXTMFN'} - 1;
163    
164          close(fileMST);          close(fileMST);
165    
# Line 162  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 180  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 fetch
220    
221  # Get a record from the MFN  Read record with selected MFN
 # Return the number of fields in the record.  
 # Return -1 if the record is marked for deletion  
 # The record is then extracted with call to GETs  
222    
223  sub GetMFN {    my $rec = $isis->fetch(55);
224          my $self = shift;  
225    Returns hash with keys which are field names and values are unpacked values
226    for that field.
227    
228    =cut
229    
230          my $mfn = shift || croak "GetMFN needs MFN as argument!";  sub fetch {
231            my $self = shift;
232    
233          print "GetMFN: $mfn\n" if ($self->{debug});          my $mfn = shift || croak "fetch needs MFN as argument!";
234    
235          open(fileXRF, $self->{isisdb}.".XRF") || croak "can't open '$self->{isisdb}.XRF': $!";          print "fetch: $mfn\n" if ($self->{debug});
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 226  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);
271    
272          seek(fileMST,$offset4,0);          read($self->{'fileMST'}, $buff, 4);
273            my $value=unpack("l",$buff);
         my $value=$self->Read32(\*fileMST);  
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 248  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 285  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            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);
                 $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    
352          return $NVF;          return $self->{'record'};
353  }  }
354    
355  =begin php  =head2 to_ascii
356    
357    # Load the dictionary from the $db.L0x files.  Dump ascii output of selected MFN
   # 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);  
358    
359      } While (!feof($fileL01));    print $isis->to_ascii(55);
360    
361      fclose($fileL01);  =cut
   }  
362    
363    # self function search through the tree and returns an array of pointers to IFP  sub to_ascii {
364    # The function must be recursive          my $self = shift;
365    
366    sub SearchTree($search,$fileNB,$PUNT)          my $mfn = shift || croak "need MFN";
   {        
       $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;  
   }  
367    
368    # Search ISIS for record containing search          my $rec = $self->fetch($mfn);
   # Return a sorted array of MFN  
369    
370    sub Search($search)          my $out = "0\t$mfn";
   {  
371    
372    $search=strtoupper($search);          foreach my $f (sort keys %{$rec}) {
373  #print "Searching....".$search." - ".$self->{POSRX}->{1}."<br>";                  $out .= "\n$f\t".join("\n$f\t",@{$self->{record}->{$f}});
374      # 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;  
   }  
375    
376  =cut          $out .= "\n";
377    
378            return $out;
379    }
380    
381  #  #
382  # XXX porting from php left-over:  # XXX porting from php left-over:
# Line 572  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.1  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26