File Coverage

blib/lib/RPC/Serialized.pm
Criterion Covered Total %
statement 67 70 95.7
branch 35 48 72.9
condition 17 42 40.4
subroutine 14 14 100.0
pod 2 3 66.6
total 135 177 76.2


line stmt bran cond sub pod time code
1             package RPC::Serialized;
2             {
3             $RPC::Serialized::VERSION = '1.123630';
4             }
5              
6 26     26   24528 use strict;
  26         47  
  26         1070  
7 26     26   153 use warnings FATAL => 'all';
  26         46  
  26         937  
8              
9 26     26   130 use base 'Class::Accessor::Fast::Contained';
  26         44  
  26         32291  
10              
11 26     26   224594 use Readonly;
  26         96897  
  26         2774  
12 26     26   36804 use Data::Serializer;
  26         81127  
  26         921  
13 26     26   18838 use RPC::Serialized::Config;
  26         104  
  26         235  
14 26     26   30466 use RPC::Serialized::Exceptions;
  26         90  
  26         215  
15              
16             __PACKAGE__->mk_ro_accessors(qw/
17             debug
18             /);
19             __PACKAGE__->mk_accessors(qw/
20             ds
21             ifh ofh
22             /);
23              
24             # this is the record separator in our data stream,
25             # used if debug is enabled
26             Readonly my $TERMINATOR => '...';
27              
28             sub new {
29 17     17 1 83491 my $class = shift;
30 17         833 my $params = RPC::Serialized::Config->parse(@_);
31              
32 17 50 33     9868 throw_app 'Missing or invalid input handle'
33             if exists $params->me->{ifh}
34             and ! _is_valid_input_handle( $params->me->{ifh} );
35              
36 17 50 33     125 throw_app 'Missing or invalid output handle'
37             if exists $params->me->{ofh}
38             and ! _is_valid_output_handle( $params->me->{ofh} );
39              
40 17 50       105 $params->me->{ofh}->autoflush(1) if exists $params->me->{ofh};
41 17         2516 $params->me->{ds} = Data::Serializer->new($params->data_serializer);
42              
43 17         252415 return $class->SUPER::new({ $params->me });
44             }
45              
46             sub _is_valid_handle {
47 34     34   88 my $h = shift;
48 34 50 33     2825 return 1
      33        
49             if defined $h
50             and ref $h
51             and $h->can('error');
52 0         0 return 0;
53             }
54              
55             sub _is_valid_input_handle {
56 17     17   1796 my $h = shift;
57 17 50 33     148 return 1
      33        
58             if _is_valid_handle($h)
59             and $h->can('getline')
60             and $h->can('eof');
61 0         0 return 0;
62             }
63              
64             sub _is_valid_output_handle {
65 17     17   1471 my $h = shift;
66 17 50 33     117 return 1
      33        
      33        
67             if _is_valid_handle($h)
68             and $h->can('print')
69             and $h->can('autoflush')
70             and $h->can('error');
71 0         0 return 0;
72             }
73              
74             sub send {
75 46     46 1 15251 my $self = shift;
76 46         84 my $data = shift;
77              
78 46 100       229 throw_proto 'Data not a hash reference'
79             unless ref($data) eq 'HASH';
80              
81 42         271 my $io = $self->ofh;
82              
83 42 100       576 if ($self->debug) {
84 2         30 my $send_data = $self->ds->raw_serialize($data);
85 2 50 33     223 $io->print( $send_data .
    50          
86             ($send_data =~ m/\n$/ ? '' : "\n") . "$TERMINATOR\n" )
87             and not $io->error
88             or throw_system "Failed to send data: $!";
89             }
90             else {
91 40 50 33     623 $io->print( $self->ds->serialize($data) . "\n" )
92             and not $io->error
93             or throw_system "Failed to send data: $!";
94             }
95             }
96              
97             sub recv {
98 51     51 0 6935 my $self = shift;
99 51         125 my $data = '';
100 51         285 my $io = $self->ifh;
101              
102 51 100       4808 if ($self->debug) {
103 4   66     37 while ( $_ = $io->getline and not $io->error ) {
104 10 100       224 last if /^\Q$TERMINATOR\E$/o;
105 8         63 $data .= $_;
106             }
107             }
108             else {
109 47         2403 $data = $io->getline;
110             }
111              
112 51 50       241534 throw_system "Failed to read data: $!"
113             if $io->error;
114              
115 51 100       494 chomp $data if defined $data;
116 51 100 66     1431 return unless defined($data) && length($data);
117              
118 46         134 my @token = ();
119 46         119 eval {
120 46 100       278 if ($self->debug) {
121 4         57 $data = $self->ds->raw_deserialize($data);
122             }
123             else {
124 42         1054 my $token = $self->ds->_get_token($data);
125 42 100       1389 @token = $self->ds->_extract_token($token) if defined $token;
126              
127 42         904 $data = $self->ds->deserialize($data);
128             }
129             };
130 46 100       15178 throw_proto "Data::Serializer error: $@"
131             if $@;
132              
133 43 100 66     417 throw_proto 'Serializer parse error'
134             if !defined $data or $data == 1;
135              
136 42 50       182 throw_proto 'Data not a hash reference'
137             if ref($data) ne 'HASH';
138              
139             return (wantarray
140 42 100       548 ? ($data, @token)
141             : $data);
142             }
143              
144             sub DESTROY {
145 17     17   31440 my $self = shift;
146 17 50       102 $self->ifh->close if $self->ifh;
147 17 50       1447 $self->ofh->close if $self->ofh;
148             }
149              
150             1;
151              
152             # ABSTRACT: Subroutine calls over the network using common serialization
153              
154              
155             # Here are some of the less common error messages. When more time is available
156             # these will be futher documented:
157             #
158             # =over 4
159             #
160             # =item C in an C
161             #
162             # The authorization scheme loaded has refused to permit the current subject to
163             # make the current call.
164             #
165             # =item C in an C
166             #
167             # The C server will look for the C environment
168             # variable, if authorization is enabled. See the C documentation for
169             # details if you don't know how to enable this.
170             #
171             # =item C in an C
172             #
173             # The C server will look for the C environment
174             # variable, if authorization is enabled. See the documentation for
175             # details if you don't know how to enable this.
176             #
177             # =item C in an C
178             #
179             # The C server failed to get the username for the calling user. Only
180             # happens if authorization has been enabled.
181             #
182             # =item C in an C
183             #
184             # Server authorization is enabled but the specified handler does not inherit
185             # from L.
186             #
187             # =item C in an C
188             #
189             # =item C in an C
190             #
191             # =item C in an C
192             #
193             # =item C in an C
194             #
195             # =item C in an C
196             #
197             # =item C in an C
198             #
199             # =item C in an C
200             #
201             # =item C in an C
202             #
203             # =item C in an C
204             #
205             # =item C in an C
206             #
207             # =item C in an C
208             #
209             # =item C in an C
210             #
211             # =item C in an C
212             #
213             # =back
214              
215              
216             __END__