File Coverage

blib/lib/Chess/PGN/Extract/Stream.pm
Criterion Covered Total %
statement 21 57 36.8
branch 0 14 0.0
condition 0 3 0.0
subroutine 7 12 58.3
pod 4 4 100.0
total 32 90 35.5


line stmt bran cond sub pod time code
1             package Chess::PGN::Extract::Stream;
2 2     2   19062 use 5.008001;
  2         6  
  2         61  
3 2     2   8 use strict;
  2         2  
  2         46  
4 2     2   8 use warnings;
  2         2  
  2         49  
5              
6 2     2   8 use base 'Exporter::Tiny';
  2         2  
  2         648  
7             our @EXPORT = qw| pgn_file read_game read_games |;
8              
9 2     2   2524 use Carp qw| croak |;
  2         3  
  2         102  
10 2     2   1405 use File::Temp qw| tempdir tempfile |;
  2         27856  
  2         168  
11 2     2   337 use Chess::PGN::Extract 'read_games' => { -prefix => '_' };
  2         4  
  2         26  
12              
13             sub new {
14 0     0 1   my ( $class, $pgn_file ) = @_;
15              
16 0 0         croak ("'new' requires a PGN file name")
17             unless defined $pgn_file;
18              
19 0           my $self = {};
20 0           $self->{pgn_file} = $pgn_file;
21 0 0         open my $pgn_handle, '<', $pgn_file
22             or croak ("Cannot open PGN file: \"$pgn_file\"");
23 0           $self->{pgn_handle} = $pgn_handle;
24              
25 0           bless $self => $class;
26             }
27              
28 0     0 1   sub pgn_file { $_[0]->{pgn_file} }
29              
30             sub read_game {
31 0     0 1   ( $_[0]->read_games (1) )[0];
32             }
33              
34             sub read_games {
35 0     0 1   my $self = shift;
36 0           my ($limit) = @_;
37              
38 0           my $handle = $self->{pgn_handle};
39 0 0         return if eof $handle;
40              
41 0 0 0       if ( ( not defined $limit ) || $limit < 0 ) {
  0 0          
42             # Slurp the PGN file if $limit is not set or negative
43 0           my $all = do { local $/; <$handle> };
  0            
  0            
44 0           return ( _read_pgn_string ($all) );
45             }
46             elsif ( $limit == 0 ) {return}
47             else {
48 0           my @games;
49 0           my @lines = ( scalar readline $handle );
50 0           while ( my $line = readline $handle ) {
51 0 0         unless ( $line =~ /^\[Event / ) {
52             # We merely check the end of a game by the above regex.
53             # It should be implemented by a more strict manner.
54 0           push @lines, $line;
55             }
56             else {
57 0           push @games, join ( '', @lines );
58 0 0         unless ( --$limit > 0 ) {
59 0           return ( _read_pgn_string ( join ( '', @games ) ) );
60             }
61 0           @lines = ($line);
62             }
63             }
64 0           push @games, join ( '', @lines );
65 0           return ( _read_pgn_string ( join ( '', @games ) ) );
66             }
67             }
68              
69             # _read_pgn_string ($pgn_string) => @games
70             sub _read_pgn_string {
71 0     0     my ($pgn_string) = @_;
72              
73 0           my $tmp_dir = tempdir (
74             $ENV{TMPDIR} . "/chess_pgn_extract_stream_XXXXXXXX",
75             CLEANUP => 1 );
76 0           my ( $tmp_handle, $tmp_file ) = tempfile ( DIR => $tmp_dir );
77 0           print $tmp_handle $pgn_string;
78 0           close $tmp_handle;
79              
80 0           return ( _read_games ($tmp_file) );
81             }
82              
83             1;
84             __END__