File Coverage

blib/lib/IO/Buffered.pm
Criterion Covered Total %
statement 43 43 100.0
branch 3 4 75.0
condition 3 6 50.0
subroutine 12 12 100.0
pod 2 2 100.0
total 63 67 94.0


line stmt bran cond sub pod time code
1             package IO::Buffered;
2 8     8   220244 use strict;
  8         22  
  8         360  
3 8     8   42 use warnings;
  8         17  
  8         365  
4              
5             our $VERSION = '1.00';
6              
7 8     8   47 use Carp;
  8         39  
  8         813  
8              
9 8     8   4186 use IO::Buffered::Split;
  8         20  
  8         353  
10 8     8   48 use IO::Buffered::Regexp;
  8         14  
  8         305  
11 8     8   4450 use IO::Buffered::Size;
  8         19  
  8         421  
12 8     8   4504 use IO::Buffered::FixedSize;
  8         20  
  8         382  
13 8     8   4693 use IO::Buffered::Last;
  8         21  
  8         389  
14 8     8   4252 use IO::Buffered::HTTP;
  8         22  
  8         660  
15              
16             =head1 NAME
17              
18             IO::Buffered - A simple buffer class for dealing with different data types
19              
20             =head1 SYNOPSIS
21              
22             my $buf = new IO::Buffered(Split => qr/,/);
23             $buf->write("record1,reco")
24             $buf->write("rd2,record3");
25              
26             my @records = $buf->read(); # @records is now ("record1", "record2")
27             @records = $buf->read_last(); # @records is now ("record3")
28              
29              
30             =head1 DESCRIPTION
31              
32             IO::Buffered provides a simple unified way of dealing with buffering. This is
33             done by providing a set of buffering types each with an understanding of what
34             they are buffering. All buffering types share a common set of function for
35             working with the buffer.
36              
37             =over 4
38              
39             =item B
40              
41             C appends more data to the buffer if the buffer type allows it.
42             Different types might have rules that prohibit the buffer for growing over a
43             certain limit or mandates that only certain types of data be written to the
44             buffer.
45              
46             In case of error the number of bytes written to the buffer is returned and the
47             function croaks.
48              
49             =item B
50              
51             C returns the number of ready records as defined by the buffer type or
52             returns an empty array when no records are available. Read records will be
53             cleared from the buffer. $alt_size defines alternative size of the next record
54             in the buffer if the buffer type does not know how much data to buffer before
55             returning the record. This is currently used by the HTTP buffer type when it is
56             in HeaderOnly mode and needs to return the data part of a http request.
57              
58             =item B
59              
60             C returns the number of ready records as defined by the buffer type and
61             the rest of the buffer as the last record. Or returns an empty array when no records
62             are available. After C is called the buffer will be empty.
63              
64             =item B
65              
66             C flushes the buffer if no input or replace the buffer with the input.
67              
68             =item B
69              
70             C returns a copy of the buffer.
71              
72             =item B
73              
74             C tells if the buffer type knows if it's dealing with a
75             complete record or not. Or a call to is need to get all valid
76             records. An example of this is the "Split" buffer type where record delimiter
77             does not have to be at the end of every record:
78              
79             my $buffer = new IO::Buffered::Split(qr/\n/);
80             $buffer->write("Hello\nHello");
81            
82             if($buffer->returns_last) {
83             my @records = $buffer->read(); # @records would be ('Hello')
84             } else {
85             my @records = $buffer->read_last(); # @records is ('Hello', 'Hello')
86             }
87              
88             =cut
89              
90             =back
91              
92             =head1 BUFFER TYPES
93              
94             =head2 Regexp
95              
96             The Regexp buffer type takes a regular expression as input and splits records
97             based on that. Only the match defined in the () is returned and not the
98             complete match.
99              
100             An example would be C that would work as line buffing:
101              
102             my $buf = IO::Buffered(Regexp => qr/^(.+)\n/);
103              
104             Read more here: L
105              
106             =head2 Split
107              
108             Split is special case of the Regexp buffer type and is in essence just
109             C. Here only the non matching part of $split is returned.
110              
111             An example would be C that also works as line buffering or C
112             for C strings.
113            
114             my $buf = IO::Buffered(Split => qr/\n/);
115              
116             Read more here: L
117              
118             =head2 Size
119              
120             The Size buffering type reads the size from the data to determine where record
121             boundaries are. Only the data is returned not the bytes that hold the length
122             information. Size buffering takes two arguments, a L template and a offset
123             for the numbers of bytes to add to the length that was unpacked with the
124             template.
125              
126             An example would be a template of "n" and a offset of 0 that could be used to
127             handle DNS tcp requests. Offset defaults to 0 if not set.
128              
129             my $buf = IO::Buffered(Size => ["n", 0]);
130              
131             Read more here: L
132              
133             =head2 FixedSize
134              
135             FixedSize buffering returns records in fixed size chunks.
136              
137             An example would to return 100 bytes at a time:
138              
139             my $buf = IO::Buffered(FixedSize => 100);
140              
141             Read more here: L
142              
143             =head2 Last
144              
145             Last buffering simple only returns one record when read_last is called. All
146             calls to read will return an empty array.
147              
148             An example would be:
149              
150             my $buf = IO::Buffered(Last => 1);
151              
152             Read more here: L
153              
154             =head2 HTTP
155              
156             HTTP buffering provides a simple buffering for HTTP traffic by looking for
157             "Content-Length:" in the HTTP header. If one is found this will be used to
158             split records. If not only the header will be returned.
159              
160             An example would be:
161              
162             my $buf = IO::Buffered(HTTP => 1);
163              
164             Read more here: L
165              
166             =head1 GENERIC OPTIONS
167              
168             =head2 MaxSize
169              
170             MaxSize provides a limit on how big a buffer can grow, when the limit is hit an
171             exception is thrown.
172              
173             The default value for MaxSize is 0, meaning that there is no size limit on the
174             buffer.
175              
176             =head1 METHODS
177              
178             =over
179              
180             =cut
181              
182 8     8   43 use base "Exporter";
  8         14  
  8         3449  
183              
184             our @EXPORT_OK = qw(recroak);
185              
186             =item new()
187              
188             IO::Buffered simple provides a wrapper for the different buffering types. The
189             argument given to the buffer type is simply given as first argument to the
190             constructor of the buffer type, as show below:
191              
192             $buf = Buffered::IO(Split => qr/\n/);
193              
194             # is the same as
195              
196             $buf = Buffered::IO::Split(qr/\n/);
197              
198             Extra options are passed along as an array after first argument, as show below:
199              
200             $buf = Buffered::IO(Split => qr/\n/, MaxSize => 1000_000);
201              
202             # is the same as
203              
204             $buf = Buffered::IO::Split(qr/\n/, MaxSize => 1000_000);
205              
206             Buffered::IO recasts exceptions so there is no differences in using either
207             interface.
208              
209             =cut
210              
211             sub new {
212 25     25 1 16768 my ($class, %args) = @_;
213              
214 25         60 my ($type) = grep { exists $args{$_} }
  150         284  
215             qw(Split Regexp Size FixedSize Last HTTP); # Find buffer type
216 25 50       80 croak "Unknown or no buffer type defined" if !defined $type;
217              
218 2         10 my %opts = map { $_ => $args{$_} }
  27         95  
219 25         64 grep { $_ ne $type } keys %args; # Get options for buffer type
220              
221 25         66 my $package = "IO::Buffered::$type";
222 25 100       126 if($type =~ /HTTP|Last/) {
223 3   33     7 return (eval { new $package(%opts); }
224             or recroak($@));
225             } else {
226 22   66     29 return (eval { new $package($args{$type}, %opts); }
227             or recroak($@));
228             }
229             }
230              
231             =item recroak()
232              
233             Helper function to rethrow croaks
234              
235             =cut
236              
237             sub recroak {
238 18     18 1 448 $_[0] =~ s/ at \S+ line \d+.*$//s;
239 18         2351 croak $_[0];
240             }
241              
242             =back
243              
244             =head1 AUTHOR
245              
246             Troels Liebe Bentsen
247              
248             =head1 COPYRIGHT
249              
250             Copyright(C) 2008 Troels Liebe Bentsen
251              
252             This library is free software; you can redistribute it and/or modify
253             it under the same terms as Perl itself.
254              
255             =cut
256              
257             1;