File Coverage

blib/lib/COPE/CORBA/BOA.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             # $Id: BOA.pm,v 1.10 1997/07/31 11:03:52 schuller Exp $
2             # Copyright (c) 1997 Lunatech Research / Bart Schuller
3             # See the file "Artistic" in the distribution for licensing and
4             # (lack of) warranties.
5             # interface CORBA::BOA
6              
7             package CORBA::BOA;
8 3     3   2566 use COPE::CORBA::ServerRequest;
  3         8  
  3         84  
9 3     3   1519 use COPE::GIOP;
  3         12  
  3         90  
10 3     3   2652 use IO::Socket;
  3         106816  
  3         16  
11 3     3   5657 use Net::Domain ();
  3         18772  
  3         84  
12 3     3   1924 use COPE::CORBA::Exception;
  0            
  0            
13             use Data::Dumper;
14              
15             $CORBA::BOA::_The_Boa = 0;
16              
17             sub myread ($\$$;$);
18             sub mywrite ($\$$);
19              
20             sub new {
21             my($class,$orb,$argv,$boa_identifier) = @_;
22             my $boa = {};
23             my $domain = Net::Domain::hostfqdn();
24             $domain =~ s/[\r\n]+//g;
25             $boa->{host} = $domain;
26             $boa->{port} = $orb->{port};
27             my $localaddr = $domain;
28             if ($boa->{port}) {
29             $localaddr .= ":$boa->{port}";
30             }
31             $boa->{'socket'} = IO::Socket::INET->new(
32             LocalAddr => $localaddr,
33             Proto => 'tcp',
34             Listen => 5,
35             Reuse => 1 );
36             $boa->{port} ||= $boa->{'socket'}->sockport();
37             $boa->{byte_order} = $orb->{byte_order};
38             $boa->{'clients'} = [];
39              
40             return $CORBA::BOA::_The_Boa = bless $boa, $class;
41             }
42              
43             sub create ($$$$) {
44             my($self,$id,$intf,$impl) = @_;
45             }
46              
47             sub _create ($$$) {
48             my($self,$id,$idef,$impl) = @_;
49             my $obj = {};
50             $obj->{'id'} = $id;
51             $obj->{'interface'} = $idef;
52             $obj->{'impl'} = $impl;
53             $self->{'objects'}{$id} = $obj;
54             $self->{'skeletons'}{$impl} = $obj;
55             return bless $obj, 'CORBA::Object';
56             }
57              
58             sub dispose ($$) {
59             my($self,$obj) = @_;
60             }
61              
62             sub get_id ($$) {
63             my($self,$obj) = @_;
64             return $obj->{'id'};
65             }
66              
67             sub change_implementation ($$$) {
68             my($self,$obj,$impl) = @_;
69             # Remove the old implementation from the skeletons hash
70             delete $self->{'skeletons'}{$obj->{'impl'}};
71             $obj->{'impl'} = $impl;
72             $self->{'skeletons'}{$impl} = $obj;
73             }
74              
75             sub impl_is_ready ($$) {
76             my($self,$impl) = @_;
77             my $server = $self->{'socket'};
78             my($rin,$rout,$client);
79             while(1) {
80             $rin = '';
81             foreach ($server, @{$self->{'clients'}}) {
82             vec($rin,fileno($_),1) = 1;
83             }
84             select($rout=$rin, undef, undef, undef);
85             foreach (@{$self->{'clients'}}) {
86             if(vec($rout,fileno($_),1)) {
87             $self->_handle_request($_);
88             }
89             }
90             if (vec($rout,fileno($server),1)) {
91             ($client, undef) = $server->accept;
92             push @{$self->{'clients'}}, $client;
93             $self->_handle_request($client);
94             }
95             }
96             }
97              
98             sub deactivate_impl ($$) {
99             my($self,$impl) = @_;
100             }
101              
102             sub obj_is_ready ($$$) {
103             my($self,$obj,$impl) = @_;
104             }
105              
106             sub deactivate_obj ($$) {
107             my($self,$obj) = @_;
108             }
109              
110             # not in interface
111              
112             sub _handle_request {
113             my($self,$socket) = @_;
114             my($data,$index,$byte_order, $client_ind);
115             if( myread($socket,$data, 12) <= 0 ) {
116             # client has left, have to remove the client.
117             $client_ind = 0;
118             foreach( @{$self->{'clients'}} ) {
119             if( $_ eq $socket ) {
120             splice( @{$self->{'clients'}}, $client_ind, 1 );
121             # remove this entry from array
122             }
123             $client_ind += 1;
124             }
125             return;
126             }
127              
128             $index = 0;
129             my $msgh = GIOP::MessageHeader::_unmarshal(\$data, \$index, \$byte_order);
130             if( myread($socket,$data, $msgh->{message_size},$index) <= 0 ) {
131             # client has left, have to remove the client.
132             $client_ind = 0;
133             foreach( @{$self->{'clients'}} ) {
134             if( $_ eq $socket ) {
135             splice( @{$self->{'clients'}}, $client_ind, 1 );
136             # remove this entry from array
137             }
138             $client_ind += 1;
139             }
140             return;
141             }
142              
143             my $rh = GIOP::RequestHeader::_unmarshal(\$data, \$index, $byte_order);
144             my $target = $self->{objects}{$rh->{object_key}};
145             if (!$target) {
146             die "No such object: $rh->{object_key}";
147             }
148             my $operation = $rh->{operation};
149             my $serverrequest = CORBA::ServerRequest->new($operation, $byte_order, $data, $index);
150             $operation =~ s/^_(get|set)_//;
151             my $exception;
152             try {
153             $target->$operation($serverrequest);
154             } catch 'Default' => sub {
155             $exception = $_[0];
156             };
157             my $reply_header = GIOP::ReplyHeader->new(
158             service_context => [],
159             request_id => $rh->{request_id},
160             reply_status => $exception ? 1 : 0,
161             );
162             my $reply = '';
163             $index = 0;
164             $byte_order = $self->{byte_order};
165             GIOP::ReplyHeader::_marshal(\$reply, \$index, $byte_order, $reply_header);
166             if ($exception) {
167             my $tc = ref $exception;
168             no strict 'refs';
169             $tc = ${"${tc}::_tc"};
170             CORBA::ORB::_marshal_using_tc(\$reply, \$index, $byte_order, $exception, $tc);
171             } else {
172             my $result = $serverrequest->get_result();
173             if ($result) {
174             CORBA::ORB::_marshal_using_tc(\$reply, \$index, $byte_order, $result->{_value}, $result->{_type});
175             }
176             my $arg_list = $serverrequest->get_arglist();
177             my $argnum = 1;
178             foreach my $arg (@{$arg_list}) {
179             $argnum++;
180             if (($arg->{arg_modes}==1)||($arg->{arg_modes}==2)) {
181             CORBA::ORB::_marshal_using_tc(\$reply, \$index, $byte_order, $arg->{argument}{_value}, $arg->{argument}{_type});
182             }
183             }
184             }
185             $msgh = GIOP::MessageHeader->new(
186             magic => 'GIOP',
187             GIOP_version => new GIOP::Version(major => chr(1), minor => chr(0)),
188             byte_order => $byte_order,
189             message_type => GIOP::Reply,
190             message_size => $index,
191             );
192             $data = '';
193             $index = 0;
194             GIOP::MessageHeader::_marshal(\$data,\$index,$byte_order,$msgh);
195             $data .= $reply;
196             mywrite($socket, $data, length($data));
197             }
198              
199             sub myread ($\$$;$) {
200             my($fh,$varref,$length,$index) = @_;
201             if (!defined($index)) {
202             $index = 0;
203             }
204             my $read = $index;
205             $length += $index;
206             while ($read < $length) {
207             my $r = $fh->sysread($$varref, $length-$read, $read);
208             if ($r > 0) {
209             $read += $r;
210             } else {
211             # Client may die, return anyway.
212             return $r;
213             }
214             }
215             return $read-$index;
216             }
217              
218             sub mywrite ($\$$) {
219             my($fh,$varref,$length) = @_;
220             my $written = 0;
221             while ($written < $length) {
222             my $r = $fh->syswrite($$varref, $length-$written, $written);
223             if ($r > 0) {
224             $written += $r;
225             } else {
226             sleep 1;
227             }
228             }
229             return $written;
230             }
231              
232             1;