File Coverage

blib/lib/Net/WebSocket/PMCE/deflate/Data/Streamer.pm
Criterion Covered Total %
statement 30 30 100.0
branch 8 8 100.0
condition n/a
subroutine 8 8 100.0
pod 2 3 66.6
total 48 49 97.9


line stmt bran cond sub pod time code
1             package Net::WebSocket::PMCE::deflate::Data::Streamer;
2              
3 3     3   22 use strict;
  3         5  
  3         94  
4 3     3   15 use warnings;
  3         6  
  3         107  
5              
6             =encoding utf-8
7              
8             =head1 NAME
9              
10             Net::WebSocket::PMCE::deflate::Data::Streamer
11              
12             =head1 SYNOPSIS
13              
14             my $streamer = $deflate_data->create_streamer( $frame_class );
15              
16             #These frames form a single compressed message in three
17             #fragments whose content is “onetwothree”.
18             my @frames = (
19             $streamer->create_chunk('one'),
20             $streamer->create_chunk('two'),
21             $streamer->create_final('three'),
22             );
23              
24             =head1 DESCRIPTION
25              
26             This class implements fragmentation for the permessage-deflate WebSocket
27             extension. It allows you to send a single message in arbitrarily many
28             parts. The class is not instantiated directly, but instances are returned
29             as the result of L’s
30             C method.
31              
32             Strictly speaking, this is a base class; the C<::Client> and C<::Server>
33             subclasses implement a bit of logic specific to either endpoint type.
34              
35             The C and C methods follow the same
36             pattern as L.
37              
38             =cut
39              
40 3     3   1128 use Module::Runtime ();
  3         3747  
  3         123  
41              
42 3     3   1413 use Net::WebSocket::Frame::continuation ();
  3         9  
  3         746  
43              
44             =head1 METHODS
45              
46             =cut
47              
48             sub new {
49 5     5 0 13 my ($class, $data_obj, $frame_class) = @_;
50              
51 5 100       58 Module::Runtime::require_module($frame_class) if !$frame_class->can('new');
52              
53 5         21 my $self = {
54             _data_obj => $data_obj,
55             _frame_class => $frame_class,
56             };
57              
58 5         30 return bless $self, $class;
59             }
60              
61             my ($_COMPRESS_FUNC, $_FIN);
62              
63             =head2 I->create_chunk( OCTET_STRING )
64              
65             Compresses OCTET_STRING. The compressor doesn’t necessarily produce output
66             from this, however. If the compressor does produce output, then this
67             method returns a frame object (an instance of either the streamer’s
68             assigned frame class or L); otherwise,
69             undef is returned.
70              
71             =cut
72              
73             sub create_chunk {
74 39     39 1 467165 $_COMPRESS_FUNC = '_compress_non_final_fragment';
75 39         118 $_FIN = 0;
76              
77 39         311 goto &_create;
78             }
79              
80             =head2 I->create_final( OCTET_STRING )
81              
82             Compresses OCTET_STRING and flushes the compressor. The output matches
83             that of C except that the output is always a frame object.
84             The output of this method will complete the message.
85              
86             =cut
87              
88             sub create_final {
89 5     5 1 17905 $_COMPRESS_FUNC = $_[0]->{'_data_obj'}{'final_frame_compress_func'};
90 5         12 $_FIN = 1;
91              
92 5         19 goto &_create;
93             }
94              
95             sub _create {
96 44     44   241 my ($self) = @_;
97              
98 44         205 my $data_obj = $self->{'_data_obj'};
99              
100 44         408 my $payload_sr = \($data_obj->$_COMPRESS_FUNC( $_[1] ));
101              
102 44 100       270 return undef if !length $$payload_sr;
103              
104 6 100       41 my $class = $self->{'_frames_count'} ? 'Net::WebSocket::Frame::continuation' : $self->{'_frame_class'};
105 6 100       67 my $rsv = $self->{'_frames_count'} ? 0 : $data_obj->INITIAL_FRAME_RSV();
106              
107 6         19 $self->{'_frames_count'}++;
108              
109 6         97 return $class->new(
110             payload => $payload_sr,
111             rsv => $rsv,
112             $data_obj->FRAME_MASK_ARGS(),
113             );
114             }
115              
116             1;