File Coverage

blib/lib/XDR/Decode.pm
Criterion Covered Total %
statement 55 55 100.0
branch 10 14 71.4
condition 3 9 33.3
subroutine 14 14 100.0
pod 0 11 0.0
total 82 103 79.6


line stmt bran cond sub pod time code
1             # Decode.pm - objects to deserialize XDR strings
2             # Copyright (C) 2000 Mountain View Data, Inc.
3             # Written by Gordon Matzigkeit , 2000-12-15
4             #
5             # This file is part of Perl XDR.
6             #
7             # Perl XDR is free software; you can redistribute it and/or modify it
8             # under the terms of the GNU General Public License as published by
9             # the Free Software Foundation; either version 2 of the License, or
10             # (at your option) any later version.
11             #
12             # Perl XDR is distributed in the hope that it will be useful, but
13             # WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15             # General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License
18             # along with this program; if not, write to the Free Software
19             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20             # USA
21              
22             package XDR::Decode;
23             # [guilt]
24             # [maint
25             # File: Decode.pm
26             # Summary: objects to deserialize XDR strings
27             # Package: Perl XDR
28             # Owner: Mountain View Data, Inc.
29             # Years: 2000
30             # Author: Gordon Matzigkeit
31             # Contact:
32             # Date: 2000-12-15
33             # License: GPL]
34             # [clemency]
35              
36 3     3   1391 use strict;
  3         4  
  3         111  
37 3     3   134 use Carp;
  3         6  
  3         2297  
38              
39              
40             # Initialize a new decoding session.
41             sub new
42             {
43 21     21 0 219 my ($type, $buf) = @_;
44 21         105 bless { buffer => $buf, offset => 0 }, $type;
45             }
46              
47              
48             # Append bytes to the decoding buffer.
49             sub append
50             {
51 1     1 0 3 my ($self, $data) = @_;
52 1         3 $self->{buffer} .= $data;
53             }
54              
55              
56             # Return the unconsumed buffer.
57             sub buffer
58             {
59 17     17 0 24 my ($self, $truncate) = @_;
60              
61 17         40 my $ret = substr ($self->{buffer}, $self->{offset});
62 17 100       36 if ($truncate)
63             {
64 16         24 $self->{buffer} = '';
65 16         22 $self->{offset} = 0;
66             }
67 17         48 return $ret;
68             }
69              
70              
71             # Add an RPC record fragment to the buffer. Return the unused bytes,
72             # if any.
73             sub fragment
74             {
75 1     1 0 4 my ($self, $rec) = @_;
76 1         9 my $dec = XDR::Decode->new ($rec);
77 1         7 my $len = $dec->unsigned;
78              
79 1         4 $self->append ($dec->inline ($len & ~(1 << 31)));
80 1         4 my $left = $dec->buffer;
81 1         2 my $leftlen = length $left;
82 1 50 33     12 croak "$leftlen too many bytes in RPC record.\n"
83             if ($len >> 31 && $leftlen > 0);
84              
85 1   33     15 return $leftlen && $left;
86             }
87              
88              
89             # Add a complete RPC record to the buffer.
90             sub record
91             {
92 1     1 0 6 my ($self, $rec) = @_;
93 1         2 my $remain;
94             do
95 1         2 {
96 1         5 $remain = $self->fragment ($rec);
97             } while ($remain);
98             }
99              
100              
101             # Fetch N bytes from the buffer.
102             sub inline
103             {
104 133     133 0 179 my ($self, $n) = @_;
105 133         238 my $left = length ($self->{buffer}) - $self->{offset};
106              
107 133 50       248 croak "Need $n bytes, but only have $left remaining in XDR buffer.\n"
108             if ($n > $left);
109              
110             # Take the slice they asked for.
111 133         247 my $ret = substr ($self->{buffer}, $self->{offset}, $n);
112              
113             # Advance the offset pointer.
114 133         176 $self->{offset} += $n;
115 133 100       277 if ($self->{offset} >= length $self->{buffer})
116             {
117             # Truncate the buffer to conserve memory.
118 12         19 $self->{offset} = 0;
119 12         24 $self->{buffer} = '';
120             }
121              
122 133         468 return $ret;
123             }
124              
125              
126             # Decode nothing at all.
127             sub void
128             {
129 1     1 0 10 return '';
130             }
131              
132              
133             # Decode an unsigned integer.
134             sub unsigned
135             {
136 102     102 0 123 my $self = shift;
137 102         196 return unpack ('N', $self->inline (4));
138             }
139              
140              
141             # Decode a variable-length opaque.
142             sub opaque
143             {
144             # opaque -> ()
145             # opaque[0] -> (0)
146             # opaque[10] -> (10)
147             # opaque<20> -> (0, 20)
148 24     24 0 46 my ($self, $min, $max) = @_;
149              
150 24 50       66 $min = $self->unsigned () if (! defined $min);
151 24 50 33     69 croak "Opaque length $min exceeds maximum $max."
152             if (defined $max && $min > $max);
153 24         44 my $ret = $self->inline ($min);
154            
155             # Strip the padded zeros.
156 24         34 my $dribble = $min & 3;
157 24 100       57 if ($dribble)
158             {
159 5         17 $self->inline (4 - $dribble);
160             }
161              
162 24         102 return $ret;
163             }
164              
165              
166             sub opaque_auth
167             {
168 17     17 0 28 my ($self) = @_;
169 17         33 return [ $self->unsigned, $self->opaque ];
170             }
171              
172              
173             # Unpack an RPC buffer.
174 3     3   1130 use XDR::RPC;
  3         8  
  3         207  
175             sub rpc
176             {
177 2     2 0 9 my ($self) = @_;
178 2         12 return XDR::RPC->decode ($self);
179             }
180              
181              
182             1;