File Coverage

blib/lib/XDR/RPC.pm
Criterion Covered Total %
statement 46 52 88.4
branch 12 16 75.0
condition 3 3 100.0
subroutine 9 11 81.8
pod 0 7 0.0
total 70 89 78.6


line stmt bran cond sub pod time code
1             # RPC.pm - base class for SunRPC packets
2             # Copyright (C) 2000 Mountain View Data, Inc.
3             # Written by Gordon Matzigkeit , 2000-12-16
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::RPC;
23             # [guilt]
24             # [maint
25             # File: RPC.pm
26             # Summary: base class for SunRPC packets
27             # Package: Perl XDR
28             # Owner: Mountain View Data, Inc.
29             # Years: 2000
30             # Author: Gordon Matzigkeit
31             # Contact:
32             # Date: 2000-12-16
33             # License: GPL]
34             # [clemency]
35              
36 3     3   936 use strict;
  3         5  
  3         102  
37 3     3   15 use Carp;
  3         5  
  3         476  
38              
39 3     3   49 use XDR ':msg_type';
  3         6  
  3         435  
40 3     3   552 use XDR::Decode;
  3         6  
  3         2681  
41              
42             sub XID () {0}
43             sub PRIVATE () {1}
44             sub ARGS () {2}
45             sub CRED () {3}
46             sub VERF () {4}
47             sub COOKED_ARGS () {5}
48              
49             sub new
50             {
51 10     10 0 24 my ($type, $xid, $private, $args, $cred, $verf) = @_;
52 10         221 return bless [$xid, $private, $args, $cred, $verf], $type;
53             }
54              
55              
56             sub xid
57             {
58 15     15 0 29 my ($self) = @_;
59 15         188 return $self->[XID];
60             }
61              
62              
63             sub private
64             {
65 22     22 0 24 my ($self) = @_;
66 22         411 return $self->[PRIVATE];
67             }
68              
69              
70             sub cred
71             {
72 0     0 0 0 my ($self) = @_;
73 0         0 return $self->[CRED];
74             }
75              
76              
77             sub verf
78             {
79 0     0 0 0 my ($self) = @_;
80 0         0 return $self->[VERF];
81             }
82              
83              
84             # Unpack the arguments to or result from an RPC.
85             sub args
86             {
87 8     8 0 20 my ($self, $callrep, @proto) = @_;
88              
89 8 100       34 if ($#proto < 0)
90             {
91             # Return the raw arguments...
92 2 50       13 return $self->[ARGS] if (! defined $callrep);
93              
94             # Or something from the last cooked ones.
95 0         0 return $self->[COOKED_ARGS]->[$callrep];
96             }
97 6         23 my ($dec) = XDR::Decode->new ($self->[ARGS]);
98              
99 6         10 my (@args, $i);
100 6         22 for ($i = 0; $i <= $#proto; $i ++)
101             {
102 8         24 my ($type, $name) = split (/ /, $proto[$i]);
103 8         11 my $tname = $type;
104 8   100     44 while (! ref $type && defined $callrep->{TYPES}->{$type})
105             {
106 4         7 $tname = $type;
107 4         15 $type = $callrep->{TYPES}->{$type};
108             }
109              
110 8 100       16 if (ref $type)
111             {
112             # Decode an interface-defined structure.
113 3         160 push (@args, eval "\$callrep->struct ('$tname', \$dec)");
114             }
115             else
116             {
117             # Decode a basic type.
118 5         264 push (@args, eval "\$dec->$type;");
119             }
120 8 50       43 croak $@ if $@;
121             }
122              
123 6         18 my $leftlen = length ($dec->buffer (1));
124 6 50       18 croak "$leftlen too many bytes in RPC arguments"
125             if ($leftlen > 0);
126              
127             # Cache the decoded values.
128 6         13 $self->[COOKED_ARGS] = \@args;
129 6         194 return @args;
130             }
131              
132              
133             # Unpack the buffer as if it is an RPC.
134             sub decode
135             {
136 10     10 0 19 my ($type, $dec) = @_;
137              
138 10 100       64 $dec = XDR::Decode->new ($dec)
139             if (! UNIVERSAL::isa ($dec, 'XDR::Decode'));
140              
141 10         28 my ($xid) = $dec->unsigned;
142 10         29 my ($msg_type) = $dec->unsigned;
143              
144 10 100       31 if ($msg_type == CALL)
    50          
145             {
146 7         1909 require 'XDR/RPC/Call.pm';
147 7         72 return XDR::RPC::Call->finish_decode ($dec, $xid);
148             }
149             elsif ($msg_type == REPLY)
150             {
151 3         1461 require 'XDR/RPC/Reply.pm';
152 3         17 return XDR::RPC::Reply->finish_decode ($dec, $xid);
153             }
154             else
155             {
156 0           croak "Unrecognized msg_type $msg_type";
157             }
158             }
159              
160              
161             1;