|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
4
  
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
133151
 | 
 use strict;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
180
 | 
    | 
| 
2
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
26
 | 
 use warnings;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
294
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Device::RFXCOM::RX;  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $Device::RFXCOM::RX::VERSION = '1.163170';  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Module to support RFXCOM RF receiver  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
141
 | 
 use 5.006;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use constant {  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   DEBUG => $ENV{DEVICE_RFXCOM_RX_DEBUG},  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   TESTING => $ENV{DEVICE_RFXCOM_RX_TESTING},  | 
| 
12
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
29
 | 
 };  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
430
 | 
    | 
| 
13
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
22
 | 
 use base 'Device::RFXCOM::Base';  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2290
 | 
    | 
| 
14
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
34
 | 
 use Carp qw/croak/;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
291
 | 
    | 
| 
15
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
24
 | 
 use IO::Handle;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
195
 | 
    | 
| 
16
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
21
 | 
 use IO::Select;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
147
 | 
    | 
| 
17
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
2636
 | 
 use Device::RFXCOM::Response;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
142
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use Module::Pluggable  | 
| 
19
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
   search_path => 'Device::RFXCOM::Decoder',  | 
| 
20
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
2639
 | 
   instantiate => 'new';  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52489
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
24
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
3992
 | 
   my $pkg = shift;  | 
