File Coverage

blib/lib/IO/Mux/Packet.pm
Criterion Covered Total %
statement 65 67 97.0
branch 20 22 90.9
condition 3 3 100.0
subroutine 13 13 100.0
pod 0 10 0.0
total 101 115 87.8


line stmt bran cond sub pod time code
1             package IO::Mux::Packet ;
2              
3 5     5   27295 use strict ;
  5         12  
  5         177  
4 5     5   27 use IO::Handle ;
  5         8  
  5         193  
5 5     5   24 use Carp ;
  5         34  
  5         3907  
6              
7              
8             our $VERSION = '0.08' ;
9              
10              
11             sub new {
12 84     84 0 563 my $class = shift ;
13 84         104 my $id = shift ;
14 84         150 my $data = shift ;
15              
16 84         124 my $this = {} ;
17 84         179 $this->{id} = $id ;
18 84         136 $this->{data} = $data ;
19 84         116 $this->{type} = 'D' ;
20              
21 84         297 return bless($this, $class) ;
22             }
23              
24              
25             sub get_length {
26 152     152 0 215 my $this = shift ;
27              
28 152 100       579 return (defined($this->{data}) ? length($this->{data}) : 0) ;
29             }
30              
31              
32             sub get_data {
33 81     81 0 93 my $this = shift ;
34              
35 81         498 return $this->{data} ;
36             }
37              
38              
39             sub get_id {
40 164     164 0 199 my $this = shift ;
41              
42 164         546 return $this->{id} ;
43             }
44              
45              
46             sub get_type {
47 112     112 0 121 my $this = shift ;
48              
49 112         363 return $this->{type} ;
50             }
51              
52              
53             sub is_eof {
54 62     62 0 74 my $this = shift ;
55              
56 62         111 return $this->get_type() eq 'E' ;
57             }
58              
59              
60             sub make_eof {
61 26     26 0 44 my $this = shift ;
62              
63 26         84 $this->{type} = 'E' ;
64 26         70 $this->{data} = 0 ;
65             }
66              
67              
68             sub serialize {
69 50     50 0 1245 my $this = shift ;
70              
71 50         95 my $len = length(
72             $this->get_id())
73             + 3
74             + $this->get_length() ;
75              
76             # We place the length in between 2 0x1 bytes in order to attempt
77             # to detect invalid data appearing in the filehandle.
78 50         201 return pack("CLC", 1, $len, 1) .
79             $this->get_id()
80             . "\t" . $this->get_type() . "\t"
81             . $this->get_data() ;
82             }
83              
84              
85             sub write {
86 47     47 0 123 my $this = shift ;
87 47         52 my $fh = shift ;
88              
89             # We do not write empty packets, but we still return success.
90 47 100       114 return 1 if ! $this->get_length() ;
91              
92 46         756 my $ret = print $fh $this->serialize() ;
93 46 100       187 if ($ret){
94 34         68 $ret = $this->get_length() ;
95             }
96              
97 46         129 return $ret ;
98             }
99              
100              
101             sub read {
102 44     44 0 557 my $class = shift ;
103 44         48 my $fh = shift ;
104              
105 44         56 my $len = '' ;
106 44         129 while (length($len) < 6){
107 45         256 my $rc = $fh->sysread($len, 6 - length($len), length($len)) ;
108 45 50       850 if (! defined($rc)){
    100          
109 0         0 return undef ;
110             }
111             elsif (! $rc){
112 5 100       23 return 0 if ! length($len) ;
113 1         183 croak("Unexpected EOF (incomplete packet length)") ;
114             }
115             }
116 39         57 my ($mb, $me) = () ;
117 39         149 ($mb, $len, $me) = unpack("CLC", $len) ;
118 39 100 100     186 if (($mb != 1)||($me != 1)){
119             # We have bad data on the handle
120 3         538 croak("Marker mismatch ($mb,$me) != (1,1): someone writing directly on IO::Mux Handle?") ;
121             }
122              
123 36         48 my $buf = '' ;
124 36         85 while (length($buf) < $len){
125 37         118 my $rc = $fh->sysread($buf, $len - length($buf), length($buf)) ;
126 37 50       498 if (! defined($rc)){
    100          
127 0         0 return undef ;
128             }
129             elsif (! $rc){
130 1         79 croak("Unexpected EOF (incomplete packet id or data)") ;
131             }
132             }
133              
134 35 100       244 if ($buf =~ s/^(.*?)\t([DE])\t//){
135 34         67 my $id = $1 ;
136 34         56 my $type = $2 ;
137 34         78 my $p = new IO::Mux::Packet($id, $buf) ;
138 34 100       78 if ($type eq 'E'){
139 7         20 $p->make_eof() ;
140             }
141 34         96 return $p ;
142             }
143             else {
144 1         95 croak("Malformed packet: $buf") ;
145             }
146             }
147              
148              
149              
150             1 ;