File Coverage

blib/lib/YAML/Tiny/Stream.pm
Criterion Covered Total %
statement 35 38 92.1
branch 5 6 83.3
condition 3 3 100.0
subroutine 8 10 80.0
pod 4 4 100.0
total 55 61 90.1


line stmt bran cond sub pod time code
1             package YAML::Tiny::Stream;
2              
3             =pod
4              
5             =head2 NAME
6              
7             YAML::Tiny::Stream - Document psuedo-streaming for YAML::Tiny
8              
9             =head2 SYNOPSIS
10              
11             my $parser = YAML::Tiny::Stream->new('lots-of-documents.yml');
12            
13             while ( my $yaml = $parser->fetch ) {
14             # Handle the document
15             }
16              
17             =head2 DESCRIPTION
18              
19             To keep the design small and contained, L intentionally discards
20             support for streamed parsing of YAML documents.
21              
22             In situations where a file contains a very large number of very small YAML
23             documents, B provides a limited implementation of streaming
24             that scans for YAML's --- document separators and parses them one entire
25             document at a time.
26              
27             Please note this approach does come with caveats, as any situation in which a
28             triple dash occurs legitimately at the beginning of a line (such as in a quote)
29             may be accidently detected as a new document by mistake.
30              
31             If you really do need a "proper" streaming parser, then you should see L
32             or one of the other full blown YAML implementations.
33              
34             =head1 METHODS
35              
36             =cut
37              
38 2     2   27563 use 5.006;
  2         6  
  2         150  
39 2     2   10 use strict;
  2         3  
  2         56  
40 2     2   10 use Carp ();
  2         12  
  2         32  
41 2     2   2087 use IO::File 1.14 ();
  2         24638  
  2         60  
42 2     2   2337 use YAML::Tiny 1.40 ();
  2         15715  
  2         785  
43              
44             our $VERSION = '0.01';
45              
46              
47              
48              
49              
50             ######################################################################
51             # Constructor and Accessors
52              
53             =pod
54              
55             =head2 new
56              
57             my $stream = YAML::Tiny::Stream->new($file);
58              
59             The C constructor creates a new stream handle.
60              
61             It takes a single parameter of a file name, which it will open via L.
62              
63             In this quick initial implementation, the file handle will remain open until
64             the stream object is destroyed.
65              
66             =cut
67              
68             sub new {
69 1     1 1 855 my $class = shift;
70 1         3 my $file = shift;
71 1         10 my $handle = IO::File->new($file, 'r');
72              
73 1         153 bless {
74             file => $file,
75             handle => $handle,
76             buffer => '',
77             }, $class;
78             }
79              
80             =pod
81              
82             =head2 file
83              
84             The C accessor returns the original file passed to the constructor.
85              
86             =cut
87              
88             sub file {
89 0     0 1 0 $_[0]->{file};
90             }
91              
92             =pod
93              
94             =head2 handle
95              
96             The C accessor returns the IO handle being used to read in the YAML
97             stream.
98              
99             =cut
100              
101             sub handle {
102 0     0 1 0 $_[0]->{handle};
103             }
104              
105              
106              
107              
108              
109             ######################################################################
110             # Main Methods
111              
112             =pod
113              
114             =head2 fetch
115              
116             my $yaml_tiny = $stream->fetch;
117              
118             The C method reads from the file until it hits the end of the next
119             document. This document is then passed to L to be parsed.
120              
121             Returns a L object containing a single document, or C if
122             there are no more documents in the stream. Throws an exception if there is
123             an IO or parsing error.
124              
125             =cut
126              
127             sub fetch {
128 4     4 1 3093 my $self = shift;
129 4         11 my $handle = $self->{handle};
130 4         6 my $buffer = $self->{buffer};
131              
132             # Fetch lines until we hit the --- for the next document
133 4         38 while ( defined( my $line = <$handle> ) ) {
134 6 100 100     34 if ( $line =~ /^---\s/ and length $buffer ) {
135             # Stash the line for the next document
136 2         5 $self->{buffer} = $line;
137              
138             # Attempt to parse the completed file
139 2         7 return $self->_parse($buffer);
140             } else {
141 4         18 $buffer .= $line;
142             }
143             }
144              
145             # Parse the final document
146 2 100       6 if ( length $buffer ) {
147 1         2 $self->{buffer} = '';
148 1         2 return $self->_parse($buffer);
149             }
150              
151             # Nothing left to parse
152 1         3 return undef;
153             }
154              
155             sub _parse {
156 3     3   3 my $self = shift;
157 3         588 my $yaml = YAML::Tiny->read_string(shift);
158 3 50       546 unless ( defined $yaml ) {
159 0         0 Carp::croak("Parsing Error: " . YAML::Tiny->errstr);
160             }
161 3         10 return $yaml;
162             }
163              
164             1;
165              
166             =pod
167              
168             =head1 SUPPORT
169              
170             Bugs should be reported via the CPAN bug tracker at
171              
172             L
173              
174             For other issues, contact the author.
175              
176             =head1 AUTHOR
177              
178             Adam Kennedy Eadamk@cpan.orgE
179              
180             =head1 SEE ALSO
181              
182             L, L, L, L,
183             L, L
184              
185             =head1 COPYRIGHT
186              
187             Copyright 2011 Adam Kennedy.
188              
189             This program is free software; you can redistribute
190             it and/or modify it under the same terms as Perl itself.
191              
192             The full text of the license can be found in the
193             LICENSE file included with this module.
194              
195             =cut