# -*- perl -*-
# Lintian::Data -- interface to query lists of keywords

# Copyright (C) 2008 Russ Allbery
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.

package Lintian::Sliding;

use strict;
use warnings;
use autodie;

use Carp qw(croak);

use Lintian::Util qw(strip);

sub new {
    my ($class, $mode, $file, $blocksub) = @_;
    my $self = {};

    my $block = '';

    open(my $handle, $mode, $file);

    $self->{'_handle'} = $handle;
    $self->{'_queue'} = ['', ''];
    $self->{'_block'} = '';
    $self->{'_blocksize'} = 4096;
    $self->{'_blocksub'} = defined($blocksub) ? $blocksub : undef;

    bless($self, $class);
    return $self;
}

sub readwindow {
    my ($self) = @_;
    my $window;
    unless(read($self->{'_handle'}, $window, $self->{'_blocksize'})) {
        return;
    }

    if(defined($self->{'_blocksub'})) {
	local $_ = $window;
	$self->{'_blocksub'}->();
	$window = $_;
    }

    my $block;
    shift @{$self->{'_queue'}};
    push (@{$self->{'_queue'}}, $window);
    $block =  join '', @{$self->{'_queue'}};
    return $block;
}

=head1 NAME

Lintian::Sliding - Lintian interface to sliding window match

=head1 SYNOPSIS

    my $sfd = Lintian::Sliding->new('<','someevilfile.c', sub locallc { return lc($_); });
    my $window;
    while ($window = $sfd->readwindow()) {
       if (index($window, 'evil') > -1) {
           if($window =~
                 m/software \s++ shall \s++
                   be \s++ used \s++ for \s++ good \s*+ ,?+ \s*+
                   not \s++ evil/xsim) {
              tag 'license-problem-json-evil';
           }
       }
    }

=head1 DESCRIPTION

Lintian::Sliding provides a way of matching some pattern,
including multi line pattern, without needing to fully load the
file in memory.

=head1 CLASS METHODS

=over 4

=item new

=back

=head1 INSTANCE METHODS

=over 4

=item readwindow


=back

=head1 DIAGNOSTICS

=over 4

=item no data type specified

=back

=head1 AUTHOR

Originally written by Bastien ROUCARIÈS for Lintian.

=head1 SEE ALSO

lintian(1)

=cut

1;

# Local Variables:
# indent-tabs-mode: nil
# cperl-indent-level: 4
# End:
# vim: syntax=perl sw=4 sts=4 sr et
