Paranoid

 view release on metacpan or  search on metacpan

lib/Paranoid/IO/Line.pm  view on Meta::CPAN

        my $aref    = shift;
        my $doChomp = shift;
        my $noLocks = shift;
        my $rv      = 1;
        my ( $buffer, $bflag, $in, $content, $bread, $irv, @tmp, $line );

        subPreamble( PDLEVEL1, '$\@;$$', $file, $aref, $doChomp, $noLocks );

        @$aref = ();

        # Check the file
        piolClose($file) unless _chkStat($file);

        # Get/initialize buffer
        if ( exists $buffers{$file} ) {
            $bflag  = $buffers{$file}[PBFLAG];
            $buffer = $buffers{$file}[PBBUFF];
        } else {
            $buffers{$file} = [ PBF_NORMAL, '' ];
            $buffer         = '';
            $bflag          = PBF_NORMAL;
        }

        # Read what we can
        $content = '';
        $bread   = 0;
        while ( $bread < PIOMAXFSIZE ) {
            $irv = $noLocks ? pnlread( $file, $in ) : pread( $file, $in );
            if ( defined $irv ) {
                $bread += $irv;
                $content .= $in;
                last if $irv < PIOBLKSIZE;
            } else {
                $rv = undef;
                last;
            }
        }

        # Post processing
        if ($rv) {

            if ( length $content ) {

                # Add the buffer
                $content = "$buffer$content";

                # Process buffer drain conditions
                pdebug( 'starting buffer flag: (%s)', PDLEVEL4, $bflag );
                pdebug( 'starting buffer: (%s)',      PDLEVEL4, $buffer );
                if ( !$bflag and $content =~ /@{[NEWLINE_REGEX]}/so ) {
                    pdebug( 'draining to next newline', PDLEVEL4 );
                    $content =~ s/^.*?@{[NEWLINE_REGEX]}//so;
                    $bflag  = PBF_NORMAL;
                    $buffer = '';
                }

                # Check for newlines
                if ( $content =~ /@{[NEWLINE_REGEX]}/so ) {

                    # Split lines along newline boundaries
                    @tmp = split m/(@{[NEWLINE_REGEX]})/so, $content;
                    while ( scalar @tmp > 1 ) {
                        if ( length $tmp[0] > PIOMAXLNSIZE ) {
                            splice @tmp, 0, 2;
                            $line = undef;
                        } else {
                            $line = join '', splice @tmp, 0, 2;
                        }
                        push @$aref, $line;
                    }

                    # Check for undefined lines
                    $rv = scalar @$aref;
                    @$aref = grep {defined} @$aref;
                    if ( $rv != scalar @$aref ) {
                        Paranoid::ERROR =
                            pdebug( 'found %s lines over PIOMAXLNSIZE',
                            PDLEVEL1, $rv - @$aref );
                        $rv = undef;
                    }

                    # Check for an unterminated line at the end and
                    # buffer appropriately
                    if ( scalar @tmp ) {

                        # Content left over, update the buffer
                        if ( length $tmp[0] > PIOMAXLNSIZE ) {
                            $buffer = '';
                            $bflag  = PBF_DRAIN;
                            $rv     = undef;
                            Paranoid::ERROR =
                                pdebug( 'buffer is over PIOMAXLNSIZE',
                                PDLEVEL1 );
                        } else {
                            $buffer = $tmp[0];
                            $bflag  = PBF_NORMAL;
                        }
                    } else {

                        # Nothing left over, make sure the buffer is empty
                        $buffer = '';
                        $bflag  = PBF_NORMAL;
                    }

                } else {

                    # Check buffered block for PIOILNSIZE limit
                    if ( length $content > PIOMAXLNSIZE ) {
                        $buffer = '';
                        $bflag  = PBF_DRAIN;
                        $rv     = undef;
                        Paranoid::ERROR =
                            pdebug( 'block is over PIOMAXLNSIZE', PDLEVEL1 );
                    } else {
                        $rv     = 0;
                        $buffer = $content;
                        $bflag  = PBF_NORMAL;
                    }
                }
                pdebug( 'ending buffer flag: (%s)', PDLEVEL4, $bflag );
                pdebug( 'ending buffer: (%s)',      PDLEVEL4, $buffer );



( run in 1.143 second using v1.01-cache-2.11-cpan-71847e10f99 )