MARC-Record

 view release on metacpan or  search on metacpan

lib/MARC/File/USMARC.pm  view on Meta::CPAN

            $marc->_warn( "field does not end in end of field character in tag $tagno $location" );
        }

        warn "Specs: ", join( "|", $tagno, $len, $offset, $tagdata ), "\n" if $MARC::Record::DEBUG;

        if ( $filter_func ) {
            next unless $filter_func->( $tagno, $tagdata );
        }

        if ( MARC::Field->is_controlfield_tag($tagno) ) {
            $marc->append_fields( MARC::Field->new( $tagno, $tagdata ) );
        } else {
            my @subfields = split( SUBFIELD_INDICATOR, $tagdata );
            my $indicators = shift @subfields;
            my ($ind1, $ind2);

            if ( length( $indicators ) > 2 or length( $indicators ) == 0 ) {
                $marc->_warn( "Invalid indicators \"$indicators\" forced to blanks $location for tag $tagno\n" );
                ($ind1,$ind2) = (" ", " ");
            } else {
                $ind1 = substr( $indicators,0, 1 );
                $ind2 = substr( $indicators,1, 1 );
            }

            # Split the subfield data into subfield name and data pairs
            my @subfield_data;
            for ( @subfields ) {
                if ( length > 0 ) {
                    push( @subfield_data, substr($_,0,1),substr($_,1) );
                } else {
                    $marc->_warn( "Entirely empty subfield found in tag $tagno" );
                }
            }

            if ( !@subfield_data ) {
                $marc->_warn( "no subfield data found $location for tag $tagno" );
                next;
            }

            my $field = MARC::Field->new($tagno, $ind1, $ind2, @subfield_data );
            if ( $field->warnings() ) {
                $marc->_warn( $field->warnings() );
            }
            $marc->append_fields( $field );
        }
    } # looping through all the fields


    return $marc;
}

=head2 update_leader()

If any changes get made to the MARC record, the first 5 bytes of the
leader (the length) will be invalid.  This function updates the
leader with the correct length of the record as it would be if
written out to a file.

=cut

sub update_leader {
        my $self = shift;

        my (undef,undef,$reclen,$baseaddress) = $self->_build_tag_directory();

        $self->_set_leader_lengths( $reclen, $baseaddress );
}

=head2 _build_tag_directory()

Function for internal use only: Builds the tag directory that gets
put in front of the data in a MARC record.

Returns two array references, and two lengths: The tag directory, and the data fields themselves,
the length of all data (including the Leader that we expect will be added),
and the size of the Leader and tag directory.

=cut

sub _build_tag_directory {
        my $marc = shift;
        $marc = shift if (ref($marc)||$marc) =~ /^MARC::File/;
        die "Wanted a MARC::Record but got a ", ref($marc) unless ref($marc) eq "MARC::Record";

        my @fields;
        my @directory;

        my $dataend = 0;
        for my $field ( $marc->fields() ) {
                # Dump data into proper format
                my $str = $field->as_usmarc;
                push( @fields, $str );

                # Create directory entry
                my $len = bytes::length( $str );

                my $direntry = sprintf( "%03s%04d%05d", $field->tag, $len, $dataend );
                push( @directory, $direntry );
                $dataend += $len;
        }

        my $baseaddress =
                LEADER_LEN +    # better be 24
                ( @directory * DIRECTORY_ENTRY_LEN ) +
                                # all the directory entries
                1;              # end-of-field marker


        my $total =
                $baseaddress +  # stuff before first field
                $dataend +      # Length of the fields
                1;              # End-of-record marker



        return (\@fields, \@directory, $total, $baseaddress);
}

=head2 encode()

Returns a string of characters suitable for writing out to a USMARC file,



( run in 2.009 seconds using v1.01-cache-2.11-cpan-98e64b0badf )