| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Audio::Scan; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 16 |  |  | 16 |  | 819205 | use strict; | 
|  | 16 |  |  |  |  | 148 |  | 
|  | 16 |  |  |  |  | 852 |  | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | our $VERSION = '1.01'; | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | require XSLoader; | 
| 8 |  |  |  |  |  |  | XSLoader::load('Audio::Scan', $VERSION); | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 16 |  |  | 16 |  | 78 | use constant FILTER_INFO_ONLY => 1; | 
|  | 16 |  |  |  |  | 21 |  | 
|  | 16 |  |  |  |  | 1405 |  | 
| 11 | 16 |  |  | 16 |  | 84 | use constant FILTER_TAGS_ONLY => 2; | 
|  | 16 |  |  |  |  | 41 |  | 
|  | 16 |  |  |  |  | 11267 |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | sub scan_info { | 
| 14 | 17 |  |  | 17 | 1 | 33208 | my ( $class, $path, $opts ) = @_; | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 17 |  | 50 |  |  | 81 | $opts ||= {}; | 
| 17 | 17 |  |  |  |  | 35 | $opts->{filter} = FILTER_INFO_ONLY; | 
| 18 |  |  |  |  |  |  |  | 
| 19 | 17 |  |  |  |  | 39 | $class->scan( $path, $opts ); | 
| 20 |  |  |  |  |  |  | } | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | sub scan_tags { | 
| 23 | 15 |  |  | 15 | 1 | 30059 | my ( $class, $path, $opts ) = @_; | 
| 24 |  |  |  |  |  |  |  | 
| 25 | 15 |  | 50 |  |  | 84 | $opts ||= {}; | 
| 26 | 15 |  |  |  |  | 50 | $opts->{filter} = FILTER_TAGS_ONLY; | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 15 |  |  |  |  | 35 | $class->scan( $path, $opts ); | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | sub scan { | 
| 32 | 193 |  |  | 193 | 1 | 402131 | my ( $class, $path, $opts ) = @_; | 
| 33 |  |  |  |  |  |  |  | 
| 34 | 193 |  |  |  |  | 338 | my ($filter, $md5_size, $md5_offset); | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 193 | 50 |  |  |  | 7133 | open my $fh, '<', $path or do { | 
| 37 | 0 |  |  |  |  | 0 | warn "Could not open $path for reading: $!\n"; | 
| 38 | 0 |  |  |  |  | 0 | return; | 
| 39 |  |  |  |  |  |  | }; | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 193 |  |  |  |  | 636 | binmode $fh; | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 193 |  |  |  |  | 1384 | my ($suffix) = $path =~ /\.(\w+)$/; | 
| 44 |  |  |  |  |  |  |  | 
| 45 | 193 | 50 |  |  |  | 508 | return if !$suffix; | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 193 | 100 |  |  |  | 416 | if ( defined $opts ) { | 
| 48 | 51 | 50 |  |  |  | 143 | if ( !ref $opts ) { | 
| 49 |  |  |  |  |  |  | # Back-compat to support filter as normal argument | 
| 50 | 0 |  |  |  |  | 0 | warn "The Audio::Scan::scan() filter passing method is deprecated, please pass a hashref instead.\n"; | 
| 51 | 0 |  |  |  |  | 0 | $filter = $opts; | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  | else { | 
| 54 | 51 |  | 100 |  |  | 170 | $filter     = $opts->{filter} || FILTER_INFO_ONLY | FILTER_TAGS_ONLY; | 
| 55 | 51 |  |  |  |  | 71 | $md5_size   = $opts->{md5_size}; | 
| 56 | 51 |  |  |  |  | 82 | $md5_offset = $opts->{md5_offset}; | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  |  | 
| 60 | 193 | 100 |  |  |  | 337 | if ( !defined $filter ) { | 
| 61 | 142 |  |  |  |  | 193 | $filter = FILTER_INFO_ONLY | FILTER_TAGS_ONLY; | 
| 62 |  |  |  |  |  |  | } | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 193 |  | 100 |  |  | 41277 | my $ret = $class->_scan( $suffix, $fh, $path, $filter, $md5_size || 0, $md5_offset || 0 ); | 
|  |  |  | 100 |  |  |  |  | 
| 65 |  |  |  |  |  |  |  | 
| 66 | 193 |  |  |  |  | 2406 | close $fh; | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 193 |  |  |  |  | 1082 | return $ret; | 
| 69 |  |  |  |  |  |  | } | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | sub scan_fh { | 
| 72 | 3 |  |  | 3 | 1 | 4713 | my ( $class, $suffix, $fh, $opts ) = @_; | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 3 |  |  |  |  | 8 | my ($filter, $md5_size, $md5_offset); | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 3 |  |  |  |  | 11 | binmode $fh; | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 3 | 50 |  |  |  | 11 | if ( defined $opts ) { | 
| 79 | 0 | 0 |  |  |  | 0 | if ( !ref $opts ) { | 
| 80 |  |  |  |  |  |  | # Back-compat to support filter as normal argument | 
| 81 | 0 |  |  |  |  | 0 | warn "The Audio::Scan::scan_fh() filter passing method is deprecated, please pass a hashref instead.\n"; | 
| 82 | 0 |  |  |  |  | 0 | $filter = $opts; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  | else { | 
| 85 | 0 |  | 0 |  |  | 0 | $filter     = $opts->{filter} || FILTER_INFO_ONLY | FILTER_TAGS_ONLY; | 
| 86 | 0 |  |  |  |  | 0 | $md5_size   = $opts->{md5_size}; | 
| 87 | 0 |  |  |  |  | 0 | $md5_offset = $opts->{md5_offset}; | 
| 88 |  |  |  |  |  |  | } | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  |  | 
| 91 | 3 | 50 |  |  |  | 23 | if ( !defined $filter ) { | 
| 92 | 3 |  |  |  |  | 5 | $filter = FILTER_INFO_ONLY | FILTER_TAGS_ONLY; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  |  | 
| 95 | 3 |  | 50 |  |  | 381 | return $class->_scan( $suffix, $fh, '(filehandle)', $filter, $md5_size || 0, $md5_offset || 0 ); | 
|  |  |  | 50 |  |  |  |  | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | sub find_frame { | 
| 99 | 17 |  |  | 17 | 1 | 9432 | my ( $class, $path, $offset ) = @_; | 
| 100 |  |  |  |  |  |  |  | 
| 101 | 17 | 50 |  |  |  | 563 | open my $fh, '<', $path or do { | 
| 102 | 0 |  |  |  |  | 0 | warn "Could not open $path for reading: $!\n"; | 
| 103 | 0 |  |  |  |  | 0 | return; | 
| 104 |  |  |  |  |  |  | }; | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 17 |  |  |  |  | 56 | binmode $fh; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 17 |  |  |  |  | 116 | my ($suffix) = $path =~ /\.(\w+)$/; | 
| 109 |  |  |  |  |  |  |  | 
| 110 | 17 | 50 |  |  |  | 38 | return -1 if !$suffix; | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 17 |  |  |  |  | 4015 | my $ret = $class->_find_frame( $suffix, $fh, $path, $offset ); | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 17 |  |  |  |  | 200 | close $fh; | 
| 115 |  |  |  |  |  |  |  | 
| 116 | 17 |  |  |  |  | 109 | return $ret; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub find_frame_fh { | 
| 120 | 6 |  |  | 6 | 1 | 2698 | my ( $class, $suffix, $fh, $offset ) = @_; | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 6 |  |  |  |  | 14 | binmode $fh; | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 6 |  |  |  |  | 998 | return $class->_find_frame( $suffix, $fh, '(filehandle)', $offset ); | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | sub find_frame_return_info { | 
| 128 | 3 |  |  | 3 | 1 | 1952 | my ( $class, $path, $offset ) = @_; | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 3 | 50 |  |  |  | 95 | open my $fh, '<', $path or do { | 
| 131 | 0 |  |  |  |  | 0 | warn "Could not open $path for reading: $!\n"; | 
| 132 | 0 |  |  |  |  | 0 | return; | 
| 133 |  |  |  |  |  |  | }; | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 3 |  |  |  |  | 10 | binmode $fh; | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 3 |  |  |  |  | 21 | my ($suffix) = $path =~ /\.(\w+)$/; | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 3 | 50 |  |  |  | 7 | return if !$suffix; | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 3 |  |  |  |  | 2544 | my $ret = $class->_find_frame_return_info( $suffix, $fh, $path, $offset ); | 
| 142 |  |  |  |  |  |  |  | 
| 143 | 3 |  |  |  |  | 28 | close $fh; | 
| 144 |  |  |  |  |  |  |  | 
| 145 | 3 |  |  |  |  | 15 | return $ret; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | sub find_frame_fh_return_info { | 
| 149 | 1 |  |  | 1 | 1 | 436 | my ( $class, $suffix, $fh, $offset ) = @_; | 
| 150 |  |  |  |  |  |  |  | 
| 151 | 1 |  |  |  |  | 3 | binmode $fh; | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 1 |  |  |  |  | 163 | return $class->_find_frame_return_info( $suffix, $fh, '(filehandle)', $offset ); | 
| 154 |  |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | 1; | 
| 157 |  |  |  |  |  |  | __END__ |