----------------------- lib/Bio/GFF3/LowLevel/Parser.pm -----------------------
index 3b3e433..7dec280 100644
@@ -189,13 +189,22 @@ sub _buffered_items_count {
sub _buffer_items {
my ( $self ) = @_;
+ # File position buffer, needed for correct parsing of
+ # implicit beginning of a FASTA section
+ my $pos_buffer = 0;
while( my $line = $self->_next_line ) {
if( $line =~ /^ \s* [^#\s>] /x ) { #< feature line, most common case
+ # Remember current position
+ $pos_buffer = tell;
+
my $f = Bio::GFF3::LowLevel::gff3_parse_feature( $line );
$self->_buffer_feature( $f );
}
# directive or comment
elsif( my ( $hashsigns, $contents ) = $line =~ /^ \s* (\#+) (.*) /x ) {
+ # Remember current position
+ $pos_buffer = tell;
+
if( length $hashsigns == 3 ) { #< sync directive, all forward-references are resolved.
$self->_buffer_all_under_construction_features;
}
@@ -216,15 +225,30 @@ sub _buffer_items {
}
elsif( $line =~ /^ \s* $/x ) {
# blank line, do nothing
+
+ # Remember current position
+ $pos_buffer = tell;
}
elsif( $line =~ /^ \s* > /x ) {
- # implicit beginning of a FASTA section. a very stupid
- # idea to include this in the format spec. increases
+ # implicit beginning of a FASTA section, a very stupid
+ # idea to include this in the format spec, increases
# implementation complexity by a lot.
$self->_buffer_all_under_construction_features;
- $self->_buffer_item( $self->_handle_implicit_fasta_start( $line ) );
+
+ # rewind to previous file position to include the fasta header
+ my $fh = shift @{$self->{filehandles}};
+ seek $fh, $pos_buffer, 0;
+
+ $self->_buffer_item( { directive => 'FASTA', filehandle => $fh } );
+ shift @{$self->{filethings}};
+
+ # update file position
+ $pos_buffer = tell;
}
else { # it's a parse error
+ # Remember current position
+ $pos_buffer = tell;
+
chomp $line;
$self->_parse_error("parse error. Cannot parse '$line'.");
}
@@ -435,25 +459,4 @@ sub _resolve_references_from {
}
}
-sub _handle_implicit_fasta_start {
- my ( $self, $line ) = @_;
- require POSIX;
- require IO::Pipe;
- my $pipe = IO::Pipe->new;
- unless( fork ) {
- $pipe->writer;
- my $fh = $self->{filehandles}[0];
- undef $self;
- $pipe->print($line);
- while( $line = $fh->getline ) {
- $pipe->print( $line );
- }
- $pipe->close;
- POSIX::_exit(0);
- }
- $pipe->reader;
- shift @$_ for $self->{filehandles}, $self->{filethings};
- return { directive => 'FASTA', filehandle => $pipe };
-}
-
1;