File Coverage

blib/lib/Audio/Metadata/Flac/Block.pm
Criterion Covered Total %
statement 49 49 100.0
branch 3 4 75.0
condition 1 2 50.0
subroutine 17 17 100.0
pod 1 7 14.2
total 71 79 89.8


line stmt bran cond sub pod time code
1             package Audio::Metadata::Flac::Block;
2             {
3             $Audio::Metadata::Flac::Block::VERSION = '0.16';
4             }
5             BEGIN {
6 3     3   82 $Audio::Metadata::Flac::Block::VERSION = '0.15';
7             }
8              
9 3     3   17 use strict;
  3         6  
  3         86  
10 3     3   15 use warnings;
  3         6  
  3         87  
11 3     3   16 use autodie;
  3         5  
  3         22  
12              
13 3     3   17024 use Any::Moose;
  3         37  
  3         27  
14 3     3   5132 use Module::Find ();
  3         20139  
  3         91  
15 3     3   30 use List::Util qw/first/;
  3         5  
  3         2056  
16              
17              
18             has _init_content => ( isa => 'Str', is => 'ro', );
19             has next => ( isa => 'Maybe[Audio::Metadata::Flac::Block]', is => 'rw', );
20              
21              
22             __PACKAGE__->meta->make_immutable;
23              
24              
25             sub BUILDARGS {
26             ## Populates attrbutes on creation of block object.
27 43     43 1 532 my $self = shift;
28              
29             # Only accept single scalar parameter as initial content.
30             return {
31 43         769 _init_content => $_[0],
32             };
33             }
34              
35              
36             sub new_from_fh {
37             ## Reads block from given filehandle and returns object of appropriate type and
38             ## is_last flag, which is true if more blocks follow.
39 48     48 0 82 my $class = shift;
40 48         76 my ($fh) = @_;
41              
42             # Read header.
43 48         130 $fh->read(my $header, $class->header_size);
44              
45             # Parse header.
46 48         374 my $first_byte = unpack('C', $header);
47 48         101 my $is_last = ($first_byte & 0b10000000) > 0;
48 48         74 my $type = $first_byte & 0b01111111;
49 48         272 my $content_size = unpack('N', chr(0) . substr($header, 1)); # 24-bit long
50              
51             # Find submodule for block with this type code.
52 48 50   228   275 my $block_class = first { $_->type_code == $type } Module::Find::useall(__PACKAGE__)
  228         288159  
53             or die "Don't know how to handle block of type \"$type\"";
54              
55             # Read content, instantiate block object and return it.
56 48         355 $fh->read(my $content, $content_size);
57 48         1100 return ( $block_class->new($content), $is_last );
58             }
59              
60              
61             sub _get_header {
62             ## Returns packed block header.
63 32     32   32 my $self = shift;
64              
65 32         126 my $first_byte = $self->type_code;
66 32 100       111 $first_byte |= 0b10000000 unless $self->next;
67 32         71 my $header = chr($first_byte) . substr(pack('N', $self->content_size), 1);
68 32         108 return $header;
69             }
70              
71              
72             sub content_as_string {
73             ## Returns block content as string, taking into account unsaved changes in block
74             ## structures.
75 116     116 0 136 my $self = shift;
76              
77 116         768 return $self->_init_content;
78             }
79              
80              
81             sub as_string {
82             ## Returns complete block as string, including header.
83 24     24 0 37 my $self = shift;
84              
85 24         72 return $self->_get_header . $self->content_as_string;
86             }
87              
88              
89             sub content_size {
90             ## Returns size of block content.
91 120     120 0 158 my $self = shift;
92              
93 120   50     310 return length($self->content_as_string || '');
94             }
95              
96              
97             sub size {
98             ## Returns total block size, including header.
99 80     80 0 110 my $self = shift;
100              
101 80         203 return $self->content_size + $self->header_size;
102             }
103              
104              
105             sub header_size {
106             ## Returns size of block header.
107              
108 135     135 0 492 4;
109             }
110              
111              
112 3     3   40 no Any::Moose;
  3         5  
  3         42  
113              
114              
115             1;
116              
117              
118             __END__