| 
25
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
   $pkg->SUPER::_new(device => '/dev/rfxcom-rx', @_);  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _init {  | 
| 
29
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
5
 | 
   my ($self, $cb) = @_;  | 
| 
30
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   $self->_write(hex => 'F020', desc => 'version check');  | 
| 
31
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   $self->_write(hex => 'F02A', desc => 'enable all possible receiving modes');  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $self->_write(hex => 'F041', desc => 'variable length with visonic',  | 
| 
33
 | 
2
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
15
 | 
                 callback => $cb || $self->{init_callback});  | 
| 
34
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   $self->{init} = 1;  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub read {  | 
| 
39
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
591490
 | 
   my ($self, $timeout) = @_;  | 
| 
40
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   my $res = $self->read_one(\$self->{_buf});  | 
| 
41
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   return $res if (defined $res);  | 
| 
42
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
   $self->_discard_buffer_check() if ($self->{_buf} ne '');  | 
| 
43
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   $self->_discard_dup_cache_check();  | 
| 
44
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   my $fh = $self->filehandle;  | 
| 
45
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
   my $sel = IO::Select->new($fh);  | 
| 
46
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
302
 | 
  REDO:  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $start = $self->_time_now;  | 
| 
48
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
   $sel->can_read($timeout) or return;  | 
| 
49
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
277
 | 
   my $bytes = sysread $fh, $self->{_buf}, 2048, length $self->{_buf};  | 
| 
50
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
   $self->{_last_read} = $self->_time_now;  | 
| 
51
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   $timeout -= $self->{_last_read} - $start if (defined $timeout);  | 
| 
52
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
   unless ($bytes) {  | 
| 
53
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak defined $bytes ? 'closed' : 'error: '.$!;  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
55
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   $res = $self->read_one(\$self->{_buf});  | 
| 
56
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   $self->_write_now() if (defined $res);  | 
| 
57
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   goto REDO unless ($res);  | 
| 
58
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
111
 | 
   return $res;  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub read_one {  | 
| 
64
 | 
98
 | 
 
 | 
 
 | 
  
98
  
 | 
  
1
  
 | 
2078812
 | 
   my ($self, $rbuf) = @_;  | 
| 
65
 | 
98
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
333
 | 
   return unless ($$rbuf);  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
111
 | 
   print STDERR "rbuf=", (unpack "H*", $$rbuf), "\n" if DEBUG;  | 
| 
68
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
   my $header_byte = unpack "C", $$rbuf;  | 
| 
69
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
401
 | 
   my %result =  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     (  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      header_byte => $header_byte,  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      type => 'unknown',  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
74
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
274
 | 
   $result{master} = !($header_byte&0x80);  | 
| 
75
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
   my $bits = $header_byte & 0x7f;  | 
| 
76
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
   my $msg = '';  | 
| 
77
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
   my @bytes;  | 
| 
78
 | 
95
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
617
 | 
   if (exists $self->{_waiting} && $header_byte == 0x4d) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     print STDERR "got version check response\n" if DEBUG;  | 
| 
81
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $msg = $$rbuf;  | 
| 
82
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     substr $msg, 0, 1, '';  | 
| 
83
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $$rbuf = '';  | 
| 
84
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $result{type} = 'version';  | 
| 
85
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     @bytes = unpack 'C*', $msg;  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (exists $self->{_waiting} &&  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
            ( $header_byte == 0x2c || $header_byte == 0x41 )) {  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     print STDERR "got mode response\n" if DEBUG;  | 
| 
91
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     substr $$rbuf, 0, 1, '';  | 
| 
92
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     $result{type} = 'mode';  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($bits == 0) {  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     print STDERR "got empty message\n" if DEBUG;  | 
| 
97
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     substr $$rbuf, 0, 1, '';  | 
| 
98
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $result{type} = 'empty';  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
220
 | 
     my $length = $bits / 8;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
     print STDERR "bits=$bits length=$length\n" if DEBUG;  | 
| 
105
 | 
91
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
280
 | 
     return if (length $$rbuf < 1 + $length);  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
91
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
258
 | 
     if ($length != int $length) {  | 
| 
108
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
       $length = 1 + int $length;  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
252
 | 
     $msg = substr $$rbuf, 0, 1 + $length, ''; # message from buffer  | 
| 
112
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
163
 | 
     substr $msg, 0, 1, '';  | 
| 
113
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
465
 | 
     @bytes = unpack 'C*', $msg;  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
365
 | 
     $result{key} = $bits.'!'.$msg;  | 
| 
116
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
275
 | 
     my $entry = $self->_cache_get(\%result);  | 
| 
117
 | 
91
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
187
 | 
     if ($entry) {  | 
| 
118
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
       print STDERR "using cache entry\n" if DEBUG;  | 
| 
119
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
       @result{qw/messages type/} = @{$entry->{result}}{qw/messages type/};  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
120
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       $self->_cache_set(\%result);  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
122
 | 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
109
 | 
       foreach my $decoder (@{$self->{plugins}}) {  | 
| 
 
 | 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
262
 | 
    | 
| 
123
 | 
702
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2792
 | 
         my $matched = $decoder->decode($self, $msg, \@bytes, $bits, \%result)  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           or next;  | 
| 
125
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
666
 | 
         ($result{type} = lc ref $decoder) =~ s/.*:://;  | 
| 
126
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
         last;  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
128
 | 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
       $self->_cache_set(\%result);  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
332
 | 
   @result{qw/data bytes/} = ($msg, \@bytes);  | 
| 
133
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
706
 | 
   return Device::RFXCOM::Response->new(%result);  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _cache_get {  | 
| 
137
 | 
96
 | 
 
 | 
 
 | 
  
96
  
 | 
 
 | 
141
 | 
   my ($self, $result) = @_;  | 
| 
138
 | 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
322
 | 
   $self->{_cache}->{$result->{key}};  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _cache_set {  | 
| 
142
 | 
93
 | 
 
 | 
 
 | 
  
93
  
 | 
 
 | 
148
 | 
   my ($self, $result) = @_;  | 
| 
143
 | 
93
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
301
 | 
   return if ($result->{dont_cache});  | 
| 
144
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
189
 | 
   my $entry = $self->{_cache}->{$result->{key}};  | 
| 
145
 | 
90
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
274
 | 
   if ($entry) {  | 
| 
146
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     $result->{duplicate} = 1 if ($self->_cache_is_duplicate($entry));  | 
| 
147
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     $entry->{t} = $self->_time_now;  | 
| 
148
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     return $entry;  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $self->{_cache}->{$result->{key}} =  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
152
 | 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
308
 | 
      result => $result,  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      t => $self->_time_now,  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _cache_is_duplicate {  | 
| 
158
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
13
 | 
   my ($self, $entry) = @_;  | 
| 
159
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   ($self->_time_now - $entry->{t}) < $self->{dup_timeout};  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _discard_buffer_check {  | 
| 
163
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
   my $self = shift;  | 
| 
164
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
96
 | 
   if ($self->{_buf} ne '' &&  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->{_last_read} < ($self->_time_now - $self->{discard_timeout})) {  | 
| 
166
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{_buf} = '';  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _discard_dup_cache_check {  | 
| 
171
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
18
 | 
   my $self = shift;  | 
| 
172
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
   if ($self->{_last_read} < ($self->_time_now - $self->{dup_timeout})) {  | 
| 
173
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $self->{_cache} = {};  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |