File Coverage

blib/lib/AMF/Connection/Message.pm
Criterion Covered Total %
statement 18 90 20.0
branch 0 10 0.0
condition 0 18 0.0
subroutine 6 15 40.0
pod 0 9 0.0
total 24 142 16.9


line stmt bran cond sub pod time code
1             package AMF::Connection::Message;
2              
3 1     1   6 use strict;
  1         3  
  1         34  
4 1     1   5 use Carp;
  1         2  
  1         128  
5              
6 1     1   748 use AMF::Connection::OutputStream;
  1         4  
  1         33  
7 1     1   822 use AMF::Connection::InputStream;
  1         2  
  1         123  
8              
9 1     1   606 use AMF::Connection::MessageBody;
  1         3  
  1         32  
10 1     1   689 use AMF::Connection::MessageHeader;
  1         2  
  1         1109  
11              
12             sub new {
13 0     0 0   my $proto = shift;
14 0   0       my $class = ref($proto) || $proto;
15            
16 0           my $self = {
17             'encoding' => 0, # default is AMF0 encoding
18             'bodies' => [],
19             'headers' => []
20             };
21              
22 0           return bless($self, $class);
23             };
24              
25             sub serialize {
26 0     0 0   my ($class, $stream) = @_;
27              
28 0 0 0       croak "Stream $stream is not a valid output stream"
29             unless(ref($stream) and $stream->isa("AMF::Connection::OutputStream"));
30              
31             # we default to AMF0 encoding
32 0           $stream->writeByte(0x00);
33 0           $stream->writeByte($class->getEncoding());
34              
35 0           $stream->writeInt(scalar(@{$class->{'headers'}}));
  0            
36 0           foreach my $header (@{$class->{'headers'}}) {
  0            
37 0           my $name =$header->getName();
38 0           $stream->writeInt(length($name));
39 0           $stream->writeBuffer($name);
40              
41 0           $stream->writeByte($header->isRequired());
42              
43 0           $stream->writeLong(-1);
44              
45             # TODO - make sure Storable::AMF does not store string "true" as boolean - or make sure value is right typed
46 0           $stream->writeAMFData( $class->getEncoding(), $header->getValue() );
47             };
48              
49 0           $stream->writeInt(scalar(@{$class->{'bodies'}}));
  0            
50 0           foreach my $body (@{$class->{'bodies'}}) {
  0            
51 0           my $target = $body->getTarget();
52 0           $stream->writeInt(length($target));
53 0           $stream->writeBuffer($target);
54              
55 0           my $response = $body->getResponse();
56 0           $stream->writeInt(length($response));
57 0           $stream->writeBuffer($response);
58              
59 0           $stream->writeLong(-1);
60 0           $stream->writeAMFData( $class->getEncoding(), $body->getData() );
61             };
62              
63             };
64              
65             sub deserialize {
66 0     0 0   my ($class, $stream) = @_;
67              
68 0           $class->{'headers'} = [];
69 0           $class->{'bodies'} = [];
70              
71 0           $stream->readByte();
72              
73 0           my $sent_encoding = $stream->readByte();
74             # need to make AMF1 returned encoding the same as AMF0 - see more about the bug at http://balazs.sebesteny.com/footprints-in-blazeds/
75 0 0 0       $class->setEncoding( ( $sent_encoding!=0 and $sent_encoding!=3 ) ? 0 : $sent_encoding );
76              
77 0           my $totalHeaders = $stream->readInt();
78 0           for(my $i=0;$i<$totalHeaders;$i++) {
79 0           my $header = new AMF::Connection::MessageHeader();
80              
81 0           my $strLen = $stream->readInt();
82 0           $header->setName( $stream->readBuffer($strLen) );
83              
84 0           $header->setRequired( $stream->readByte() );
85              
86 0           $stream->readLong();
87 0           $header->setValue( $stream->readAMFData() ); # we deparse the next read value out
88              
89 0           $class->addHeader( $header );
90             };
91              
92 0           my $totalBodies = $stream->readInt();
93 0           for(my $i=0;$i<$totalBodies;$i++) {
94 0           my $body = new AMF::Connection::MessageBody();
95              
96 0           my $strLen = $stream->readInt();
97 0           $body->setTarget( $stream->readBuffer($strLen) );
98              
99 0           $strLen = $stream->readInt();
100 0           $body->setResponse( $stream->readBuffer($strLen) );
101              
102             # TODO - make sure we deal properly with avm+ object marker stuff here - and have message containing multiple encodings
103 0           $stream->readLong();
104 0           $body->setData( $stream->readAMFData() ); # we deparse the next read value out
105              
106 0           $class->addBody( $body );
107             };
108             };
109              
110             sub addBody {
111 0     0 0   my ($class, $body) = @_;
112              
113 0 0 0       croak "Body $body is not a valid message body"
114             unless(ref($body) and $body->isa("AMF::Connection::MessageBody"));
115              
116 0           push @{ $class->{'bodies'} }, $body;
  0            
117             };
118              
119             sub addHeader {
120 0     0 0   my ($class, $header) = @_;
121              
122 0 0 0       croak "Header $header is not a valid message header"
123             unless(ref($header) and $header->isa("AMF::Connection::MessageHeader"));
124              
125 0           push @{ $class->{'headers'} }, $header;
  0            
126             };
127              
128             sub getHeaders {
129 0     0 0   my ($class) = @_;
130              
131 0           return $class->{'headers'};
132             };
133              
134             sub getBodies {
135 0     0 0   my ($class) = @_;
136              
137 0           return $class->{'bodies'};
138             };
139              
140             sub setEncoding {
141 0     0 0   my ($class, $encoding) = @_;
142              
143 0 0 0       croak "Unsupported AMF encoding $encoding"
144             unless( $encoding==0 or $encoding==3 );
145              
146 0           $class->{'encoding'} = $encoding;
147             };
148              
149             sub getEncoding {
150 0     0 0   my ($class) = @_;
151              
152 0           return $class->{'encoding'};
153             };
154              
155              
156             1;
157             __END__