File Coverage

blib/lib/Games/Go/AGA/Parse/Round.pm
Criterion Covered Total %
statement 81 98 82.6
branch 28 50 56.0
condition 6 11 54.5
subroutine 17 18 94.4
pod 3 9 33.3
total 135 186 72.5


line stmt bran cond sub pod time code
1             #===============================================================================
2             #
3             # FILE: Games::Go::AGA::Parse::Round.pm
4             #
5             # PODNAME: Games::Go::AGA::Parse::Round
6             # ABSTRACT: Parses lines from an AGA Tournament Round file
7             #
8             # AUTHOR: Reid Augustin (REID),
9             # COMPANY: LucidPort Technology, Inc.
10             # CREATED: 11/19/2010 03:13:05 PM PST
11             #===============================================================================
12              
13 1     1   620 use 5.008;
  1         3  
  1         39  
14 1     1   6 use strict;
  1         1  
  1         44  
15 1     1   6 use warnings;
  1         2  
  1         58  
16              
17             package Games::Go::AGA::Parse::Round;
18 1     1   493 use parent 'Games::Go::AGA::Parse';
  1         303  
  1         6  
19              
20 1     1   54 use Carp;
  1         2  
  1         89  
21 1     1   650 use Readonly;
  1         3187  
  1         68  
22 1     1   589 use String::Tokenizer;
  1         1430  
  1         33  
23 1     1   615 use Games::Go::AGA::Parse::Exceptions;
  1         2  
  1         57  
24 1     1   432 use Games::Go::AGA::Parse::Util qw( normalize_ID );
  1         2  
  1         932  
