| InfoSys-FreeDB documentation | Contained in the InfoSys-FreeDB distribution. |
ARRAY must be a (sub)class of:InfoSys::FreeDB::Entry - FreeDB entry
require InfoSys::FreeDB;
require InfoSys::FreeDB::Entry;
# Read entry from the default CD device
my $entry = InfoSys::FreeDB::Entry->new_from_cdparanoia();
# Create a HTTP connection
my $fact = InfoSys::FreeDB->new();
my $conn = $fact->create_connection( {
client_name => 'testing-InfoSys::FreeDB',
client_version => $InfoSys::FreeDB::VERSION,
} );
# Query FreeDB
my $res_q = $conn->query( $entry );
scalar( $res_q->get_match() ) ||
die 'no matches found for the disck in the default CD-Rom drive';
# Read the first match
my $res_r = $conn->read( ( $res_q->get_match() )[0] );
# Write the entry to STDERR
use IO::Handle;
my $fh = IO::Handle->new_from_fd( fileno(STDERR), 'w' );
$res_r->get_entry()->write_fh( $fh );
FreeDB entry
InfoSys::FreeDB::Entry contains information on FreeDB entries.
Creates a new InfoSys::FreeDB::Entry object. OPT_HASH_REF is a hash reference used to pass initialization options. On error an exception Error::Simple is thrown.
Options for OPT_HASH_REF may include:
artistPassed to set_artist().
client_commentPassed to set_client_comment().
client_namePassed to set_client_name().
client_versionPassed to set_client_version().
disc_lengthPassed to set_disc_length().
discidPassed to set_discid().
extdPassed to set_extd().
genrePassed to set_genre().
revisionPassed to set_revision().
titlePassed to set_title().
trackPassed to set_track(). Must be an ARRAY reference.
yearPassed to set_year().
Creates a new InfoSys::FreeDB::Entry object from the specified array reference. ARRAY_REF is an array reference containing the lines of the entry file. On error an exception Error::Simple is thrown.
Creates a new InfoSys::FreeDB::Entry object using cdparanoia. If specified, DEVICE is used as CD-Rom device name. Otherwise the default cdparanoia CD-Rom device is used. On error an exception Error::Simple is thrown.
Creates a new InfoSys::FreeDB::Entry object from the specified file handle. FILE_HANDLE is a IO::Handle object. On error an exception Error::Simple is thrown.
Creates a new InfoSys::FreeDB::Entry object from the specified file. FILE is a file name. On error an exception Error::Simple is thrown.
Returns the count of items in ARRAY that are in the entry track list.
Returns the entry artist.
Returns the entry client comment.
Returns the entry client name.
Returns the entry client version.
Returns the entry disc length.
Returns the entry discid.
Returns the entry extd.
Returns the entry genre.
Returns the entry revision.
Returns the entry title.
Returns an ARRAY containing the entry track list. INDEX_ARRAY is an optional list of indexes which when specified causes only the indexed elements in the ordered list to be returned. If not specified, all elements are returned.
Returns the entry year.
Calculates the FreeDB disc ID and stores it through method set_discid(). Note that in the InfoSys::FreeDB::Connectionclasses the method discid() lets the FreeDB server calculate the disc ID.
Pop and return an element off the entry track list. On error an exception Error::Simple is thrown.
Push additional values on the entry track list. ARRAY is the list value. On error an exception Error::Simple is thrown.
ARRAY must be a (sub)class of:
Set the entry artist. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry client comment. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry client name. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry client version. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry disc length. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry discid. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry extd. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry genre. VALUE is the value. On error an exception Error::Simple is thrown.
Set value in the entry track list. INDEX is the integer index which is greater than or equal to 0. VALUE is the value.
ARRAY must be a (sub)class of:
Set value in the entry track list. NUMBER is the integer index which is greater than 0. VALUE is the value.
ARRAY must be a (sub)class of:
Set the entry revision. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry title. VALUE is the value. On error an exception Error::Simple is thrown.
Set the entry track list absolutely. ARRAY is the list value. On error an exception Error::Simple is thrown.
ARRAY must be a (sub)class of:
Set the entry year. VALUE is the value. On error an exception Error::Simple is thrown.
Shift and return an element off the entry track list. On error an exception Error::Simple is thrown.
Unshift additional values on the entry track list. ARRAY is the list value. On error an exception Error::Simple is thrown.
ARRAY must be a (sub)class of:
Writes the entry to an ARRAY and retuens a reference to the ARRAY. On error an exception Error::Simple is thrown.
Writes the entry to the specified file handle. FILE_HANDLE is a IO::Handle object. On error an exception Error::Simple is thrown.
Writes the entry to the specified file. FILE is file name. On error an exception Error::Simple is thrown.
InfoSys::FreeDB, InfoSys::FreeDB::Connection, InfoSys::FreeDB::Connection::CDDBP, InfoSys::FreeDB::Connection::HTTP, InfoSys::FreeDB::Entry::Track, InfoSys::FreeDB::Match, InfoSys::FreeDB::Response, InfoSys::FreeDB::Response::DiscId, InfoSys::FreeDB::Response::Hello, InfoSys::FreeDB::Response::LsCat, InfoSys::FreeDB::Response::Motd, InfoSys::FreeDB::Response::Proto, InfoSys::FreeDB::Response::Query, InfoSys::FreeDB::Response::Quit, InfoSys::FreeDB::Response::Read, InfoSys::FreeDB::Response::SignOn, InfoSys::FreeDB::Response::Sites, InfoSys::FreeDB::Response::Stat, InfoSys::FreeDB::Response::Ver, InfoSys::FreeDB::Response::Whom, InfoSys::FreeDB::Response::Write::1, InfoSys::FreeDB::Response::Write::2, InfoSys::FreeDB::Site
None known (yet.)
First development: September 2003 Last update: November 2003
Vincenzo Zocca
Copyright 2003 by Vincenzo Zocca
This file is part of the InfoSys::FreeDB module hierarchy for Perl by
Vincenzo Zocca.
The InfoSys::FreeDB module hierarchy is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
The InfoSys::FreeDB module hierarchy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the InfoSys::FreeDB module hierarchy; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| InfoSys-FreeDB documentation | Contained in the InfoSys-FreeDB distribution. |
package InfoSys::FreeDB::Entry; use 5.006; use strict; use warnings; use AutoLoader qw(AUTOLOAD); use Error qw(:try); use IO::File; our $CDPARA_TOTAL_RX = '^\s*TOTAL\s+(\d+)'; our $CDPARA_TRACK_RX = '^\s*(\d+)\.\s*(\d+)\s*\[\d+[:.]\d+[:.]\d+\]\s*(\d+)\s*\[\d+[:.]\d+[:.]\d+\]'; our $DGENRE_RX = '^\s*DGENRE\s*=(.*)$'; our $DID_ERR = 'DISCID=<disc ID>'; our $DID_RX = '^\s*DISCID\s*=\s*(\S+)\s*$'; our $DL_ERR = '# Disc length: <length> seconds'; our $DL_RX = '^\s*#\s*Disc\s+length\s*:\s*(\d+)'; our $DTITLE_RX = '^\s*DTITLE\s*=(.*)$'; our $DYEAR_RX = '^\s*DYEAR\s*=(.*)$'; our $EXTD_RX = '^\s*EXTD\s*=(.*)$'; our $EXTTN_RX = '^\s*EXTT(\d+)\s*=(.*)$'; our $FO_ERR = '# <number>'; our $FO_RX = '^\s*#\s*(\d+)\s*$'; our $REV_ERR = '# Revision: <revision>'; our $REV_RX = '^\s*#\s*Revision\s*:\s*(\d+)\s*'; our $SUB_ERR = '# Submitted via: <client_name> <client_version> <optional_comments>'; our $SUB_RX = '^\s*#\s*Submitted\s+via\s*:\s*(\S+)\s+(\S+)\s*(.*)\s*$'; our $TFO_ERR = '# Track frame offsets:'; our $TFO_RX = '^\s*#\s*Track\s+frame\s+offsets\s*:\s*$'; our $TTITLEN_RX = '^\s*TTITLE(\d+)\s*=(.*)$'; our $XMCD_ERR = '# xmcd'; our $XMCD_RX = '^\s*#\s*xmcd'; # Used by _value_is_allowed our %ALLOW_ISA = ( 'track' => [ 'InfoSys::FreeDB::Entry::Track' ], ); # Used by _value_is_allowed our %ALLOW_REF = ( ); # Used by _value_is_allowed our %ALLOW_RX = ( ); # Used by _value_is_allowed our %ALLOW_VALUE = ( ); # Package version our ($VERSION) = '$Revision: 0.92 $' =~ /\$Revision:\s+([^\s]+)/; 1; __END__
sub new { my $class = shift; my $self = {}; bless( $self, ( ref($class) || $class ) ); return( $self->_initialize(@_) ); } sub new_from_array_ref { my $class = shift; my $array_ref = shift; # Create an empty object my $self = $class->new(); # Read from the file array reference $self->read_array_ref($array_ref); # Return $self return($self); } sub new_from_cdparanoia { my $class = shift; my $dev = shift; # Setup the cdparanoia command my $cmd = 'cdparanoia -Q'; $cmd .= " -d '$dev'" if ($dev); # Run the cdparanoia command use IO::File; my $fh = IO::File->new ("$cmd 2>&1 |"); defined ($fh) || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::new_from_cdparanoia, Failed to open pipe from command '$cmd'."); # Create an empty object my $self = $class->new(); # Parse cdparanoia's output my $frame_offset = 150; while ( my $line = $fh->getline() ) { my ($track, $frame_length, $frame_begin) = $line =~ /$CDPARA_TRACK_RX/; if ( defined($track) ) { require InfoSys::FreeDB::Entry::Track; $self->push_track( InfoSys::FreeDB::Entry::Track->new( { offset => $frame_offset, } ) ); $frame_offset += $frame_length; next; } my ($frame_total) = $line =~ /$CDPARA_TOTAL_RX/; if ( defined($frame_total) ) { $self->set_disc_length( int($frame_total / 75) + 2); last; } } # Check if anything is read ($frame_offset == 150) && throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::new_from_cdparanoia, Command '$cmd' did not produce any usable output."); # Return $self return($self); } sub new_from_fh { my $class = shift; my $fh = shift; # Create an empty object my $self = $class->new(); # Read from the file handle $self->read_fh($fh); # Return $self return($self); } sub new_from_fn { my $class = shift; my $file = shift; # Open file for reading my $fh = IO::File->new( $file, 'r'); defined($fh) || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::new_from_fn, failed to open file '$file' for reading."); # Call new_from_fh return( $class->new_from_fh( $fh) ); } sub _initialize { my $self = shift; my $opt = defined($_[0]) ? shift : {}; # Check $opt ref($opt) eq 'HASH' || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::_initialize, first argument must be 'HASH' reference."); # artist, SINGLE exists( $opt->{artist} ) && $self->set_artist( $opt->{artist} ); # client_comment, SINGLE exists( $opt->{client_comment} ) && $self->set_client_comment( $opt->{client_comment} ); # client_name, SINGLE exists( $opt->{client_name} ) && $self->set_client_name( $opt->{client_name} ); # client_version, SINGLE exists( $opt->{client_version} ) && $self->set_client_version( $opt->{client_version} ); # disc_length, SINGLE exists( $opt->{disc_length} ) && $self->set_disc_length( $opt->{disc_length} ); # discid, SINGLE exists( $opt->{discid} ) && $self->set_discid( $opt->{discid} ); # extd, SINGLE exists( $opt->{extd} ) && $self->set_extd( $opt->{extd} ); # genre, SINGLE exists( $opt->{genre} ) && $self->set_genre( $opt->{genre} ); # revision, SINGLE exists( $opt->{revision} ) && $self->set_revision( $opt->{revision} ); # title, SINGLE exists( $opt->{title} ) && $self->set_title( $opt->{title} ); # track, MULTI if ( exists( $opt->{track} ) ) { ref( $opt->{track} ) eq 'ARRAY' || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::_initialize, specified value for option 'track' must be an 'ARRAY' reference."); $self->set_track( @{ $opt->{track} } ); } else { $self->set_track(); } # year, SINGLE exists( $opt->{year} ) && $self->set_year( $opt->{year} ); # Return $self return($self); } sub _digit_sum { my $int = int(shift); my $sum = 0; while ( $int ) { $sum += $int % 10; $int = int( $int / 10 ); } return($sum); } sub _str2db_lines { my $pre = shift; my $str = shift || ''; $str =~ s/\n/\\n/gm; my @array = (); my $first = 1; while ($first || $str) { push( @array, $pre . substr($str, 0, 80 - 1 - length($pre), '') ); $first = 0; } return(@array); } sub _value_is_allowed { my $name = shift; # Value is allowed if no ALLOW clauses exist for the named attribute if ( ! exists( $ALLOW_ISA{$name} ) && ! exists( $ALLOW_REF{$name} ) && ! exists( $ALLOW_RX{$name} ) && ! exists( $ALLOW_VALUE{$name} ) ) { return(1); } # At this point, all values in @_ must to be allowed CHECK_VALUES: foreach my $val (@_) { # Check ALLOW_ISA if ( ref($val) && exists( $ALLOW_ISA{$name} ) ) { foreach my $class ( @{ $ALLOW_ISA{$name} } ) { &UNIVERSAL::isa( $val, $class ) && next CHECK_VALUES; } } # Check ALLOW_REF if ( ref($val) && exists( $ALLOW_REF{$name} ) ) { exists( $ALLOW_REF{$name}{ ref($val) } ) && next CHECK_VALUES; } # Check ALLOW_RX if ( defined($val) && ! ref($val) && exists( $ALLOW_RX{$name} ) ) { foreach my $rx ( @{ $ALLOW_RX{$name} } ) { $val =~ /$rx/ && next CHECK_VALUES; } } # Check ALLOW_VALUE if ( ! ref($val) && exists( $ALLOW_VALUE{$name} ) ) { exists( $ALLOW_VALUE{$name}{$val} ) && next CHECK_VALUES; } # We caught a not allowed value return(0); } # OK, all values are allowed return(1); } sub exists_track { my $self = shift; # Count occurrences my $count = 0; foreach my $val1 (@_) { foreach my $val2 ( @{ $self->{InfoSys_FreeDB_Entry}{track} } ) { ( $val1 eq $val2 ) && $count ++; } } return($count); } sub get_artist { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{artist} ); } sub get_client_comment { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{client_comment} ); } sub get_client_name { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{client_name} ); } sub get_client_version { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{client_version} ); } sub get_disc_length { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{disc_length} ); } sub get_discid { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{discid} ); } sub get_extd { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{extd} ); } sub get_genre { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{genre} ); } sub get_revision { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{revision} ); } sub get_title { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{title} ); } sub get_track { my $self = shift; if ( scalar(@_) ) { my @ret = (); foreach my $i (@_) { push( @ret, $self->{InfoSys_FreeDB_Entry}{track}[ int($i) ] ); } return(@ret); } else { # Return the full list return( @{ $self->{InfoSys_FreeDB_Entry}{track} } ); } } sub get_year { my $self = shift; return( $self->{InfoSys_FreeDB_Entry}{year} ); } sub mk_discid { my $self = shift; # Make sum my $sum = 0; my @track = $self->get_track(); for ( my $i = 0; $i < scalar( @track ); $i++) { $sum += &_digit_sum( $track[$i]->get_offset() / 75 ); } # Make ID out of sum, get_disc_length()-2 and the number of tracks. # And call set_discid(). $self->set_discid( sprintf("%08x", ( $sum % 0xff ) << 24 | int( $self->get_disc_length() - 2 ) << 8 | scalar( @track ) ) ); } sub pop_track { my $self = shift; # Pop an element from the list return( pop( @{ $self->{InfoSys_FreeDB_Entry}{track} } ) ); } sub push_track { my $self = shift; # Check if isas/refs/rxs/values are allowed &_value_is_allowed( 'track', @_ ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::push_track, one or more specified value(s) '@_' is/are not allowed."); # Push the list push( @{ $self->{InfoSys_FreeDB_Entry}{track} }, @_ ); } sub read_array_ref { my $self = shift; my $array = shift; # From http://www.freedb.org/src/latest/DBFORMAT : # The beginning of the first line in a database entry should consist of # the string "# xmcd". This string identifies the file as an xmcd format # CD database file. More text can appear after the "xmcd", but is # unnecessary. my $line = shift( @{$array} ); my $line_nr = 1; $line =~ /$XMCD_RX/ || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$XMCD_ERR' in line " . $line_nr . ' but encountered: ' . $line); # Tolerate '#.*' until '# Track frame offsets:' while ( $line = shift( @{$array} ) ) { $line_nr++; $line =~ /$TFO_RX/ && last; $line =~ /^\s*#/ && next; throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$TFO_ERR' in line " . $line_nr . ' but encountered: ' . $line); } # Delete all tracks $self->set_track(); # Read frame offsets my $track = 0; while ( $line = shift( @{$array} ) ) { $line_nr++; # Read the offset my ($offset) = $line =~ /$FO_RX/; if ( ! defined ($offset) ) { unshift( @{$array}, $line ); last; } # Put the offset in the correct track object $track++; require InfoSys::FreeDB::Entry::Track; $self->push_track( InfoSys::FreeDB::Entry::Track->new( { offset => $offset, } ) ); } $track || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$FO_ERR' in line " . $line_nr . ' but encountered: ' . $line); # Read '# Disc length', '"# Revision', "# Submitted via' until 'DID' while ( $line = shift( @{$array} ) ) { $line_nr++; my ($len) = $line =~ /$DL_RX/i; if ( defined($len) ) { $self->set_disc_length($len); next; } my ($rev) = $line =~ /$REV_RX/i; if ( defined($rev) ) { $self->set_revision($rev); next; } my ($name, $vers, $comm) = $line =~ /$SUB_RX/i; if (defined ($name)) { $self->set_client_name($name); $self->set_client_version($vers); $self->set_client_comment($comm); next; } my ($discid) = $line =~ /$DID_RX/i; if (defined ($discid)) { $self->set_discid($discid); last; } ($line =~ /^\s*#/) && next; last; } $self->get_disc_length() || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$DL_ERR' in line " . $line_nr . ' but encountered: ' . $line); defined ( $self->get_revision() ) || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$REV_ERR' in line " . $line_nr . ' but encountered: ' . $line); $self->get_client_name() || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$SUB_ERR' in line " . $line_nr . ' but encountered: ' . $line); $self->get_discid() || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, Expected '$DID_ERR' in line " . $line_nr . ' but encountered: ' . $line); # Read DTITLE, DYEAR, DGENRE, TTITLEN, EXTD, EXTTN # Indeed, this code is a bit forgiving my $DTITLE = ''; my $DYEAR = ''; my $DGENRE = ''; my @TTITLEN = ''; my $EXTD = ''; my @EXTTN = ''; while ( $line = shift( @{$array} ) ) { $line_nr++; my $str; ($str) = $line =~ /$DTITLE_RX/; if ( defined($str) ) { $DTITLE .= $str; next; } ($str) = $line =~ /$DYEAR_RX/; if ( defined($str) ) { $DYEAR .= $str; next; } ($str) = $line =~ /$DGENRE_RX/; if ( defined($str) ) { $DGENRE .= $str; next; } my $nr; ($nr, $str) = $line =~ /$TTITLEN_RX/; if ( defined($nr) ) { $TTITLEN[$nr] .= $str; next; } ($str) = $line =~ /$EXTD_RX/; if ( defined($str) ) { $EXTD .= $str; next; } ($nr, $str) = $line =~ /$EXTTN_RX/; if ( defined($nr) ) { $EXTTN[$nr] .= $str; next; } } # Set artist and title my ($artist, $title) = split( /\s*\/\s*/, $DTITLE, 2 ); $title = '' if (!$title); $artist =~ s/\\n/\n/gm; $title =~ s/\\n/\n/gm; $self->set_artist($artist); $self->set_title($title); # DYEAR $DYEAR =~ s/\\n/\n/gm; $self->set_year($DYEAR); # DGENRE $DGENRE =~ s/\\n/\n/gm; $self->set_genre($DGENRE); # TTITLEN # First check if there are more TTITLE than offset lines scalar( @TTITLEN ) > scalar( $self->get_track() ) && throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, More TTITLEN than frame offset lines."); foreach my $track ( $self->get_track() ) { $track->set_title( shift(@TTITLEN) || '' ); } # EXTD $EXTD =~ s/\\n/\n/gm; $self->set_extd($EXTD); # EXTTN # First check if there are more EXTTN than offset lines scalar( @EXTTN ) > scalar( $self->get_track() ) && throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::read, More EXTTN than frame offset lines."); foreach my $track ( $self->get_track() ) { $track->set_extt( shift(@EXTTN) || '' ); } } sub read_fh { my $self = shift; my $fh = shift; my @array = (); while ( my $line = $fh->getline() ) { chomp($line); push( @array, $line ); } return( $self->read_array_ref( \@array ) ); } sub set_artist { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'artist', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_artist, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{artist} = $val; } sub set_client_comment { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'client_comment', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_client_comment, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{client_comment} = $val; } sub set_client_name { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'client_name', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_client_name, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{client_name} = $val; } sub set_client_version { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'client_version', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_client_version, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{client_version} = $val; } sub set_disc_length { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'disc_length', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_disc_length, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{disc_length} = $val; } sub set_discid { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'discid', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_discid, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{discid} = $val; } sub set_extd { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'extd', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_extd, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{extd} = $val; } sub set_genre { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'genre', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_genre, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{genre} = $val; } sub set_idx_track { my $self = shift; my $idx = shift; my $val = shift; # Check if index is a positive integer or zero ( $idx == int($idx) ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_idx_track, the specified index '$idx' is not an integer."); ( $idx >= 0 ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_idx_track, the specified index '$idx' is not a positive integer or zero."); # Check if isas/refs/rxs/values are allowed &_value_is_allowed( 'track', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_idx_track, one or more specified value(s) '@_' is/are not allowed."); # Set the value in the list $self->{InfoSys_FreeDB_Entry}{track}[$idx] = $val; } sub set_num_track { my $self = shift; my $num = shift; # Check if index is an integer ( $num == int($num) ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_num_track, the specified number '$num' is not an integer."); # Call set_idx_track $self->set_idx_track( $num - 1, @_ ); } sub set_revision { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'revision', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_revision, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{revision} = $val; } sub set_title { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'title', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_title, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{title} = $val; } sub set_track { my $self = shift; # Check if isas/refs/rxs/values are allowed &_value_is_allowed( 'track', @_ ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_track, one or more specified value(s) '@_' is/are not allowed."); # Set the list @{ $self->{InfoSys_FreeDB_Entry}{track} } = @_; } sub set_year { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'year', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::set_year, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Entry}{year} = $val; } sub shift_track { my $self = shift; # Shift an element from the list return( shift( @{ $self->{InfoSys_FreeDB_Entry}{track} } ) ); } sub unshift_track { my $self = shift; # Check if isas/refs/rxs/values are allowed &_value_is_allowed( 'track', @_ ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Entry::unshift_track, one or more specified value(s) '@_' is/are not allowed."); # Unshift the list unshift( @{ $self->{InfoSys_FreeDB_Entry}{track} }, @_ ); } sub write_array_ref { my $self = shift; # Make an empty array my @array = (); # xmcd push(@array, "# xmcd"); push(@array, "#"); # Make maximum tracks my $max = scalar( $self->get_track() ); # Track frame offsets: push(@array, "# Track frame offsets:"); foreach my $track ( $self->get_track() ) { push( @array, "#\t" . $track->get_offset() ); } push(@array, "#"); # Disc length: N seconds push(@array, "# Disc length: " . $self->get_disc_length() . " seconds"); push(@array, "#"); # Revision: N push (@array, "# Revision: " . ( $self->get_revision() || '0') ); push (@array, "#"); # Submitted via: client_name client_version optional_comments my $str = ($self->get_client_name() || 'none') . ' '; $str .= ($self->get_client_version() || '0'); $str .= ' ' . $self->get_client_comment() if ( $self->get_client_comment() ); push( @array, sprintf ("%.79s", "# Submitted via: " . $str) ); push(@array, "#"); # DISCID $self->get_discid() || $self->mk_discid(); push( @array, "DISCID=" . ( $self->get_discid() ) ); # DTITLE (Artist / Title) push( @array, &_str2db_lines( 'DTITLE=', ($self->get_artist() || '') . ' / ' . ($self->get_title() || '') ) ); # DYEAR push( @array, &_str2db_lines( 'DYEAR=', $self->get_year() ) ); # DGENRE push( @array, &_str2db_lines( 'DGENRE=', $self->get_genre() ) ); # TTITLEN my $i = 0; foreach my $track ( $self->get_track() ) { if ( defined($track) ) { push( @array, &_str2db_lines( "TTITLE$i=", $track->get_title() || '' ) ); } else { push( @array, &_str2db_lines( "TTITLE$i=", '' ) ); } $i++; } # EXTD push( @array, &_str2db_lines( 'EXTD=', $self->get_extd() ) ); # EXTTN $i = 0; foreach my $track ( $self->get_track() ) { if ( defined($track) ) { push( @array, &_str2db_lines( "EXTT$i=", $track->get_extt() || '' ) ); } else { push( @array, &_str2db_lines( "EXTT$i=", '' ) ); } $i++; } # PLAYORDER push(@array, "PLAYORDER="); # Return array reference return( \@array ); } sub write_fh { my $self = shift; my $fh = shift; foreach my $line ( @{ $self->write_array_ref() } ) { $fh->print( "$line\n" ); } } sub write_fn { my $self = shift; my $fn = shift; my $fh = IO::File->new( $fn, 'w' ); defined($fh) || throw Error::Simple ("ERROR: InfoSys::FreeDB::Entry::write_fn, Failed to open file '$fn' for writing."); $self->write_fh($fh); }