File Coverage

lib/Net/EGTS/Util.pm
Criterion Covered Total %
statement 71 71 100.0
branch 8 12 66.6
condition 3 5 60.0
subroutine 25 25 100.0
pod 12 12 100.0
total 119 125 95.2


line stmt bran cond sub pod time code
1 15     15   52492 use utf8;
  15         25  
  15         84  
2 15     15   400 use strict;
  15         20  
  15         243  
3 15     15   53 use warnings;
  15         25  
  15         474  
4              
5             package Net::EGTS::Util;
6 15     15   62 use base qw(Exporter);
  15         20  
  15         1593  
7              
8 15     15   80 use Carp;
  15         38  
  15         747  
9 15     15   5579 use Digest::CRC qw();
  15         28709  
  15         302  
10 15     15   5515 use Date::Parse qw();
  15         84962  
  15         406  
11 15     15   2287 use List::MoreUtils qw(natatime any);
  15         48410  
  15         97  
12 15     15   15759 use POSIX qw();
  15         74023  
  15         705  
13              
14             our @EXPORT = qw(
15             crc8 crc16
16             str2time time2new new2time strftime
17             dumper_bitstring
18             usize
19             lat2mod mod2lat
20             lon2mod mod2lon
21             );
22              
23             =head1 NAME
24              
25             Net::EGTS::Util - Utility functions.
26              
27             =cut
28              
29 15     15   84 use constant TIMESTAMP_20100101_000000_UTC => 1262304000;
  15         23  
  15         877  
30              
31             =head2 crc8 $bytes
32              
33             CRC8 with EGTS customization
34              
35             =cut
36              
37             sub crc8($) {
38 15     15   5684 use bytes;
  15         156  
  15         70  
39 17     17 1 89 my $ctx = Digest::CRC->new(
40             width => 8,
41             poly => 0x31,
42             init => 0xff,
43             xorout => 0x00,
44             check => 0xf7,
45             );
46 17         1254 $ctx->add($_[0]);
47 17         153 return $ctx->digest;
48             }
49              
50             =head2 crc16 $bytes
51              
52             CRC16 with EGTS customization
53              
54             =cut
55              
56             sub crc16($) {
57 15     15   991 use bytes;
  15         27  
  15         80  
58 10     10 1 36 my $ctx = Digest::CRC->new(
59             width => 16,
60             poly => 0x1021,
61             init => 0xffff,
62             xorout => 0x0000,
63             check => 0x29b1,
64             );
65 10         595 $ctx->add($_[0]);
66 10         59 return $ctx->digest;
67             }
68              
69             =head2 strftime $format, time
70              
71             Return formatted string.
72              
73             =cut
74              
75             sub strftime {
76 1     1 1 73 POSIX::strftime @_;
77             }
78              
79             =head2 str2time $str
80              
81             Return timestamp from any time format
82              
83             =cut
84              
85             sub str2time($) {
86 2 50   2 1 6 return undef unless defined $_[0];
87 2 50       6 return undef unless length $_[0];
88 2 50       11 return $_[0] if $_[0] =~ m{^\d+$};
89 2         9 return Date::Parse::str2time( $_[0] );
90             }
91              
92             =head2 time2new [$time]
93              
94             Return time from 2010 instead of 1970
95              
96             =cut
97              
98             sub time2new(;$) {
99 5     5 1 569 my ($time) = @_;
100 5   66     15 $time //= time;
101 5         15 return ($time - TIMESTAMP_20100101_000000_UTC);
102             }
103              
104             =head2 new2time [$time]
105              
106             Return time from 1970 instead of 2010
107              
108             =cut
109              
110             sub new2time($) {
111 1     1 1 55 my ($time) = @_;
112 1         12 return ($time + TIMESTAMP_20100101_000000_UTC);
113             }
114              
115             =head2 dumper_bitstring $bin, [$size]
116              
117             Return bitstring from I<$bin> chanked by I<$size>
118              
119             =cut
120              
121             sub dumper_bitstring($;$) {
122 6     6 1 16 my ($bin, $size) = @_;
123 6         78 my @bytes = ((unpack('B*', $bin)) =~ m{.{8}}g);
124 6   50     44 my $it = natatime( ($size || 4), @bytes );
125 6         9 my @chunks;
126 6         30 while (my @vals = $it->()) {
127 44         112 push @chunks, join ' ', @vals;
128             }
129 6         42 return join "\n", @chunks;
130             }
131              
132             =head2 usize $mask
133              
134             Return size in bytes of pack/unpack mask
135              
136             =cut
137              
138             sub usize($) {
139 439     439 1 2015 my ($mask) = @_;
140 15     15   4801 use bytes;
  15         27  
  15         52  
141 439 50       577 die 'Unknown "*" length' if $mask =~ m{^\w\*$};
142 439         1266 return length pack $mask => 0;
143             }
144              
145             =head2 lat2mod $latitude
146              
147             Module from latitude
148              
149             =cut
150              
151             sub lat2mod($) {
152 2     2 1 3238 return int( abs( $_[0] ) / 90 * 0xffffffff );
153             }
154              
155             =head2 mod2lat $module, $sign
156              
157             Latitude from module and sign
158              
159             =cut
160              
161             sub mod2lat($$) {
162 3     3 1 1958 my ($module, $sign) = @_;
163 3 100       54 return $_[0] / 0xffffffff * 90 * ($sign ? -1 : 1);
164             }
165              
166             =head2 lon2mod $longitude
167              
168             Module from longitude
169              
170             =cut
171              
172             sub lon2mod($) {
173 2     2 1 2057 return int( abs( $_[0] ) / 180 * 0xffffffff );
174             }
175              
176             =head2 mod2lon $module, $sign
177              
178             Longitude from module and sign.
179              
180             =cut
181              
182             sub mod2lon($$) {
183 3     3 1 2072 my ($module, $sign) = @_;
184 3 100       33 return $_[0] / 0xffffffff * 180 * ($sign ? -1 : 1);
185             }
186              
187             1;