File Coverage

blib/lib/Mojo/IOLoop/Stream/Role/LineBuffer.pm
Criterion Covered Total %
statement 26 26 100.0
branch 5 6 83.3
condition 1 2 50.0
subroutine 5 5 100.0
pod 2 2 100.0
total 39 41 95.1


line stmt bran cond sub pod time code
1             package Mojo::IOLoop::Stream::Role::LineBuffer;
2              
3 1     1   1873 use Mojo::Base -role;
  1         3  
  1         8  
4              
5             our $VERSION = '0.007';
6              
7             has 'read_line_separator' => sub { qr/\x0D?\x0A/ };
8             has 'write_line_separator' => "\x0D\x0A";
9              
10             requires qw(on emit write);
11              
12             sub watch_lines {
13 6     6 1 14459 my $self = shift;
14 6 50       20 return $self if $self->{_read_line_read_cb};
15             $self->{_read_line_read_cb} = $self->on(read => sub {
16 8     8   5148 my ($self, $bytes) = @_;
17 8         24 $self->{_read_line_buffer} .= $bytes;
18 8         26 my $sep = $self->read_line_separator;
19 8         168 while ($self->{_read_line_buffer} =~ s/^(.*?)($sep)//s) {
20 7         53 $self->emit(read_line => "$1", "$2");
21             } continue {
22 7         106 $sep = $self->read_line_separator;
23             }
24 6         38 });
25             $self->{_read_line_close_cb} = $self->on(close => sub {
26 6     6   2566 my $self = shift;
27 6 100 50     27 if (length($self->{_read_line_buffer} // '')) {
28 3         7 my $sep = $self->read_line_separator;
29 3         77 while ($self->{_read_line_buffer} =~ s/^(.*?)($sep)//s) {
30 2         12 $self->emit(read_line => "$1", "$2");
31             } continue {
32 2         35 $sep = $self->read_line_separator;
33             }
34 3 100       38 if (length(my $buffer = $self->{_read_line_buffer})) {
35 2         5 $self->{_read_line_buffer} = '';
36 2         6 $self->emit(read_line => $buffer);
37             }
38             }
39 6         62 });
40 6         40 return $self;
41             }
42              
43             sub write_line {
44 3     3 1 1391 my ($self, $line) = (shift, shift);
45 3         10 my $sep = $self->write_line_separator;
46 3         36 $self->write("$line$sep", @_);
47             }
48              
49             1;
50              
51             =head1 NAME
52              
53             Mojo::IOLoop::Stream::Role::LineBuffer - Read and write streams by lines
54              
55             =head1 SYNOPSIS
56              
57             use Mojo::IOLoop;
58             Mojo::IOLoop->client({port => 3000} => sub {
59             my ($loop, $err, $stream) = @_;
60             $stream->with_roles('+LineBuffer')->watch_lines->on(read_line => sub {
61             my ($stream, $line) = @_;
62             say "Received line: $line";
63             $stream->write_line('Line received');
64             });
65             });
66              
67             =head1 DESCRIPTION
68              
69             L composes the method
70             L which causes a L object to emit the
71             L event for each line received. The L method is
72             also provided to add a line separator to the passed data before writing.
73              
74             =head1 EVENTS
75              
76             L can emit the following events.
77              
78             =head2 read_line
79              
80             $stream->on(read_line => sub {
81             my ($stream, $line, $separator) = @_;
82             ...
83             });
84              
85             Emitted when a line ending in L arrives on the stream,
86             and when the stream closes if data is still buffered. The separator is passed
87             as a separate argument if present.
88              
89             =head1 ATTRIBUTES
90              
91             L composes the following attributes.
92              
93             =head2 read_line_separator
94              
95             my $separator = $stream->read_line_separator;
96             $stream = $stream->read_line_separator(qr/\x0D\x0A/);
97              
98             Regular expression to indicate new lines in received bytes. Defaults to a
99             newline (LF) character optionally preceded by a CR character (C<\x0D?\x0A>).
100             Note that if you set this to L or
101             C<\v> (vertical whitespace), this may match the CR character of a CR/LF
102             sequence and consider the LF as a separate line if they are read separately.
103              
104             =head2 write_line_separator
105              
106             my $separator = $stream->write_line_separator;
107             $stream = $stream->write_line_separator("\x0A");
108              
109             Byte sequence to indicate new lines in data written with L.
110             Defaults to the network newline CR/LF (C<\x0D\x0A>).
111              
112             =head1 METHODS
113              
114             L composes the following methods.
115              
116             =head2 watch_lines
117              
118             $stream = $stream->watch_lines;
119              
120             Subscribe to the L and
121             L events, to buffer received bytes and emit
122             L when L is encountered or the stream is
123             closed with buffered data.
124              
125             =head2 write_line
126              
127             $stream = $stream->write_line($bytes);
128             $stream = $stream->write_line($bytes => sub {...});
129              
130             Write a line to the stream by appending L to the data.
131             The optional drain callback will be executed once all data has been written.
132              
133             =head1 BUGS
134              
135             Report any issues on the public bugtracker.
136              
137             =head1 AUTHOR
138              
139             Dan Book
140              
141             =head1 COPYRIGHT AND LICENSE
142              
143             This software is Copyright (c) 2018 by Dan Book.
144              
145             This is free software, licensed under:
146              
147             The Artistic License 2.0 (GPL Compatible)
148              
149             =head1 SEE ALSO
150              
151             L, L, L,
152             L