File Coverage

lib/SMB/Parser.pm
Criterion Covered Total %
statement 54 58 93.1
branch 6 6 100.0
condition 5 6 83.3
subroutine 21 25 84.0
pod 19 20 95.0
total 105 115 91.3


line stmt bran cond sub pod time code
1             # SMB Perl library, Copyright (C) 2014 Mikhael Goikhman, migo@cpan.org
2             #
3             # This program is free software: you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation, either version 3 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package SMB::Parser;
17              
18 3     3   860 use strict;
  3         7  
  3         110  
19 3     3   16 use warnings;
  3         4  
  3         79  
20              
21 3     3   14 use bytes;
  3         4  
  3         26  
22 3     3   2977 use if (1 << 32 == 1), 'bigint'; # support native uint64 on 32-bit platforms
  3         25  
  3         18  
23 3     3   2029 use Encode 'decode';
  3         21664  
  3         2211  
24              
25             sub new ($$) {
26 3     3 1 453 my $class = shift;
27 3   100     19 my $data = shift // "";
28              
29 3         10 my $self = bless {}, $class;
30              
31 3         10 return $self->set($data);
32             }
33              
34             sub reset ($;$) {
35 23     23 1 1949 my $self = shift;
36 23   100     94 my $offset = shift || 0;
37              
38 23         35 $self->{offset} = $offset;
39              
40 23         73 return $self;
41             }
42              
43             sub set ($$;$) {
44 7     7 1 13 my $self = shift;
45              
46 7         24 $self->{data} = $_[0];
47 7         18 $self->{size} = length($_[0]);
48              
49 7         30 return $self->reset($_[1]);
50             }
51              
52 1     1 1 4 sub data { $_[0]->{data} }
53 2     2 1 8 sub size { $_[0]->{size} }
54 10     10 1 60 sub offset { $_[0]->{offset} }
55              
56             my %UINT_MODS = (
57             +1 => 'C',
58             +2 => 'v',
59             +4 => 'V',
60             -1 => 'C',
61             -2 => 'n',
62             -4 => 'N',
63             );
64              
65             sub uint ($$;$) {
66 66     66 0 98 my $self = shift;
67 66         76 my $n_bytes = shift;
68 66 100       123 my $be_factor = shift() ? -1 : 1;
69              
70 66         170 return unpack($UINT_MODS{$be_factor * $n_bytes}, $self->bytes($n_bytes));
71             }
72              
73             sub str ($$;$) {
74 9     9 1 11 my $self = shift;
75 9         13 my $n_bytes = shift;
76 9   50     33 my $enc = shift || 'UTF-16LE';
77              
78 9         19 return decode($enc, $self->bytes($n_bytes));
79             }
80              
81             sub bytes ($$) {
82 90     90 1 109 my $self = shift;
83 90         99 my $n_bytes = shift;
84              
85 90 100       266 my $n_avail = $self->{offset} + $n_bytes > $self->{size}
86             ? $self->{size} - $self->{offset} : $n_bytes;
87              
88 90 100       245 my $bytes = $self->{offset} > $self->{size} ? '' : substr($self->{data}, $self->{offset}, $n_avail);
89 90         114 $self->{offset} += $n_bytes;
90              
91 90         528 return $bytes;
92             }
93              
94             sub skip ($) {
95 9     9 1 13 my $self = shift;
96 9         12 my $n_bytes = shift;
97              
98 9         14 $self->{offset} += $n_bytes;
99              
100 9         24 return $self;
101             }
102              
103 14     14 1 4543 sub uint8 { uint($_[0], 1 ); }
104 26     26 1 1996 sub uint16 { uint($_[0], 2 ); }
105 17     17 1 593 sub uint32 { uint($_[0], 4 ); }
106 6     6 1 1605 sub uint16_be { uint($_[0], 2, 1); }
107 3     3 1 598 sub uint32_be { uint($_[0], 4, 1); }
108 1     1 1 4 sub uint64 { uint32($_[0]) + (uint32($_[0]) << 32); }
109 0     0 1   sub utf16 { str($_[0], $_[1]); }
110 0     0 1   sub utf16_be { str($_[0], $_[1], 'UTF-16BE'); }
111 0     0 1   sub fid1 { uint16($_[0]); }
112 0     0 1   sub fid2 { [ uint64($_[0]), uint64($_[0]) ]; }
113              
114             1;
115              
116             __END__