XML-Tape

 view release on metacpan or  search on metacpan

lib/XML/Tape.pm  view on Meta::CPAN

    else {
        $fh = new IO::File;
        $fh->open("< $filename") || return undef;
    }

    $obj->{fh}             = $fh;   # XML file handle
    $obj->{records}        = [];    # Temporary storage for XML::Tape::Record
    $obj->{admins}         = [];    # Temporary storage for XML::Tape::Admin
    $obj->{curr}           = undef; # Current record to be read
    $obj->{parse_init}     = 0;     # Flag to indicate if we started reading XML
    $obj->{parse_done}     = 0;     # Flag to indicate if we still reading XML
    $obj->{parser}         = undef; # XML::Parser
    $obj->{parsernb}       = undef; # XML::Parser::ExpatNB
    $obj->{nav}            = {};    # Hash to navigate in the XML record

    return $obj;
}

=item $tape->get_admin()

Reads one XMLtape admin section. Returns an instance of XML::Tape::Admin on success
or undef when no more XMLtape admin sections are available.

=cut
sub get_admin {
    my ($this) = shift;

    $this->parse() until ( ( scalar @{$this->{records}} ) || ( $this->{parse_done} ) );

    return shift( @{$this->{admins}} );
}

=item $tape->get_record()

Reads one XMLtape record section. Returns an instance of XML::Tape::Record on success
or undef when no more records are available.

=cut
sub get_record {
    my ($this) = shift;

    # Parse the XML until we read a new record or the parse is done...
    $this->parse() until ( ( scalar @{$this->{records}} ) || ( $this->{parse_done} ) );

    return shift( @{$this->{records}} );
}

sub tapeclose {
    my ($this) = shift;
    $this->{fh}->close;
}

sub parse_init {
    my ($this) = shift;

    $this->{parser} = new XML::Parser( Handlers => {
                    Start      => sub { $this->handle_start(@_); },
                    Char       => sub { $this->handle_char(@_); },
                    Comment    => sub { $this->handle_comment(@_); },
                    Proc       => sub { $this->handle_proc(@_); },
                    CdataStart => sub { $this->handle_cdata_start(@_); },
                    CdataEnd   => sub { $this->handle_cdata_end(@_); },
                    End        => sub { $this->handle_end(@_); },
                    Final      => sub { $this->handle_final(@_); },
                      });

    $this->{parsernb} = $this->{parser}->parse_start();

    return undef unless $this->{parsernb};

    $this->{parse_init} = 1;

    return 1;
}

sub parse {
    my ($this) = shift;

    unless ($this->{parse_init}) {
        $this->parse_init() || return undef;
    }

    if (defined $this->{fh}) {
        my $buffer;

        # Read a chunk of XML...
        read($this->{fh}, $buffer, $XML::Tape::Reader::BUFF_SIZE);
     
        # If the buffer isn't empty then, parse it
        # otherwise we reached the end of the file...
        if (length $buffer) {
            $this->{parsernb}->parse_more($buffer);
        }
        else {
            $this->{parsernb}->parse_done();
            $this->{parse_done} = 1;
        }
    }
}

sub handle_start {
    my ($this, $xp, $elem, %attr) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }

    if (0) {}
    elsif ($xp->depth == 1 && $elem =~ /^(\w+:)?tapeAdmin$/) {
        $this->{nav}->{in_tape_admin} = 1;
        $this->{curr} = XML::Tape::Admin->new();
    }
    elsif ($xp->depth == 1 && $elem =~ /^(\w+:)?tapeRecord$/) {
        $this->{curr} = XML::Tape::Record->new();
    }

lib/XML/Tape.pm  view on Meta::CPAN

    }
    elsif ($xp->depth == 2 && $elem =~ /^(\w+:)?record$/) {
        $this->{nav}->{in_record} = 0;
        $this->{curr}->setEndByte($xp->current_byte);
    }

    if (0) {}
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
}

sub handle_char {
    my ($this, $xp, $data) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_identifier}) {
        $this->{curr}->addIdentifier($data);
    }
    elsif ($this->{nav}->{in_record_date}) {
        $this->{curr}->addDate($data);
    }
}