25              
26             our $VERSION = '0.042'; # VERSION
27              
28             sub white_id {
29 2     2 0 2 my ($self, $new) = @_;
30              
31 2 50       3 if (@_ > 1) {
32 0         0 $self->{white_id} = $new;
33             }
34 2   50     8 return $self->{white_id} || '';
35             }
36              
37             sub black_id {
38 1     1 0 2 my ($self, $new) = @_;
39              
40 1 50       3 if (@_ > 1) {
41 0         0 $self->{black_id} = $new;
42             }
43 1   50     3 return $self->{black_id} || '';
44             }
45              
46             sub result {
47 1     1 0 1 my ($self, $new) = @_;
48              
49 1 50       4 if (@_ > 1) {
50 0         0 $self->{result} = $new;
51             }
52 1   50     3 return $self->{result} || '';
53             }
54              
55             sub handicap {
56 1     1 0 1 my ($self, $new) = @_;
57              
58 1 50       3 if (@_ > 1) {
59 0         0 $self->{handicap} = $new;
60             }
61 1 50       3 return defined $self->{handicap} ? $self->{handicap} : '0';
62             }
63              
64             sub komi {
65 1     1 0 1 my ($self, $new) = @_;
66              
67 1 50       8 if (@_ > 1) {
68 0         0 $self->{komi} = $new;
69             }
70 1 50       3 return defined $self->{komi} ? $self->{komi} : '0';
71             }
72              
73             sub comment {
74 1     1 0 1 my ($self, $new) = @_;
75              
76 1 50       2 if (@_ > 1) {
77 0         0 $self->{comment} = $new;
78             }
79 1   50     9 return $self->{comment} || '';
80             }
81              
82             sub as_array {
83 0     0 1 0 my ($self, $new) = @_;
84              
85 0         0 my @ret;
86 0 0       0 if ($self->white_id) {
    0          
87 0         0 @ret = map(
88 0         0 { $self->$_ }
89             # fields, in order
90             qw(
91             white_id
92             black_id
93             result
94             handicap
95             komi
96             comment
97             ),
98             );
99             }
100             elsif (exists $self->{comment}) {
101 0         0 @ret = ($self->comment);
102             }
103 0 0       0 return wantarray ? @ret : \@ret;
104             }
105              
106             sub as_hash {
107 1     1 1 2 my ($self, $new) = @_;
108              
109 1         1 my %ret;
110 1 50       3 if ($self->white_id) {
    0          
111 6         12 %ret = map(
112 1         1 { $_, $self->$_ }
113             # fields
114             qw(
115             white_id
116             black_id
117             result
118             handicap
119             komi
120             comment
121             ),
122             );
123             }
124             elsif (exists $self->{comment}) {
125 0         0 %ret = (comment => $self->comment);
126             }
127 1 50       17 return wantarray ? %ret : \%ret;
128             }
129              
130             Readonly my $WHITE_ID => 0;
131             Readonly my $BLACK_ID => 1;
132             Readonly my $RESULT => 2;
133             Readonly my $HANDICAP => 3;
134             Readonly my $KOMI => 4;
135              
136             Readonly my %name_of_state => (
137             $WHITE_ID => 'white_id',
138             $BLACK_ID => 'black_id',
139             $RESULT => 'result',
140             $HANDICAP => 'handicap',
141             $KOMI => 'komi',
142             );
143              
144             *parse = \&parse_line; # alias parse to parse_line
145             sub parse_line {
146 2     2 1 2229 my ($self, $string) = @_;
147              
148 2         5 map { delete $self->{$_} }
  12         25  
149             qw(
150             white_id
151             black_id
152             result
153             handicap
154             komi
155             comment
156             );
157 2 50       7 return $self->as_hash if (not $string);
158 2         24 my $tokenizer = String::Tokenizer->new(
159             $string, # source string
160             # delimiters
161             # "~!@#\$\%^&*()`={}[]:;\"'<>,?/|\\\n",
162             "@#\$\n",
163             String::Tokenizer->RETAIN_WHITESPACE,
164             );
165 2         405 my $iter = $tokenizer->iterator;
166 2         103 $self->{source} = $string;
167 2         10 my $state = $WHITE_ID;
168             TOKEN:
169 2         13 while ($iter->hasNextToken) {
170 20         105 my $token = $iter->nextToken;
171             #print $self->err("state $state, token $token");
172 20 50 66     162 if ($token eq "\n") { # a carriage return?
    100          
    100          
173 0         0 last TOKEN;
174             }
175             elsif ($token !~ m/\S/ or # only whitespace
176             $token eq '') { # empty
177 9         25 next TOKEN; # ignore
178             }
179             elsif ($token eq '#') { # comment
180 2 100       4 if ($state != $WHITE_ID) {
181 1         9 $self->_parse_error(
182             error => "got comment, expected $name_of_state{$state}",
183             source => $self->{source},
184             );
185             }
186 1         7 $self->{comment} = join q{}, $iter->collectTokensUntil("\n");
187 1         55 last TOKEN;
188             }
189             else {
190             #print $self->err("state $state, token $token");
191 9 100       18 if ($state == $WHITE_ID) {
    100          
    100          
    100          
    50          
192 2         16 $self->{white_id} = normalize_ID($token);
193 2         5 $state = $BLACK_ID;
194             }
195             elsif ($state == $BLACK_ID) {
196 2         15 $self->{black_id} = normalize_ID($token);
197 2         4 $state = $RESULT;
198             }
199             elsif ($state == $RESULT) {
200 2         18 $self->{result} = $token;
201 2         3 $state = $HANDICAP;
202             }
203             elsif ($state == $HANDICAP) {
204 2         25 $self->{handicap} = 0 + $token; # numerify
205 2         4 $state = $KOMI;
206             }
207             elsif ($state == $KOMI) {
208 1         23 $self->{komi} = 0 + $token; # numerify
209 1         2 $state = $WHITE_ID;
210             }
211             else {
212 0         0 $self->_parse_error(
213             error => "unknown state: $state",
214             source => $self->{source},
215             );
216             }
217 9         38 next TOKEN;
218             }
219             }
220 1 50       3 if ($state != $WHITE_ID) {
221 0         0 $self->_parse_error(
222             error => "got end of line, expected $name_of_state{$state}",
223             source => $self->{source},
224             );
225             }
226 1         5 return $self->as_hash;
227             }
228              
229             1;
230              
231             __END__