sub
new {
my
$class
=
shift
;
my
$filename
=
shift
;
my
$self
=
bless
{
filename
=>
$filename
,
fh
=>
undef
,
},
$class
;
if
(
$self
->{filename} eq
'-'
) {
$self
->{fh} =
*STDIN
;
}
return
$self
;
}
sub
name {
return
$_
[0]->{filename};
}
sub
basename {
my
(
$self
) =
@_
;
return
$self
->{basename} //= (File::Spec->splitpath(
$self
->name))[2];
}
sub
open
{
my
(
$self
) =
@_
;
if
( !
$self
->{fh} ) {
if
(
open
$self
->{fh},
'<'
,
$self
->{filename} ) {
}
else
{
$self
->{fh} =
undef
;
}
}
return
$self
->{fh};
}
sub
may_be_present {
my
$self
=
shift
;
my
$regex
=
shift
;
my
$may_be_present
= 1;
if
(
$regex
&&
$self
->
open
() && -f
$self
->{fh} ) {
my
$buffer
;
my
$size
= 10_000_000;
my
$rc
=
sysread
(
$self
->{fh},
$buffer
,
$size
);
if
( !
defined
(
$rc
) ) {
if
(
$App::Ack::report_bad_filenames
) {
App::Ack::
warn
(
$self
->name .
": $!"
);
}
$may_be_present
= 0;
}
else
{
if
( (
$rc
==
$size
) || (
index
(
$buffer
,
"\r"
) >= 0) ) {
$may_be_present
= 1;
}
else
{
if
(
$buffer
!~ /
$regex
/o ) {
$may_be_present
= 0;
}
}
}
}
return
$may_be_present
;
}
sub
reset
{
my
$self
=
shift
;
if
(
defined
(
$self
->{fh}) ) {
return
unless
-f
$self
->{fh};
if
( !
seek
(
$self
->{fh}, 0, 0 ) &&
$App::Ack::report_bad_filenames
) {
App::Ack::
warn
(
"$self->{filename}: $!"
);
}
}
return
;
}
sub
close
{
my
$self
=
shift
;
if
(
$self
->{fh} ) {
if
( !
close
(
$self
->{fh}) &&
$App::Ack::report_bad_filenames
) {
App::Ack::
warn
(
$self
->name() .
": $!"
);
}
$self
->{fh} =
undef
;
}
return
;
}
sub
clone {
my
(
$self
) =
@_
;
return
__PACKAGE__->new(
$self
->name);
}
sub
firstliney {
my
(
$self
) =
@_
;
if
( !
exists
$self
->{firstliney} ) {
my
$fh
=
$self
->
open
();
if
( !
$fh
) {
if
(
$App::Ack::report_bad_filenames
) {
App::Ack::
warn
(
$self
->name .
': '
. $! );
}
$self
->{firstliney} =
''
;
}
else
{
my
$buffer
;
my
$rc
=
sysread
(
$fh
,
$buffer
, 250 );
if
(
$rc
) {
$buffer
=~ s/[\r\n].*//s;
}
else
{
if
( !
defined
(
$rc
) ) {
App::Ack::
warn
(
$self
->name .
': '
. $! );
}
$buffer
=
''
;
}
$self
->{firstliney} =
$buffer
;
$self
->
reset
;
}
}
return
$self
->{firstliney};
}
1;