sub handle_comment {
    my ($this, $xp, $data) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_proc {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_cdata_start {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_cdata_end {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_final {
    return 1;
}

package XML::Tape::Reader::v2005_01;
# Old tape reader keeping for backwards compatibility reasons;
# NS version http://library.lanl.gov/2005-01/STB-RL/tape/
use XML::Parser;
use IO::File;

$XML::Tape::Reader::BUFF_SIZE = 1024;

sub new {
    my ($pkg, $filename,%options) = @_;
    my $obj = bless {} , $pkg;
    my $fh;

    if (ref $filename && $filename->isa('Tie::Handle')) {
        $fh = $filename;
    }
    else {
        $fh = new IO::File;
        $fh->open("< $filename") || return undef;
    }

    $obj->{fh}             = $fh;   # XML file handle
    $obj->{records}        = [];    # Temporary storage for XML::Tape::Record
    $obj->{admins}         = [];    # Temporary storage for XML::Tape::Admin
    $obj->{curr}           = undef; # Current record to be read
    $obj->{parse_init}     = 0;     # Flag to indicate if we started reading XML
    $obj->{parse_done}     = 0;     # Flag to indicate if we still reading XML
    $obj->{parser}         = undef; # XML::Parser
    $obj->{parsernb}       = undef; # XML::Parser::ExpatNB
    $obj->{nav}            = {};    # Hash to navigate in the XML record

    return $obj;
}

sub get_admin {
    my ($this) = shift;

    $this->parse() until ( ( scalar @{$this->{records}} ) || ( $this->{parse_done} ) );

    return shift( @{$this->{admins}} );
}

sub get_record {
    my ($this) = shift;

    # Parse the XML until we read a new record or the parse is done...
    $this->parse() until ( ( scalar @{$this->{records}} ) || ( $this->{parse_done} ) );

    return shift( @{$this->{records}} );
}

sub tapeclose {
    my ($this) = shift;
    $this->{fh}->close;
}

sub parse_init {
    my ($this) = shift;

    $this->{parser} = new XML::Parser( Handlers => {
                    Start      => sub { $this->handle_start(@_); },
                    Char       => sub { $this->handle_char(@_); },
                    Comment    => sub { $this->handle_comment(@_); },
                    Proc       => sub { $this->handle_proc(@_); },
                    CdataStart => sub { $this->handle_cdata_start(@_); },
                    CdataEnd   => sub { $this->handle_cdata_end(@_); },
                    End        => sub { $this->handle_end(@_); },
                    Final      => sub { $this->handle_final(@_); },
                      });

    $this->{parsernb} = $this->{parser}->parse_start();

    return undef unless $this->{parsernb};

    $this->{parse_init} = 1;

    return 1;
}

sub parse {
    my ($this) = shift;

    unless ($this->{parse_init}) {
        $this->parse_init() || return undef;
    }

    if (defined $this->{fh}) {
        my $buffer;

        # Read a chunk of XML...
        read($this->{fh}, $buffer, $XML::Tape::Reader::BUFF_SIZE);

        # If the buffer isn't empty then, parse it
        # otherwise we reached the end of the file...
        if (length $buffer) {
            $this->{parsernb}->parse_more($buffer);
        }
        else {
            $this->{parsernb}->parse_done();
            $this->{parse_done} = 1;
        }
    }
}

sub handle_start {
    my ($this, $xp, $elem, %attr) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }

    if (0) {}
    elsif ($xp->depth == 1 && $elem =~ /^(\w+:)?tape-admin$/) {
        $this->{nav}->{in_tape_admin} = 1;
        $this->{curr} = XML::Tape::Admin->new();
    }
    elsif ($xp->depth == 1 && $elem =~ /^(\w+:)?tape-record$/) {
        $this->{curr} = XML::Tape::Record->new();
    }

lib/XML/Tape.pm  view on Meta::CPAN

    }
    elsif ($xp->depth == 2 && $elem =~ /^(\w+:)?record$/) {
        $this->{nav}->{in_record} = 0;
        $this->{curr}->setEndByte($xp->current_byte);
    }

    if (0) {}
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
}

sub handle_char {
    my ($this, $xp, $data) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record_identifier}) {
        $this->{curr}->addIdentifier($data);
    }
    elsif ($this->{nav}->{in_record_date}) {
        $this->{curr}->addDate($data);
    }
}

sub handle_comment {
    my ($this, $xp, $data) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_proc {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_cdata_start {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_cdata_end {
    my ($this, $xp) = @_;

    if (0) {}
    elsif ($this->{nav}->{in_tape_admin}) {
        $this->{curr}->addAdminXML($xp->original_string);
    }
    elsif ($this->{nav}->{in_record}) {
        $this->{curr}->addRecordXML($xp->original_string);
    }
}

sub handle_final {
    return 1;
}


=back

=head1 XML::Tape::Admin METHODS

=over 4

=item $admin->getRecord()

Returns a XML string representation of a XMLtape administrative record.

=back

=cut
package XML::Tape::Admin;

sub new {
    my ($pkg) = shift;
    return bless {
        adminXML => undef ,
    } , $pkg;
}

sub addAdminXML {
    my ($this, $str) = @_;
    $this->{adminXML} .= $str;
}

sub getRecord {
    my ($this) = @_;
    return $this->{adminXML};
}

=head1 XML::Tape::Record METHODS

=over 4

=item $record->getIdentifier()

Returns the record identifier as string.

=item $record->getDate()

Returns the record datestamp as string.



( run in 1.246 second using v1.01-cache-2.11-cpan-39bf76dae61 )