File Coverage

/.cpan/build/Net-FreeDB2-0.8.2.6-xK8Ulr/blib/lib/Net/FreeDB2/Entry.pm
Criterion Covered Total %
statement 21 356 5.9
branch 0 116 0.0
condition 0 54 0.0
subroutine 7 50 14.0
pod 36 38 94.7
total 64 614 10.4


line stmt bran cond sub pod time code
1             package Net::FreeDB2::Entry;
2              
3             # Copyright 2002, Vincenzo Zocca.
4              
5             # See LICENSE section for usage and distribution rights.
6              
7             require 5.005_62;
8 1     1   4 use strict;
  1         2  
  1         29  
9 1     1   4 use warnings;
  1         2  
  1         25  
10 1     1   775 use Error qw (:try);
  1         6211  
  1         5  
11              
12             require Exporter;
13 1     1   862 use AutoLoader qw(AUTOLOAD);
  1         2060  
  1         7  
14              
15             our @ISA = qw(Exporter);
16              
17             # Items to export into callers namespace by default. Note: do not export
18             # names by default without a very good reason. Use EXPORT_OK instead.
19             # Do not simply export all your public functions/methods/constants.
20              
21             # This allows declaration use Net::FreeDB2::Entry ':all';
22             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
23             # will save memory.
24             our %EXPORT_TAGS = ( 'all' => [ qw(
25            
26             ) ] );
27              
28             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29              
30             our @EXPORT = qw(
31            
32             );
33             our ( $VERSION ) = '$Revision: 0.8.2.3 $ ' =~ /\$Revision:\s+([^\s]+)/;
34              
35             my $DB_LINE_LEN_DEF = 256;
36              
37             my $XMCD_RX = '^\s*#\s*xmcd';
38             my $XMCD_ERR = '# xmcd';
39             my $TFO_RX = '^\s*#\s*Track\s+frame\s+offsets\s*:\s*$';
40             my $TFO_ERR = '# Track frame offsets:';
41             my $FO_RX = '^\s*#\s*(\d+)\s*$';
42             my $FO_ERR = '# ';
43             my $DL_RX = '^\s*#\s*Disc\s+length\s*:\s*(\d+)\s+seconds\s*$';
44             my $DL_ERR = '# Disc length: seconds';
45             my $REV_RX = '^\s*#\s*Revision\s*:\s*(\d+)\s*';
46             my $REV_ERR = '# Revision: ';
47             my $SUB_RX = '^\s*#\s*Submitted\s+via\s*:\s*(\S+)\s+(\S+)\s*(.*)\s*$';
48             my $SUB_ERR = '# Submitted via: ';
49             my $DID_RX = '^\s*DISCID\s*=\s*(\S+)\s*$';
50             my $DID_ERR = 'DISCID=';
51             my $DTITLE_RX = '^\s*DTITLE\s*=(.*)$';
52             my $DYEAR_RX = '^\s*DYEAR\s*=(.*)$';
53             my $DGENRE_RX = '^\s*DGENRE\s*=(.*)$';
54             my $TTITLEN_RX = '^\s*TTITLE(\d+)\s*=(.*)$';
55             my $EXTD_RX = '^\s*EXTD\s*=(.*)$';
56             my $EXTTN_RX = '^\s*EXTT(\d+)\s*=(.*)$';
57             my $CDPARA_TRACK_RX = '^\s*(\d+)\.\s*(\d+)\s*\[\d+[:.]\d+[:.]\d+\]\s*(\d+)\s*\[\d+[:.]\d+[:.]\d+\]';
58             my $CDPARA_TOTAL_RX = '^\s*TOTAL\s+(\d+)';
59              
60             sub new {
61 0     0 1   my $class = shift;
62              
63 0           my $self = {};
64 0   0       bless ($self, (ref($class) || $class));
65 0           return ($self->_initialize (@_));
66             }
67              
68             sub _initialize {
69 0     0     my $self = shift;
70 0   0       my $opt = shift || {};
71              
72 0 0 0       (defined ($opt->{fh}) or defined ($opt->{fn}) or defined ($opt->{array_ref})) and $self->read ($opt);
      0        
73 0 0         defined ($opt->{dev}) and $self->readDev ($opt);
74 0           return ($self);
75             }
76              
77             sub read {
78 0     0 1   my $self = shift;
79 0   0       my $opt = shift || {};
80              
81             # Make an array reference out of $opt->{fh}, $opt->{fn} or
82             # $opt->{array_ref}.
83             # From http://www.freedb.org/src/latest/DBFORMAT :
84             # The beginning of the first line in a database entry should consist of
85             # the string "# xmcd". This string identifies the file as an xmcd format
86             # CD database file. More text can appear after the "xmcd", but is
87             # unnecessary.
88 0           my $array_ref;
89 0           my $lineNr = 1;;
90 0 0 0       if (exists ($opt->{fh})|| exists ($opt->{fn})) {
    0          
91 0           my $fh;
92 0 0         if (exists ($opt->{fh})) {
    0          
93 0           $fh = $opt->{fh};
94             } elsif (exists ($opt->{fn})) {
95 1     1   1430 use IO::File;
  1         11332  
  1         1644  
96 0           $fh = IO::File->new ("< $opt->{fn}");
97             }
98 0 0         defined ($fh) || throw Error::Simple ('ERROR: Net::FreeDB2::Entry::read, Failed to make file handle out of provided options.');
99            
100 0           my $line = $fh->getline ();
101 0           chomp ($line);
102 0 0         $line =~ /$XMCD_RX/ || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$XMCD_ERR' in line " . $lineNr . ' but encountered: ' . $line);
103              
104 0           my @array = ();
105 0           while ($line = $fh->getline ()) {
106 0           chomp ($line);
107 0           push (@array, $line);
108             }
109 0           $array_ref = \@array;
110             } elsif (exists ($opt->{array_ref})) {
111 0           $array_ref = $opt->{array_ref};
112 0           my $line = shift (@{$array_ref});
  0            
113 0 0         $line =~ /$XMCD_RX/ || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$XMCD_ERR' in line " . $lineNr . ' but encountered: ' . $line);
114             } else {
115 0           throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, missing option 'fh', 'fn' or 'array_ref'");
116             }
117              
118              
119             # Tollerate '#.*' until '# Track frame offsets:'
120 0           my $line;
121 0           while ($line = shift (@{$array_ref})) {
  0            
122 0           $lineNr++;
123 0 0         ($line =~ /$TFO_RX/i) && last;
124 0 0         ($line =~ /^\s*#/) && next;
125 0           throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$TFO_ERR' in line " . $lineNr . ' but encountered: ' . $line);
126             }
127              
128             # Read frame offsets
129 0           my $track = 1;
130 0           while ($line = shift (@{$array_ref})) {
  0            
131 0           $lineNr++;
132 0           my ($off) = $line =~ /$FO_RX/;
133 0 0         defined ($off) || last;
134 0           $self->setFrameOffset ($track++, $off);
135             }
136 0 0         $track > 1 || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$FO_ERR' in line " . $lineNr . ' but encountered: ' . $line);
137              
138             # Read '# Disc length', '"# Revision', "# Submitted via' until 'DID'
139 0           while ($line = shift (@{$array_ref})) {
  0            
140 0           $lineNr++;
141 0           my ($len) = $line =~ /$DL_RX/i;
142 0 0         if (defined ($len)) {
143 0           $self->setDiscLength ($len);
144 0           next;
145             }
146 0           my ($rev) = $line =~ /$REV_RX/i;
147 0 0         if (defined ($rev)) {
148 0           $self->setRevision ($rev);
149 0           next;
150             }
151 0           my ($name, $vers, $comm) = $line =~ /$SUB_RX/i;
152 0 0         if (defined ($name)) {
153 0           $self->setClientName ($name);
154 0           $self->setClientVersion ($vers);
155 0           $self->setClientComment ($comm);
156 0           next;
157             }
158 0           my ($discid) = $line =~ /$DID_RX/i;
159 0 0         if (defined ($discid)) {
160 0           $self->setDiscID ($discid);
161 0           last;
162             }
163 0 0         ($line =~ /^\s*#/) && next;
164 0           last;
165             }
166 0 0         $self->getDiscLength () || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$DL_ERR' in line " . $lineNr . ' but encountered: ' . $line);
167 0 0         defined ($self->getRevision ()) || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$REV_ERR' in line " . $lineNr . ' but encountered: ' . $line);
168 0 0         $self->getClientName () || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$SUB_ERR' in line " . $lineNr . ' but encountered: ' . $line);
169 0 0         $self->getDiscID () || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::read, Expected '$DID_ERR' in line " . $lineNr . ' but encountered: ' . $line);
170              
171             # Read DTITLE, DYEAR, DGENRE, TTITLEN, EXTD, EXTTN
172             # Indeed, this code is a bit forgiving
173 0           my $DTITLE = '';
174 0           my $DYEAR = '';
175 0           my $DGENRE = '';
176 0           my @TTITLEN = '';
177 0           my $EXTD = '';
178 0           my @EXTTN = '';
179 0           while ($line = shift (@{$array_ref})) {
  0            
180 0           $lineNr++;
181 0           my $str;
182 0           ($str) = $line =~ /$DTITLE_RX/;
183 0 0         if (defined ($str)) {
184 0           $DTITLE .= $str;
185 0           next;
186             }
187 0           ($str) = $line =~ /$DYEAR_RX/;
188 0 0         if (defined ($str)) {
189 0           $DYEAR .= $str;
190 0           next;
191             }
192 0           ($str) = $line =~ /$DGENRE_RX/;
193 0 0         if (defined ($str)) {
194 0           $DGENRE .= $str;
195 0           next;
196             }
197 0           my $nr;
198 0           ($nr, $str) = $line =~ /$TTITLEN_RX/;
199 0 0         if (defined ($nr)) {
200 0           $TTITLEN[$nr] .= $str;
201 0           next;
202             }
203 0           ($str) = $line =~ /$EXTD_RX/;
204 0 0         if (defined ($str)) {
205 0           $EXTD .= $str;
206 0           next;
207             }
208 0           ($nr, $str) = $line =~ /$EXTTN_RX/;
209 0 0         if (defined ($nr)) {
210 0           $EXTTN[$nr] .= $str;
211 0           next;
212             }
213             }
214             # Set artist and title
215 0           my ($artist, $title) = split (/\s*\/\s*/, $DTITLE, 2);
216 0 0         $title = '' if (!$title);
217 0           $artist =~ s/\\n/\n/gm;
218 0           $title =~ s/\\n/\n/gm;
219 0           $self->setArtist ($artist);
220 0           $self->setTitle ($title);
221              
222             # DYEAR
223 0           $DYEAR =~ s/\\n/\n/gm;
224 0           $self->setDyear ($DYEAR);
225              
226             # DGENRE
227 0           $DGENRE =~ s/\\n/\n/gm;
228 0           $self->setDgenre ($DGENRE);
229              
230             # TTITLEN
231 0           for (my $i = 0; $i < scalar (@TTITLEN); $i++) {
232 0           $TTITLEN[$i] =~ s/\\n/\n/gm;
233 0           $self->setTtitlen ($i+1, $TTITLEN[$i]);
234             }
235              
236             # EXTD
237 0           $EXTD =~ s/\\n/\n/gm;
238 0           $self->setExtd ($EXTD);
239              
240             # EXTTN
241 0           for (my $i = 0; $i < scalar (@EXTTN); $i++) {
242 0           $EXTTN[$i] =~ s/\\n/\n/gm;
243 0           $self->setExttn ($i+1, $EXTTN[$i]);
244             }
245             }
246              
247             sub readDev {
248 0     0 1   my $self = shift;
249 0   0       my $opt = shift || {};
250              
251             # Setup the cdparanoia command
252 0           my $cmd = 'cdparanoia -Q';
253 0 0         $cmd .= " -d '$opt->{dev}'" if (exists $opt->{dev});
254              
255             # Run the cdparanoia command
256 1     1   12 use IO::File;
  1         2  
  1         972  
257 0           my $fh = IO::File->new ("$cmd 2>&1 |");
258 0 0         defined ($fh) || throw Error::Simple ("ERROR: Net::FreeDB2::Entry::readDev, Failed to open pipe from command '$cmd'.");
259              
260             # Parse cdparanoia's output
261 0           my $frameOffset = 150;
262 0           while (my $line = $fh->getline ()) {
263 0           my ($track, $framelength, $frameBegin) = $line =~ /$CDPARA_TRACK_RX/;
264 0 0         if (defined ($track)) {
265 0           $self->setFrameOffset ($track, $frameOffset);
266 0           $frameOffset += $framelength;
267 0           next;
268             }
269              
270 0           my ($frameTotal) = $line =~ /$CDPARA_TOTAL_RX/;
271 0 0         if (defined ($frameTotal)) {
272 0           $self->setDiscLength (int ($frameTotal / 75) + 2);
273 0           last;
274             }
275             }
276              
277             # Check if anything is read
278 0 0         ($frameOffset == 150) && throw Error::Simple ("ERROR: Net::FreeDB2::Entry::readDev, Command '$cmd' did not produce any usable output.");
279              
280             # Make discid
281 0           $self->mkDiscID ();
282             }
283              
284             sub write {
285 0     0 1   my $self = shift;
286 0   0       my $opt = shift || {};
287              
288             # Make an empty array
289 0           my @array = ();
290              
291             # xmcd
292 0           push (@array, "# xmcd");
293 0           push (@array, "#");
294              
295             # Make maximum tracks
296 0           my $max = scalar ($self->getFrameOffset ());
297              
298             # Track frame offsets:
299 0           push (@array, "# Track frame offsets:");
300 0           for (my $i = 1; $i <= $max; $i++) {
301 0           push (@array, "#\t" . $self->getFrameOffset ($i));
302             }
303 0           push (@array, "#");
304              
305             # Disc length: N seconds
306 0           push (@array, "# Disc length: " . $self->getDiscLength () . " seconds");
307 0           push (@array, "#");
308              
309             # Revision: N
310 0   0       push (@array, "# Revision: " . ($self->getRevision () || '0'));
311 0           push (@array, "#");
312              
313             # Submitted via: client_name client_version optional_comments
314 0   0       my $str = ($self->getClientName () || 'none') . ' ';
315 0   0       $str .= ($self->getClientVersion () || '0');
316 0 0         $str .= ' ' . $self->getClientComment () if ($self->getClientComment ());
317 0           push (@array, sprintf ("%.79s", "# Submitted via: " . $str));
318 0           push (@array, "#");
319              
320             # DISCID
321 0   0       push (@array, "DISCID=" . ($self->getDiscID () || ''));
322              
323             # DTITLE (Artist / Title)
324 0   0       $self->print_db_length (\@array, 'DTITLE=',
      0        
325             ($self->getArtist () || '') . ' / ' . ($self->getTitle () || ''));
326              
327             # DYEAR
328 0           $self->print_db_length (\@array, 'DYEAR=', $self->getDyear ());
329              
330             # DGENRE
331 0           $self->print_db_length (\@array, 'DGENRE=', $self->getDgenre ());
332              
333             # TTITLEN
334 0           for (my $i = 1; $i <= $max; $i++) {
335 0           my $str;
336             try {
337 0     0     $str = $self->getTtitlen ($i);
338 0     0     } catch Error::Simple with {
339 0           };
340 0           $self->print_db_length (\@array, "TTITLE" . int ($i-1) . "=", $str);
341             }
342              
343             # EXTD
344 0           $self->print_db_length (\@array, 'EXTD=', $self->getExtd ());
345              
346             # EXTTN
347 0           for (my $i = 1; $i <= $max; $i++) {
348 0           my $str;
349             try {
350 0     0     $str = $self->getExttn ($i);
351 0     0     } catch Error::Simple with {
352 0           };
353 0           $self->print_db_length (\@array, "EXTT" . int ($i-1) . "=", $str);
354             }
355              
356             # PLAYORDER
357 0           push (@array, "PLAYORDER=");
358              
359 0 0 0       if (exists ($opt->{fh})|| exists ($opt->{fn})) {
    0          
360             # Make a file handle out of $opt->{fh} or $opt->{fn}
361 0           my $fh;
362 0 0         if (exists ($opt->{fh})) {
    0          
363 0           $fh = $opt->{fh};
364             } elsif (exists ($opt->{fn})) {
365 1     1   7 use IO::File;
  1         4  
  1         2332  
366 0           $fh = IO::File->new ("> $opt->{fn}");
367             }
368 0 0         defined ($fh) || throw Error::Simple ('ERROR: Net::FreeDB2::Entry::write, Failed to make file handle out of provided options.');
369 0           foreach my $line (@array) {
370 0           $fh->print ($line, "\n");
371             }
372             } elsif (exists ($opt->{array_ref})) {
373 0           @{$opt->{array_ref}} = @array;
  0            
374             } else {
375 0           throw Error::Simple ("ERROR: Net::FreeDB2::Entry::write, missing option 'fh', 'fn' or 'array_ref'");
376             }
377             }
378              
379             sub setFrameOffset {
380 0     0 1   my $self = shift;
381 0           my $track = int (shift);
382 0           my $off = int (shift);
383              
384             # Check for a positive track number
385 0 0         $track > 0 || throw Error::Simple ("ERROR: setFrameOffset, track must be a positive integer.");
386              
387             # Check for a positive offset
388 0 0         $off > 0 || throw Error::Simple ("ERROR: setFrameOffset, offset must be a positive integer.");
389              
390             # Set the offset
391 0           $self->{Net_FreeDB2_Entry}{track}{$track}{off} = $off;
392             }
393              
394             sub getFrameOffset {
395 0     0 1   my $self = shift;
396 0   0       my $track = int (shift || 0);
397              
398             # Check for a positive or 0 track number
399 0 0         $track > -1 || throw Error::Simple ("ERROR: getFrameOffset, track must be a positive or 0 integer.");
400              
401             # Handle a specified track number
402 0 0         if ($track) {
403             # Check for an existing track number
404 0 0 0       (exists ($self->{Net_FreeDB2_Entry}{track}{$track}) && exists ($self->{Net_FreeDB2_Entry}{track}{$track}{off})) || throw Error::Simple ("ERROR: getFrameOffset, no track with number '$track'.");
405              
406             # Return the offset
407 0           return ($self->{Net_FreeDB2_Entry}{track}{$track}{off});
408             }
409              
410             # Return all offsets if track == 0;
411 0           my @ret = ();
412 0           foreach my $track (sort {$a <=> $b} (keys (%{$self->{Net_FreeDB2_Entry}{track}}))) {
  0            
  0            
413 0 0         exists ($self->{Net_FreeDB2_Entry}{track}{$track}{off}) || next;
414 0           push (@ret, $self->{Net_FreeDB2_Entry}{track}{$track}{off});
415             }
416 0           return (@ret);
417             }
418              
419             sub setDiscLength {
420 0     0 1   my $self = shift;
421 0           my $length = int (shift);
422              
423 0 0         $length || throw Error::Simple ("ERROR: setDiscLength, length must be a positive integer.");
424 0           $self->{Net_FreeDB2_Entry}{length} = $length;
425             }
426              
427             sub getDiscLength {
428 0     0 1   my $self = shift;
429              
430 0           return ($self->{Net_FreeDB2_Entry}{length});
431             }
432              
433             sub setRevision {
434 0     0 1   my $self = shift;
435 0           my $revision = shift;
436              
437 0           $self->{Net_FreeDB2_Entry}{revision} = $revision;
438             }
439              
440             sub getRevision {
441 0     0 1   my $self = shift;
442              
443 0           return ($self->{Net_FreeDB2_Entry}{revision});
444             }
445              
446             sub setClientName {
447 0     0 1   my $self = shift;
448 0           my $client_name = shift;
449              
450 0           $self->{Net_FreeDB2_Entry}{client_name} = $client_name;
451             }
452              
453             sub getClientName {
454 0     0 1   my $self = shift;
455              
456 0           return ($self->{Net_FreeDB2_Entry}{client_name});
457             }
458              
459             sub setClientVersion {
460 0     0 1   my $self = shift;
461 0           my $client_version = shift;
462              
463 0           $self->{Net_FreeDB2_Entry}{client_version} = $client_version;
464             }
465              
466             sub getClientVersion {
467 0     0 1   my $self = shift;
468              
469 0           return ($self->{Net_FreeDB2_Entry}{client_version});
470             }
471              
472             sub setClientComment {
473 0     0 1   my $self = shift;
474 0           my $client_comment = shift;
475              
476 0           $self->{Net_FreeDB2_Entry}{client_comment} = $client_comment;
477             }
478              
479             sub getClientComment {
480 0     0 1   my $self = shift;
481              
482 0           return ($self->{Net_FreeDB2_Entry}{client_comment});
483             }
484              
485             sub setDiscID {
486 0     0 1   my $self = shift;
487 0           my $disc_id = shift;
488              
489 0           $self->{Net_FreeDB2_Entry}{disc_id} = $disc_id;
490             }
491              
492             sub getDiscID {
493 0     0 1   my $self = shift;
494              
495 0           return ($self->{Net_FreeDB2_Entry}{disc_id});
496             }
497              
498             sub mkDiscID {
499 0     0 1   my $self = shift;
500              
501             # Make sum
502 0           my $sum = 0;
503 0           for (my $i = 1; $i <= scalar ($self->getFrameOffset ()); $i++) {
504 0           $sum += &digitSum ($self->getFrameOffset ($i)/75);
505             }
506              
507             # Make ID out of sum, getDiscLength () -2 and the number of tracks.
508             # And call setDiscID.
509 0           $self->setDiscID (sprintf ("%8x", ($sum % 0xff) << 24 |
510             int( $self->getDiscLength () - 2) << 8 |
511             scalar ($self->getFrameOffset ())));
512             }
513              
514             sub mkQuery {
515 0     0 1   my $self = shift;
516              
517             # Make a 'fresh' disc ID
518 0           $self->mkDiscID ();
519              
520             # Return query: disc ID, number of tracks, frame offsets and disc lenght
521 0           return (sprintf ("%s %d %s %d",
522             $self->getDiscID (),
523             scalar ($self->getFrameOffset ()),
524             join (' ', $self->getFrameOffset ()),
525             $self->getDiscLength ()
526             ));
527             }
528              
529             sub setArtist {
530 0     0 1   my $self = shift;
531 0           my $artist = shift;
532              
533 0           $self->{Net_FreeDB2_Entry}{artist} = $artist;
534             }
535              
536             sub getArtist {
537 0     0 0   my $self = shift;
538              
539 0           return ($self->{Net_FreeDB2_Entry}{artist});
540             }
541              
542             sub setTitle {
543 0     0 1   my $self = shift;
544 0           my $title = shift;
545              
546 0           $self->{Net_FreeDB2_Entry}{title} = $title;
547             }
548              
549             sub getTitle {
550 0     0 1   my $self = shift;
551              
552 0           return ($self->{Net_FreeDB2_Entry}{title});
553             }
554              
555             sub setDyear {
556 0     0 1   my $self = shift;
557 0           my $year = shift;
558              
559 0           $self->{Net_FreeDB2_Entry}{year} = $year;
560             }
561              
562             sub getDyear {
563 0     0 1   my $self = shift;
564              
565 0           return ($self->{Net_FreeDB2_Entry}{year});
566             }
567              
568             sub setDgenre {
569 0     0 1   my $self = shift;
570 0           my $genre = shift;
571              
572 0           $self->{Net_FreeDB2_Entry}{genre} = $genre;
573             }
574              
575             sub getDgenre {
576 0     0 1   my $self = shift;
577              
578 0           return ($self->{Net_FreeDB2_Entry}{genre});
579             }
580              
581             sub setTtitlen {
582 0     0 1   my $self = shift;
583 0           my $track = int (shift);
584 0           my $title = shift;
585              
586             # Check for a positive track number
587 0 0         $track > 0 || throw Error::Simple ("ERROR: setTtitlen, track must be a positive integer.");
588              
589             # Set the title
590 0           $self->{Net_FreeDB2_Entry}{track}{$track}{title} = $title;
591             }
592              
593             sub getTtitlen {
594 0     0 1   my $self = shift;
595 0           my $track = int (shift);
596              
597             # Check for a positive or 0 track number
598 0 0         $track > -1 || throw Error::Simple ("ERROR: getTtitlen, track must be a positive or 0 integer.");
599              
600             # Handle a specified track number
601 0 0         if ($track) {
602             # Check for an existing track number
603 0 0 0       (exists ($self->{Net_FreeDB2_Entry}{track}{$track}) && exists ($self->{Net_FreeDB2_Entry}{track}{$track}{title})) || throw Error::Simple ("ERROR: getFrameOffset, no track with number '$track'.");
604              
605             # Return the title
606 0           return ($self->{Net_FreeDB2_Entry}{track}{$track}{title});
607             }
608              
609             # Return all title if track == 0;
610 0           my @ret = ();
611 0           foreach my $track (sort {$a <=> $b} (keys (%{$self->{Net_FreeDB2_Entry}{track}}))) {
  0            
  0            
612 0 0         exists ($self->{Net_FreeDB2_Entry}{track}{$track}{title}) || next;
613 0           push (@ret, $self->{Net_FreeDB2_Entry}{track}{$track}{title});
614             }
615 0           return (@ret);
616             }
617              
618             sub setExtd {
619 0     0 1   my $self = shift;
620 0           my $ext = shift;
621              
622 0           $self->{Net_FreeDB2_Entry}{ext} = $ext;
623             }
624              
625             sub getExtd {
626 0     0 0   my $self = shift;
627              
628 0           return ($self->{Net_FreeDB2_Entry}{ext});
629             }
630              
631             sub setExttn {
632 0     0 1   my $self = shift;
633 0           my $track = int (shift);
634 0           my $ext = shift;
635              
636             # Check for a positive track number
637 0 0         $track > 0 || throw Error::Simple ("ERROR: setExttn, track must be a positive integer.");
638              
639             # Set the ext
640 0           $self->{Net_FreeDB2_Entry}{track}{$track}{ext} = $ext;
641             }
642              
643             sub getExttn {
644 0     0 1   my $self = shift;
645 0           my $track = int (shift);
646              
647             # Check for a positive or 0 track number
648 0 0         $track > -1 || throw Error::Simple ("ERROR: setExttn, track must be a positive or 0 integer.");
649              
650             # Handle a specified track number
651 0 0         if ($track) {
652             # Check for an existing track number
653 0 0 0       (exists ($self->{Net_FreeDB2_Entry}{track}{$track}) && exists ($self->{Net_FreeDB2_Entry}{track}{$track}{ext})) || throw Error::Simple ("ERROR: getFrameOffset, no track with number '$track'.");
654              
655             # Return the ext
656 0           return ($self->{Net_FreeDB2_Entry}{track}{$track}{ext});
657             }
658              
659             # Return all ext if track == 0;
660 0           my @ret = ();
661 0           foreach my $track (sort {$a <=> $b} (keys (%{$self->{Net_FreeDB2_Entry}{track}}))) {
  0            
  0            
662 0 0         exists ($self->{Net_FreeDB2_Entry}{track}{$track}{ext}) || next;
663 0           push (@ret, $self->{Net_FreeDB2_Entry}{track}{$track}{ext});
664             }
665 0           return (@ret);
666             }
667              
668             sub setDbLineLen {
669 0     0 1   my $self = shift;
670 0           my $length = int (shift);
671              
672 0 0         $length > 10 || throw Error::Simple ('ERROR: Net::FreeDB2::Entry::setDbLineLen, length must be greater than 10.');
673 0           $self->{Net_FreeDB2_Entry}{db_line_len} = $length;
674             }
675              
676             sub getDbLineLen {
677 0     0 1   my $self = shift;
678              
679 0   0       return ($self->{Net_FreeDB2_Entry}{db_line_len} || $DB_LINE_LEN_DEF);
680             }
681              
682             sub print_db_length {
683 0     0 1   my $self = shift;
684 0           my $array_ref = shift;
685 0           my $pre = shift;
686 0   0       my $str = shift || '';
687              
688 0           $str =~ s/\n/\\n/gm;
689              
690 0           my $first = 1;
691 0   0       while ($first || $str) {
692 0           push (@{$array_ref}, $pre . substr ($str, 0, $self->getDbLineLen () - 1 - length ($pre), ''));
  0            
693 0           $first = 0;
694             }
695             }
696              
697             sub digitSum {
698 0     0 1   my $int = int (shift);
699              
700              
701 0           my $sum = 0;
702 0           while ($int) {
703 0           $sum += $int % 10;
704 0           $int = int ($int / 10);
705             }
706 0           return ($sum);
707             }
708              
709             1;
710             __END__