Paranoid

 view release on metacpan or  search on metacpan

lib/Paranoid/IO/FileMultiplexer/Block.pm  view on Meta::CPAN

    # NOTE:  This method intentionally allows reads of a length greater than
    # the block size, but it will only return content from within the block
    # boundaries.

    # Error out if we were not given a valid scalar ref
    unless ( defined $cref and ref($cref) eq 'SCALAR' ) {
        $rv = undef;
        pdebug( 'invalid argument for content ref', PDLEVEL1 );
    }

    # Set start to beginning of block if not specified
    $start = 0 unless defined $start;

    # Set default bytes if not specified
    $bytes = $bsize - $start unless defined $bytes;

    # Make sure start is in range
    if ( $minp + $start > $maxp ) {
        pdebug( 'starting position is out of range', PDLEVEL1 );
        $rv = undef;
    }

    if ($rv) {

        # Make sure we limit read to our block
        $bytes = ( $maxp + 1 ) - ( $minp + $start )
            if ( $minp + $start + $bytes ) > ( $maxp + 1 );

        # Perform the read
        if ( pseek( $file, $minp + $start, SEEK_SET ) ) {
            $rv = pread( $file, $$cref, $bytes );
        } else {
            $rv = undef;
        }
    }

    subPostamble( PDLEVEL3, '$', $rv );

    return $rv;
}

sub bwrite {

# Purpose:  Writes the contents of the entire block. or a specified range
# Returns:  Integer (bytes written) or undef on error
# Usage:    $bytesWritten = $obj->bwrite($content);
# Usage:    $bytesWritten = $obj->bwrite($content, $start );
# Usage:    $bytesWritten = $obj->bwrite($content, $start, $length );
# Usage:    $bytesWritten = $obj->bwrite($content, $start, $length, $offset );

    my $self    = shift;
    my $content = shift;
    my $start   = shift;
    my $length  = shift;
    my $offset  = shift;
    my $file    = $$self{file};
    my $bsize   = $$self{blockSize};
    my $minp    = $$self{minPos};
    my $maxp    = $$self{maxPos};
    my $rv      = PTRUE_ZERO;
    my $cdata   = defined $content ? ( length $content ) . ' bytes' : undef;
    my $blkLeft;

    subPreamble( PDLEVEL3, '$;$$$', $cdata, $start, $length, $offset );

    # NOTE:  This method intentionally allows writes of a length greater than
    # the block size, but it will only write content from within the block
    # boundaries.

    # Error out if we were not given a valid scalar ref
    unless ( defined $content and length $content ) {
        $rv = undef;
        pdebug( 'invalid argument for content', PDLEVEL1 );
    }

    # Set start to beginning of block if not specified
    $start = 0 unless defined $start;

    # Set offset to zero if not specified
    $offset = 0 unless defined $offset;

    # Set length to max content length available if not defined
    $length  = length($content) - $offset unless defined $length;
    $blkLeft = $bsize - $start;
    $length  = $blkLeft if $blkLeft < $length;

    # Make sure start is in range
    if ( $minp + $start > $maxp ) {
        pdebug( 'starting position is out of range', PDLEVEL1 );
        $rv = undef;
    }

    if ($rv) {

        # Perform the write
        if ( pseek( $file, $minp + $start, SEEK_SET ) ) {
            $rv = pwrite( $file, $content, $length, $offset );
        } else {
            $rv = undef;
        }
    }

    subPostamble( PDLEVEL3, '$', $rv );

    return $rv;
}

1;

__END__

=head1 NAME

Paranoid::IO::FileMultiplexer::Block - Block-level Allocator/Accessor

=head1 VERSION

$Id: lib/Paranoid/IO/FileMultiplexer/Block.pm, 2.10 2022/03/08 00:01:04 acorliss Exp $

=head1 SYNOPSIS

    $obj = Paranoid::IO::FileMultiplexer::Block->new(
            $filename, $bnum, $bsize);
    $rv  = $obj->allocate;



( run in 0.825 second using v1.01-cache-2.11-cpan-f56aa216473 )