File Coverage

blib/lib/FLV/AMFReader.pm
Criterion Covered Total %
statement 40 40 100.0
branch 2 2 100.0
condition n/a
subroutine 11 11 100.0
pod 2 2 100.0
total 55 55 100.0


line stmt bran cond sub pod time code
1             package FLV::AMFReader;
2              
3 6     6   38 use warnings;
  6         14  
  6         207  
4 6     6   100 use strict;
  6         15  
  6         306  
5 6     6   116 use 5.008;
  6         22  
  6         298  
6 6     6   34 use English qw(-no_match_vars);
  6         22  
  6         37  
7              
8 6     6   15069 use AMF::Perl::Util::Object;
  6         7398  
  6         202  
9 6     6   6032 use AMF::Perl::IO::InputStream;
  6         6274  
  6         199  
10 6     6   36 use base 'AMF::Perl::IO::Deserializer';
  6         11  
  6         5365  
11              
12             our $VERSION = '0.24';
13              
14             =for stopwords AMF Remoting
15              
16             =head1 NAME
17              
18             FLV::AMFReader - Wrapper for the AMF::Perl deserializer
19              
20             =head1 LICENSE
21              
22             See L
23              
24             =head1 METHODS
25              
26             This is a subclass of AMF::Perl::IO::Deserializer.
27              
28             That class is optimized for Flash Remoting communications. We are
29             instead just interested in the protocol for the data payload of those
30             messages, since that's all that FLV carries.
31              
32             So, this class is a hack. We override the AMF::Perl::IO::Deserializer
33             constructor so that it doesn't start parsing immediately. Also, we
34             pass it a string instead of an instantiated
35             AMF::Perl::IO::InputStream.
36              
37             Also, as of this writing AMF::Perl was at v0.15, which lacked support
38             for hashes. So, we hack that in. Hopefully we did it in a
39             future-friendly way...
40              
41             =over
42              
43             =item $pkg->new($content)
44              
45             Creates a minimal AMF::Perl::IO::Deserializer instance.
46              
47             =cut
48              
49             sub new
50             {
51 39     39 1 68 my $pkg = shift;
52 39         70 my $content = shift;
53              
54 39         403 my $input_stream = AMF::Perl::IO::InputStream->new($content);
55 39         6699 return bless { inputStream => $input_stream }, $pkg;
56             }
57              
58             =item $self->read_flv_meta()
59              
60             Returns an array of anonymous data structures.
61              
62             Parse AMF data from a block of FLV data. This method of very lenient.
63             If there are any parsing errors, that data is just ignored and any
64             successfully parsed data is returned.
65              
66             We expect there to be exactly two return values, but this method is
67             generic and is happy to return anywhere from zero to twenty data.
68              
69             =cut
70              
71             sub read_flv_meta
72             {
73 39     39 1 75 my $self = shift;
74              
75 39         60 my @data;
76 39         79 local $EVAL_ERROR = undef;
77             ## no critic (RequireCheckingReturnValueOfEval)
78 39         75 eval {
79 39         115 for my $iter (1 .. 20)
80             {
81 117         5554 my $type = $self->{inputStream}->readByte();
82 78         1074 push @data, $self->readData($type);
83             }
84             };
85 39         581 return @data;
86             }
87              
88             =item $self->readMixedArray()
89              
90             Returns a populated hashref.
91              
92             This is a workaround for versions of AMF::Perl which did not handle
93             hashes (namely v0.15 and earlier). This method is only installed if a
94             method of the same name does not exist in the superclass.
95              
96             This should be removed when a newer release of AMF::Perl is available.
97              
98             =item $self->readData($type)
99              
100             This is a minimal override of readData() in the superclass to add
101             support for mixed arrays (aka hashes).
102              
103             As above, it is only installed if AMF::Perl::IO::Deserializer lacks a
104             readMixedArray() method.
105              
106             =cut
107              
108             if (!__PACKAGE__->can('readMixedArray'))
109             {
110             *readMixedArray = sub {
111 48     48   80 my ($self) = @_;
112              
113             # This length is actually unused! How odd...
114             # Instead, a value with datatype == 9 is the end flag
115 48         193 my $length = $self->{inputStream}->readLong();
116              
117 48         924 return $self->readObject();
118             };
119              
120             *readData = sub {
121 802     802   54167 my ($self, $type) = @_;
122              
123 802 100       1558 if (8 == $type)
124             {
125 48         157 return $self->readMixedArray();
126             }
127             else
128             {
129 754         2230 return $self->SUPER::readData($type);
130             }
131             };
132             }
133              
134             1;
135              
136             __END__