diff --git a/src/ID3/ExtendedHeader.php b/src/ID3/ExtendedHeader.php index c299074..a5f96d1 100644 --- a/src/ID3/ExtendedHeader.php +++ b/src/ID3/ExtendedHeader.php @@ -78,13 +78,13 @@ final class ID3_ExtendedHeader extends ID3_Object private $_size; /** @var integer */ - private $_flags; + private $_flags = 0; /** @var integer */ private $_crc; /** @var integer */ - private $_restrictions; + private $_restrictions = 0; /** * Constructs the class with given parameters and reads object related data @@ -92,9 +92,12 @@ final class ID3_ExtendedHeader extends ID3_Object * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; $offset = $this->_reader->getOffset(); $this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE()); @@ -105,9 +108,9 @@ final class ID3_ExtendedHeader extends ID3_Object $this->_reader->skip(1); if ($this->hasFlag(self::CRC32)) { $this->_reader->skip(1); - $this->_crc = Transform::fromInt32BE - (($this->_reader->read(1) << 4) & - $this->decodeSynchsafe32($this->_reader->read(4))); + $this->_crc = + Transform::fromInt8($this->_reader->read(1)) * (0xfffffff + 1) + + decodeSynchsafe32(Transform::fromUInt32BE($this->_reader->read(4))); } if ($this->hasFlag(self::RESTRICTED)) { $this->_reader->skip(1); @@ -162,14 +165,28 @@ final class ID3_ExtendedHeader extends ID3_Object /** * Sets whether the CRC-32 should be generated upon tag write. * - * @param boolean $useCrc Whether CRC-32 should be generated + * @param boolean $useCrc Whether CRC-32 should be generated. */ - public function setCrc($useCrc) + public function useCrc($useCrc) { if ($useCrc) - $this->setFlags($this->getFlags() | self::CDC32); + $this->setFlags($this->getFlags() | self::CRC32); else - $this->setFlags($this->getFlags() & ~self::CDC32); + $this->setFlags($this->getFlags() & ~self::CRC32); + } + + /** + * Sets the CRC-32. The CRC-32 value is calculated of all the frames in the + * tag and includes padding. + * + * @param integer $crc The 32-bit CRC value. + */ + public function setCrc($crc) + { + if (is_bool($crc)) + $this->useCrc($crc); + else + $this->_crc = $crc; } /** @@ -235,7 +252,6 @@ final class ID3_ExtendedHeader extends ID3_Object /** * Returns the header raw data. * - * @todo CRC must use safesynch * @return string */ public function toString() @@ -243,7 +259,9 @@ final class ID3_ExtendedHeader extends ID3_Object return Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) . Transform::toInt8(1) . Transform::toInt8($this->_flags) . ($this->hasFlag(self::UPDATE) ? "\0" : "") . - ($this->hasFlag(self::CRC32) ? Transform::toInt8(5) . $this->_crc : "") . + ($this->hasFlag(self::CRC32) ? Transform::toInt8(5) . + Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf /* eq >>> 28 */) . + Transform::toUInt32BE(encodeSynchsafe32($this->_crc)) : "") . ($this->hasFlag(self::RESTRICTED) ? Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : ""); } diff --git a/src/ID3/Frame/AENC.php b/src/ID3/Frame/AENC.php index 2693e50..af22d95 100644 --- a/src/ID3/Frame/AENC.php +++ b/src/ID3/Frame/AENC.php @@ -68,19 +68,25 @@ final class ID3_Frame_AENC extends ID3_Frame /** @var integer */ private $_previewLength; + /** @var string */ + private $_encryptionInfo; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); $this->_previewStart = substr($this->_data, 0, 2); $this->_previewLength = substr($this->_data, 2, 2); - $this->_data = substr($this->_data, 4); + $this->_encryptionInfo = substr($this->_data, 4); } /** @@ -89,25 +95,75 @@ final class ID3_Frame_AENC extends ID3_Frame * @return string */ public function getIdentifier() { return $this->_id; } - + + /** + * Sets the owner identifier string. + * + * @param string $id The owner identifier string. + */ + public function setIdentifier($id) { $this->_id = $id; } + /** * Returns the pointer to an unencrypted part of the audio in frames. * * @return integer */ public function getPreviewStart() { return $this->_previewStart; } - + + /** + * Sets the pointer to an unencrypted part of the audio in frames. + * + * @param integer $previewStart The pointer to an unencrypted part. + */ + public function setPreviewStart($previewStart) + { + $this->_previewStart = $previewStart; + } + /** * Returns the length of the preview in frames. * * @return integer */ public function getPreviewLength() { return $this->_previewLength; } - + + /** + * Sets the length of the preview in frames. + * + * @param integer $previewLength The length of the preview. + */ + public function setPreviewLength($previewLength) + { + $this->_previewLength = $previewLength; + } + /** * Returns the encryption info. * * @return string */ - public function getData() { return $this->_data; } + public function getEncryptionInfo() { return $this->_encryptionInfo; } + + /** + * Sets the encryption info binary string. + * + * @param string $encryptionInfo The data string. + */ + public function setEncryptionInfo($encryptionInfo) + { + $this->_encryptionInfo = $encryptionInfo; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + ($this->_id . "\0" . Transform::toInt16BE($this->_previewStart) . + Transform::toInt16BE($this->_previewLength) . $this->_encryptionInfo); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/APIC.php b/src/ID3/Frame/APIC.php index ffff12b..20dab0e 100644 --- a/src/ID3/Frame/APIC.php +++ b/src/ID3/Frame/APIC.php @@ -79,30 +79,36 @@ final class ID3_Frame_APIC extends ID3_Frame "Publisher/Studio logotype"); /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_mimeType; + private $_mimeType = "image/unknown"; /** @var integer */ - private $_imageType; + private $_imageType = 0; /** @var string */ private $_description; + /** @var string */ + private $_imageData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_encoding = substr($this->_data, 0, 1); + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_mimeType = substr ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); - $this->_pictureType = ord($this->_data{$pos++}); + $this->_pictureType = Transform::fromInt8($this->_data[$pos++]); $this->_data = substr($this->_data, $pos); switch ($this->_encoding) { @@ -128,14 +134,29 @@ final class ID3_Frame_APIC extends ID3_Frame * @return integer */ public function getEncoding() { return $this->_encoding; } - + /** - * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + + /** + * Returns the MIME type. The MIME type is always ISO-8859-1 encoded. * * @return string */ public function getMimeType() { return $this->_mimeType; } - + + /** + * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } + /** * Returns the image type. * @@ -143,17 +164,70 @@ final class ID3_Frame_APIC extends ID3_Frame */ public function getImageType() { return $this->_imageType; } + /** + * Sets the image type code. + * + * @param integer $imageType The image type code. + */ + public function setImageType($imageType) { $this->_imageType = $imageType; } + /** * Returns the file description. * * @return string */ public function getDescription() { return $this->_description; } - + /** - * Returns the embedded picture data. + * Sets the content description text using given encoding. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = false) + { + $this->_description = $description; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the embedded image data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_imageData; } + + /** + * Sets the embedded image data. + * + * @param string $imageData The image data. + */ + public function setData($imageData) { $this->_imageData = $imageData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_mimeType . "\0" . + Transform::toInt8($this->_imageType); + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_description) . "\0\0"; + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_description) . "\0\0"; + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_description) . "\0\0"; + break; + default: + $data .= $this->_description . "\0"; + } + parent::setData($data . $this->_imageData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/ASPI.php b/src/ID3/Frame/ASPI.php index 98269c7..4c173b6 100644 --- a/src/ID3/Frame/ASPI.php +++ b/src/ID3/Frame/ASPI.php @@ -50,6 +50,7 @@ require_once("ID3/Frame.php"); * {@link ID3_Frame_TLEN} frame, indicating the duration of the file in * milliseconds. There may only be one audio seek point index frame in a tag. * + * @todo Data parsing and write support * @package php-reader * @subpackage ID3 * @author Sven Vollbehr @@ -70,30 +71,34 @@ final class ID3_Frame_ASPI extends ID3_Frame private $_size; /** @var Array */ - private $_fraction = array(); + private $_fractions = array(); /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + throw new ID3_Exception("Write not supported yet"); $this->_dataStart = Transform::fromInt32BE(substr($this->_data, 0, 4)); $this->_dataLength = Transform::fromInt32BE(substr($this->_data, 4, 4)); $this->_size = Transform::fromInt16BE(substr($this->_data, 8, 2)); - $bitsPerPoint = substr($this->_data, 10, 1); - for ($i = 0, $offset = 11; $i < $this->_size; $i++) { + + $bitsPerPoint = Transform::fromInt8($this->_data[10]); + /*for ($i = 0, $offset = 11; $i < $this->_size; $i++) { if ($bitsPerPoint == 16) { - $this->_fraction[$i] = substr($this->_data, $offset, 2); + $this->_fractions[$i] = substr($this->_data, $offset, 2); $offset += 2; } else { - $this->_fraction[$i] = substr($this->_data, $offset, 1); + $this->_fractions[$i] = substr($this->_data, $offset, 1); $offset ++; } - } + }*/ } /** @@ -103,6 +108,13 @@ final class ID3_Frame_ASPI extends ID3_Frame */ public function getDataStart() { return $this->_dataStart; } + /** + * Sets the byte offset from the beginning of the file. + * + * @param integer $dataStart The offset. + */ + public function setDataStart($dataStart) { $this->_dataStart = $dataStart; } + /** * Returns the byte length of the audio data being indexed. * @@ -110,12 +122,22 @@ final class ID3_Frame_ASPI extends ID3_Frame */ public function getDataLength() { return $this->_dataLength; } + /** + * Sets the byte length of the audio data being indexed. + * + * @param integer $dataLength The length. + */ + public function setDataLength($dataLength) + { + $this->_dataLength = $dataLength; + } + /** * Returns the number of index points in the frame. * * @return integer */ - public function getSize() { return $this->_size; } + public function getSize() { return count($this->_fractions); } /** * Returns the numerator of the fraction representing a relative position in @@ -125,5 +147,10 @@ final class ID3_Frame_ASPI extends ID3_Frame * @param integer $index The fraction numerator. * @return integer */ - public function getFractionAt($index) { return $this->_fraction[$index]; } + public function getFractionAt($index) + { + if (isset($this->_fractions[$index])) + return $this->_fractions[$index]; + return false; + } } diff --git a/src/ID3/Frame/AbstractLink.php b/src/ID3/Frame/AbstractLink.php index 51694c6..926727f 100644 --- a/src/ID3/Frame/AbstractLink.php +++ b/src/ID3/Frame/AbstractLink.php @@ -75,7 +75,7 @@ abstract class ID3_Frame_AbstractLink extends ID3_Frame public function getLink() { return $this->_link; } /** - * Sets the link. + * Sets the link. The link encoding is always ISO-8859-1. * * @param string $link The link. */ diff --git a/src/ID3/Frame/AbstractText.php b/src/ID3/Frame/AbstractText.php index 5aebf38..3937dfc 100644 --- a/src/ID3/Frame/AbstractText.php +++ b/src/ID3/Frame/AbstractText.php @@ -71,7 +71,7 @@ abstract class ID3_Frame_AbstractText extends ID3_Frame if ($reader === null) return; - $this->_encoding = ord($this->_data{0}); + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_data = substr($this->_data, 1); switch ($this->_encoding) { case self::UTF16: @@ -98,9 +98,10 @@ abstract class ID3_Frame_AbstractText extends ID3_Frame /** * Sets the text encoding. * + * @see ID3_Encoding * @param integer $encoding The text encoding. */ - public function setEncoding($encoding) { $this->_encoding = $encoding; }; + public function setEncoding($encoding) { $this->_encoding = $encoding; } /** * Returns the first text chunk the frame contains. @@ -120,11 +121,13 @@ abstract class ID3_Frame_AbstractText extends ID3_Frame * Sets the text using given encoding. * * @param mixed $text The test string or an array of strings. + * @param integer $encoding The text encoding. */ - public function setText($text, $encoding = ID3_Encoding::UTF8) + public function setText($text, $encoding = false) { - $this->_encoding = $encoding; $this->_text = is_array($text) ? $text : array($text); + if ($encoding !== false) + $this->_encoding = $encoding; } /** diff --git a/src/ID3/Frame/COMM.php b/src/ID3/Frame/COMM.php index 8764468..b0f4803 100644 --- a/src/ID3/Frame/COMM.php +++ b/src/ID3/Frame/COMM.php @@ -39,6 +39,7 @@ require_once("ID3/Frame.php"); require_once("ID3/Encoding.php"); require_once("ID3/Language.php"); +require_once("ID3/Exception.php"); /**#@-*/ /** @@ -60,10 +61,10 @@ final class ID3_Frame_COMM extends ID3_Frame implements ID3_Encoding, ID3_Language { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_language; + private $_language = "eng"; /** @var string */ private $_description; @@ -76,11 +77,14 @@ final class ID3_Frame_COMM extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - $this->_encoding = ord($this->_data{0}); + if ($reader === null) + return; + + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_language = substr($this->_data, 1, 3); $this->_data = substr($this->_data, 4); @@ -111,27 +115,106 @@ final class ID3_Frame_COMM extends ID3_Frame * @return integer */ public function getEncoding() { return $this->_encoding; } - + + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the language code as specified in the * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. * - * @see ID3_Language#ISO_639_2 * @return string */ public function getLanguage() { return $this->_language; } - + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language + * @param string $language The language code. + */ + public function setLanguage($language) { $this->_language = $language; } + /** * Returns the short content description. * * @return string */ public function getDescription() { return $this->_description; } - + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $language = false, + $encoding = false) + { + $this->_description = $description; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the comment text. * * @return string */ public function getText() { return $this->_text; } + + /** + * Sets the text using given encoding. The text language and encoding must be + * that of the description text. + * + * @param mixed $text The test string. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setText($text, $language = false, $encoding = false) + { + $this->_text = $text; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_language; + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_description) . "\0\0" . + Transform::toString16($this->_text); + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_description) . "\0\0" . + Transform::toString16BE($this->_text); + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_description) . "\0\0" . + Transform::toString16LE($this->_text); + break; + default: + $data .= $this->_description . "\0" . $this->_text; + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/COMR.php b/src/ID3/Frame/COMR.php index de8356e..56ab4e4 100644 --- a/src/ID3/Frame/COMR.php +++ b/src/ID3/Frame/COMR.php @@ -71,10 +71,10 @@ final class ID3_Frame_COMR extends ID3_Frame "Non-musical merchandise"); /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_currency; + private $_currency = "EUR"; /** @var string */ private $_price; @@ -86,7 +86,7 @@ final class ID3_Frame_COMR extends ID3_Frame private $_contact; /** @var integer */ - private $_delivery; + private $_delivery = 0; /** @var string */ private $_seller; @@ -97,16 +97,22 @@ final class ID3_Frame_COMR extends ID3_Frame /** @var string */ private $_mimeType = false; + /** @var string */ + private $_imageData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_encoding = ord($this->_data{0}); + $this->_encoding = Transform::fromInt8($this->_data[0]); list($pricing, $this->_data) = preg_split("/\\x00/", substr($this->_data, 1), 2); $this->_currency = substr($pricing, 0, 3); @@ -114,7 +120,7 @@ final class ID3_Frame_COMR extends ID3_Frame $this->_date = substr($this->_data, 0, 8); list($this->_contact, $this->_data) = preg_split("/\\x00/", substr($this->_data, 8), 2); - $this->_delivery = ord($this->_data{0}); + $this->_delivery = Transform::fromInt8($this->_data[0]); $this->_data = substr($this->_data, 1); switch ($this->_encoding) { @@ -140,8 +146,8 @@ final class ID3_Frame_COMR extends ID3_Frame if (strlen($this->_data) == 0) return; - list($this->_mimeType, $this->_data) = - preg_split("/\\x00/", $this->_data, 2); + list($this->_mimeType, $this->_imageData) = + preg_split("/\\x00/", $this->_imageData, 2); } /** @@ -151,6 +157,14 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getEncoding() { return $this->_encoding; } + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the currency code, encoded according to * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm @@ -160,6 +174,15 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getCurrency() { return $this->_currency; } + /** + * Sets the currency used in transaction, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @param string $currency The currency code. + */ + public function setCurrency($currency) { $this->_currency = $currency; } + /** * Returns the price as a numerical string using "." as the decimal separator. * @@ -170,6 +193,17 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getPrice() { return $this->_price; } + /** + * Sets the price. The price must use "." as the decimal separator and have + * multiple values be separated by a "/" character. + * + * @param string $price The price. + */ + public function setPrice($price) + { + $this->_price = $price; + } + /** * Returns the date as an 8 character date string (YYYYMMDD), describing for * how long the price is valid. @@ -178,12 +212,27 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getDate() { return $this->_price; } + /** + * Sets the date describing for how long the price is valid for. The date must + * be an 8 character date string (YYYYMMDD). + * + * @param string $date The date string. + */ + public function setDate($date) { $this->_date = $date; } + /** * Returns the contact URL, with which the user can contact the seller. * * @return string */ public function getContact() { return $this->_contact; } + + /** + * Sets the contact URL, with which the user can contact the seller. + * + * @param string $contact The contact URL. + */ + public function setContact($contact) { $this->_contact = $contact; } /** * Returns the delivery type with whitch the audio was delivered when bought. @@ -192,13 +241,34 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getDelivery() { return $this->_delivery; } + /** + * Sets the delivery type with whitch the audio was delivered when bought. + * + * @param integer $delivery The delivery type code. + */ + public function setDelivery($delivery) { $this->_delivery = $delivery; } + /** * Returns the name of the seller. * * @return string */ public function getSeller() { return $this->_seller; } - + + /** + * Sets the name of the seller using given encoding. The seller text encoding + * must be that of the description text. + * + * @param string $seller The name of the seller. + * @param integer $encoding The text encoding. + */ + public function setSeller($seller, $encoding = false) + { + $this->_seller = $seller; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the short description of the product. * @@ -206,6 +276,20 @@ final class ID3_Frame_COMR extends ID3_Frame */ public function getDescription() { return $this->_description; } + /** + * Sets the content description text using given encoding. The description + * encoding must be that of the seller text. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = false) + { + $this->_description = $description; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the MIME type of the seller's company logo, if attached, or * false otherwise. Currently only "image/png" and "image/jpeg" @@ -214,11 +298,58 @@ final class ID3_Frame_COMR extends ID3_Frame * @return string */ public function getMimeType() { return $this->_mimeType; } - + + /** + * Sets the MIME type. Currently only "image/png" and "image/jpeg" are + * allowed. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } + /** * Returns the embedded image binary data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_imageData; } + + /** + * Sets the embedded image data. + * + * @param string $imageData The image data. + */ + public function setData($imageData) { $this->_imageData = $imageData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_price . "\0" . + $this->_date . $this->_contact . "\0" . + Transform::toInt8($this->_delivery); + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_seller) . "\0\0" . + Transform::toString16($this->_description) . "\0\0"; + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_seller) . "\0\0"; + Transform::toString16($this->_description) . "\0\0"; + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_seller) . "\0\0"; + Transform::toString16($this->_description) . "\0\0"; + break; + default: + $data .= $this->_seller . "\0" . $this->_description . "\0"; + } + parent::setData + ($data . ($this->_mimeType ? + $this->_mimeType . "\0" . $this->_imageData : 0)); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/ENCR.php b/src/ID3/Frame/ENCR.php index 992caa2..88753e2 100644 --- a/src/ID3/Frame/ENCR.php +++ b/src/ID3/Frame/ENCR.php @@ -74,38 +74,81 @@ final class ID3_Frame_ENCR extends ID3_Frame /** @var integer */ private $_method; + /** @var string */ + private $_encryptionData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - + + if ($reader === null) + return; + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); - $this->_method = substr($this->_data, 0, 1); - $this->_data = substr($this->_data, 1); + $this->_method = Transform::fromInt8($this->_data[0]); + $this->_encryptionData = substr($this->_data, 1); } - + /** * Returns the owner identifier string. * * @return string */ public function getIdentifier() { return $this->_id; } - + + /** + * Sets the owner identifier string. + * + * @param string $id The owner identifier string. + */ + public function setIdentifier($id) { $this->_id = $id; } + /** * Returns the method symbol. * * @return integer */ public function getMethod() { return $this->_method; } - + + /** + * Sets the method symbol. + * + * @param integer $method The method symbol byte. + */ + public function setMethod($method) { $this->_method = $method; } + /** * Returns the encryption data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_encryptionData; } + + /** + * Sets the encryption data. + * + * @param string $encryptionData The encryption data string. + */ + public function setData($encryptionData) + { + $this->_encryptionData = $encryptionData; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + parent::setData + ($this->_id . "\0" . Transform::toInt8($this->_method) . + $this->_encryptionData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/EQU2.php b/src/ID3/Frame/EQU2.php index 3eb670a..c72dcbd 100644 --- a/src/ID3/Frame/EQU2.php +++ b/src/ID3/Frame/EQU2.php @@ -61,13 +61,13 @@ final class ID3_Frame_EQU2 extends ID3_Frame * one adjustment level to another occurs in the middle between two adjustment * points. */ - const BAND = 0x00; + const BAND = 0; /** * Interpolation type that defines that interpolation between adjustment * points is linear. */ - const LINEAR = 0x01; + const LINEAR = 1; /** @var integer */ private $_interpolation; @@ -83,20 +83,24 @@ final class ID3_Frame_EQU2 extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_interpolation = substr($this->_data, 0, 1); + + if ($reader === null) + return; + + $this->_interpolation = Transform::fromInt8($this->_data[0]); list ($this->_device, $this->_data) = preg_split("/\\x00/", substr($this->_data, 1), 2); for ($i = 0; $i < strlen($this->_data); $i += 8) - $this->_adjustments[Transform::fromInt16BE(substr($this->_data, $j, 2))] = - Transform::fromInt16BE(substr($this->_data, $j + 2, 2)); + $this->_adjustments + [Transform::fromInt16BE(substr($this->_data, $j, 2)) / 2] = + Transform::fromInt16BE(substr($this->_data, $j + 2, 2)) / 512; sort($this->_adjustments); } - + /** * Returns the interpolation method. The interpolation method describes which * method is preferred when an interpolation between the adjustment point that @@ -105,7 +109,19 @@ final class ID3_Frame_EQU2 extends ID3_Frame * @return integer */ public function getInterpolation() { return $this->_interpolation; } - + + /** + * Sets the interpolation method. The interpolation method describes which + * method is preferred when an interpolation between the adjustment point that + * follows. + * + * @param integer $interpolation The interpolation method code. + */ + public function setInterpolation($interpolation) + { + $this->_interpolation = $interpolation; + } + /** * Returns the device where the adjustments should apply. * @@ -114,21 +130,47 @@ final class ID3_Frame_EQU2 extends ID3_Frame public function getDevice() { return $this->_device; } /** - * Returns the array containing adjustments having fequencies as keys and + * Sets the device where the adjustments should apply. + * + * @param string $device The device. + */ + public function setDevice($device) { $this->_device = $device; } + + /** + * Returns the array containing adjustments having frequencies as keys and * their corresponding adjustments as values. * - * The frequency is stored in units of 1/2 Hz, giving it a range from 0 to - * 32767 Hz. - * - * The volume adjustment is encoded as a fixed point decibel value, 16 bit - * signed integer representing (adjustment*512), giving +/- 64 dB with a - * precision of 0.001953125 dB. E.g. +2 dB is stored as $04 00 and -2 dB is - * $FC 00. - * - * Adjustment points are ordered by frequency and one frequency is described - * once in the frame. + * Adjustment points are ordered by frequency. * * @return Array */ public function getAdjustments() { return $this->_adjustments; } + + /** + * Adds a volume adjustment setting for given frequency. The frequency can + * have a value from 0 to 32767 Hz, and the adjustment +/- 64 dB with a + * precision of 0.001953125 dB. + * + * @return Array + */ + public function addAdjustment($frequency, $adjustment) + { + $this->_adjustments[$frequency * 2] = $adjustment * 512; + sort($this->_adjustments); + } + + /** + * Sets the adjustments array. The array must have frequencies as keys and + * their corresponding adjustments as values. The frequency can have a value + * from 0 to 32767 Hz, and the adjustment +/- 64 dB with a precision of + * 0.001953125 dB. One frequency should only be described once in the frame. + * + * @param Array $adjustments The adjustments array. + */ + public function setAdjustments($adjustments) + { + foreach ($adjustments as $frequency => $adjustment) + $this->_adjustments[$frequency * 2] = $adjustment * 512; + sort($this->_adjustments); + } } diff --git a/src/ID3/Frame/ETCO.php b/src/ID3/Frame/ETCO.php index 982fd0f..2159d8c 100644 --- a/src/ID3/Frame/ETCO.php +++ b/src/ID3/Frame/ETCO.php @@ -85,7 +85,7 @@ final class ID3_Frame_ETCO extends ID3_Frame "One more byte of events follows"); /** @var integer */ - private $_format; + private $_format = 1; /** @var Array */ private $_events = array(); @@ -95,15 +95,17 @@ final class ID3_Frame_ETCO extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_format = ord($this->_data{0}); + if ($reader === null) + return; + + $this->_format = Transform::fromInt8($this->_data[0]); for ($i = 1; $i < $this->getSize(); $i += 5) { $this->_events[Transform::fromInt32BE(substr($this->_data, $i + 1, 4))] = - $data = $this->_data{$i}; + $data = Transform::fromInt8($this->_data[$i]); if ($data == 0xff) break; } @@ -116,12 +118,49 @@ final class ID3_Frame_ETCO extends ID3_Frame * @return integer */ public function getFormat() { return $this->_format; } - + + /** + * Sets the timing format. + * + * @see ID3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) { $this->_format = $format; } + /** * Returns the events as an associated array having the timestamps as keys and * the event types as values. * - * @return string + * @return Array */ public function getEvents() { return $this->_events; } + + /** + * Sets the events using given format. The value must be an associated array + * having the timestamps as keys and the event types as values. + * + * @param Array $events The events array. + * @param integer $format The timing format. + */ + public function setEvents($events, $format = false) + { + $this->_events = events; + if ($format !== false) + $this->_format = $format; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_format); + sort($this->_events); + foreach ($this->_events as $timestamp => $type) + $data .= Transform::toInt8($type) . Transform::toInt32BE($timestamp); + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/GEOB.php b/src/ID3/Frame/GEOB.php index 74c5a62..8be226e 100644 --- a/src/ID3/Frame/GEOB.php +++ b/src/ID3/Frame/GEOB.php @@ -55,7 +55,7 @@ final class ID3_Frame_GEOB extends ID3_Frame implements ID3_Encoding { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ private $_mimeType; @@ -66,16 +66,22 @@ final class ID3_Frame_GEOB extends ID3_Frame /** @var string */ private $_description; + /** @var string */ + private $_objectData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_encoding = ord($this->_data{0}); + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_mimeType = substr ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); $this->_data = substr($this->_data, $pos); @@ -107,32 +113,110 @@ final class ID3_Frame_GEOB extends ID3_Frame * @return integer */ public function getEncoding() { return $this->_encoding; } - + + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. * * @return string */ public function getMimeType() { return $this->_mimeType; } - + + /** + * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } + /** * Returns the file name. * * @return string */ public function getFilename() { return $this->_filename; } - + + /** + * Sets the file name using given encoding. The file name encoding must be + * that of the description text. + * + * @param string $description The file description text. + * @param integer $encoding The text encoding. + */ + public function setFilename($filename, $encoding = false) + { + $this->_filename = $filename; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the file description. * * @return string */ public function getDescription() { return $this->_description; } - + + /** + * Sets the file description text using given encoding. The description + * encoding must be that of the file name. + * + * @param string $description The file description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = false) + { + $this->_description = $description; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the embedded object binary data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_objectData; } + + /** + * Sets the embedded object binary data. + * + * @param string $objectData The object data. + */ + public function setData($objectData) { $this->_objectData = $objectData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_mimeType . "\0"; + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_filename) . "\0\0" . + Transform::toString16($this->_description) . "\0\0"; + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_filename) . "\0\0" . + Transform::toString16BE($this->_description) . "\0\0"; + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_filename) . "\0\0" . + Transform::toString16LE($this->_description) . "\0\0"; + break; + default: + $data .= $this->_filename . "\0" . $this->_description . "\0"; + } + $this->setData($data . $this->_objectData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/GRID.php b/src/ID3/Frame/GRID.php index 53bb985..60bbe7e 100644 --- a/src/ID3/Frame/GRID.php +++ b/src/ID3/Frame/GRID.php @@ -53,7 +53,7 @@ require_once("ID3/Frame.php"); * The group symbol contains a value that associates the frame with this group * throughout the whole tag, in the range $80-F0. All other values are reserved. * The group symbol may optionally be followed by some group specific data, e.g. - * a digital signature. There may be several "GRID" frames in a tag but only one + * a digital signature. There may be several GRID frames in a tag but only one * containing the same symbol and only one containing the same owner identifier. * The group symbol must be used somewhere in the tag. See * {@link ID3_Frame#GROUPING_IDENTITY} for more information. @@ -73,18 +73,24 @@ final class ID3_Frame_GRID extends ID3_Frame /** @var integer */ private $_group; + /** @var string */ + private $_groupData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); - $this->_group = substr($this->_data, 0, 1); - $this->_data = substr($this->_data, 1); + $this->_group = Transform::fromInt8($this->_data[0]); + $this->_groupData = substr($this->_data, 1); } /** @@ -94,6 +100,13 @@ final class ID3_Frame_GRID extends ID3_Frame */ public function getIdentifier() { return $this->_id; } + /** + * Sets the owner identifier string. + * + * @param string $id The owner identifier string. + */ + public function setIdentifier($id) { $this->_id = $id; } + /** * Returns the group symbol. * @@ -101,10 +114,37 @@ final class ID3_Frame_GRID extends ID3_Frame */ public function getGroup() { return $this->_group; } + /** + * Sets the group symbol. + * + * @param integer $group The group symbol. + */ + public function setGroup($group) { $this->_group = $group; } + /** * Returns the group dependent data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_groupData; } + + /** + * Sets the group dependent data. + * + * @param string $groupData The data. + */ + public function setData($groupData) { $this->_groupData = $groupData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + parent::setData + ($this->_id . "\0" . Transform::toInt8($this->_group) . + $this->_groupData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/LINK.php b/src/ID3/Frame/LINK.php index 2039e06..7ade550 100644 --- a/src/ID3/Frame/LINK.php +++ b/src/ID3/Frame/LINK.php @@ -91,17 +91,23 @@ final class ID3_Frame_LINK extends ID3_Frame /** @var string */ private $_url; + /** @var string */ + private $_qualifier; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; $this->_target = substr($this->_data, 0, 4); - list($this->_url, $this->_data) = + list($this->_url, $this->_qualifier) = preg_split("/\\x00/", substr($this->_data, 4), 2); } @@ -111,18 +117,55 @@ final class ID3_Frame_LINK extends ID3_Frame * @return string */ public function getTarget() { return $this->_target; } - + + /** + * Sets the target tag identifier. + * + * @param string $target The target tag identifier. + */ + public function setTarget($target) { $this->_target = $target; } + /** * Returns the target tag URL. * * @return string */ - public function getURL() { return $this->_url; } + public function getUrl() { return $this->_url; } /** - * Returns the additional ID data. + * Sets the target tag URL. + * + * @param string $url The target URL. + */ + public function setUrl($url) { $this->_url = $url; } + + /** + * Returns the additional data to identify further the tag. * * @return string */ - public function getData() { return $this->_data; } + public function getQualifier() { return $this->_qualifier; } + + /** + * Sets the additional data to be used in tag identification. + * + * @param string $identifier The qualifier. + */ + public function setQualifier($qualifier) + { + $this->_qualifier = $qualifier; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + (Transform::toString8(substr($this->_target, 0, 4), 4) . + $this->_url . "\0" . $this->_qualifier); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/MCDI.php b/src/ID3/Frame/MCDI.php index be2d4ee..6c496e5 100644 --- a/src/ID3/Frame/MCDI.php +++ b/src/ID3/Frame/MCDI.php @@ -68,4 +68,11 @@ final class ID3_Frame_MCDI extends ID3_Frame * @return string */ public function getData() { return $this->_data; } + + /** + * Sets the CD TOC binary dump. + * + * @param string $data The CD TOC binary dump string. + */ + public function setData($data) { parent::setData($data); } } diff --git a/src/ID3/Frame/MLLT.php b/src/ID3/Frame/MLLT.php index e245175..5c7ae4c 100644 --- a/src/ID3/Frame/MLLT.php +++ b/src/ID3/Frame/MLLT.php @@ -59,6 +59,7 @@ require_once("ID3/Frame.php"); * * There may only be one MLLT frame in each tag. * + * @todo Data parsing and write support * @package php-reader * @subpackage ID3 * @author Sven Vollbehr @@ -85,18 +86,21 @@ final class ID3_Frame_MLLT extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + throw new ID3_Exception("Write not supported yet"); $this->_frames = Transform::fromInt16BE(substr($this->_data, 0, 2)); $this->_bytes = Transform::fromInt32BE(substr($this->_data, 2, 3)); $this->_milliseconds = Transform::fromInt32BE(substr($this->_data, 5, 3)); - $byteDevBits = ord(substr($this->_data, 8, 1)); - $millisDevBits = ord(substr($this->_data, 9, 1)); + $byteDevBits = Transform::fromInt8($this->_data[8]); + $millisDevBits = Transform::fromInt8($this->_data[9]); - $this->_data = substr($this->_data, 10); // FIXME: Better parsing of data + // $data = substr($this->_data, 10); } /** @@ -106,20 +110,44 @@ final class ID3_Frame_MLLT extends ID3_Frame */ public function getFrames() { return $this->_frames; } + /** + * Sets the number of MPEG frames between reference. + * + * @param integer $frames The number of MPEG frames. + */ + public function setFrames($frames) { $this->_frames = $frames; } + /** * Returns the number of bytes between reference. * * @return integer */ public function getBytes() { return $this->_bytes; } - + + /** + * Sets the number of bytes between reference. + * + * @param integer $bytes The number of bytes. + */ + public function setBytes($bytes) { $this->_bytes = $bytes; } + /** * Returns the number of milliseconds between references. * * @return integer */ public function getMilliseconds() { return $this->_milliseconds; } - + + /** + * Sets the number of milliseconds between references. + * + * @param integer $milliseconds The number of milliseconds. + */ + public function setMilliseconds($milliseconds) + { + return $this->_milliseconds; + } + /** * Returns the deviations as an array. Each value is an array containing two * values, ie the deviation in bytes, and the deviation in milliseconds, @@ -128,4 +156,13 @@ final class ID3_Frame_MLLT extends ID3_Frame * @return Array */ public function getDeviation() { return $this->_deviation; } + + /** + * Sets the deviations array. The array must consist of arrays, each of which + * having two values, the deviation in bytes, and the deviation in + * milliseconds, respectively. + * + * @param Array $deviation The deviations array. + */ + public function setDeviation($deviation) { $this->_deviation = $deviation; } } diff --git a/src/ID3/Frame/OWNE.php b/src/ID3/Frame/OWNE.php index e010a0b..933be3f 100644 --- a/src/ID3/Frame/OWNE.php +++ b/src/ID3/Frame/OWNE.php @@ -58,10 +58,10 @@ final class ID3_Frame_OWNE extends ID3_Frame implements ID3_Encoding { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_currency; + private $_currency = "EUR"; /** @var string */ private $_price; @@ -77,12 +77,16 @@ final class ID3_Frame_OWNE extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_encoding = ord($this->_data{0}); - list($tmp, $this->_data) = preg_split("/\\x00/", substr($this->_data, 1), 2); + $this->_encoding = Transform::fromInt8($this->_data[0]); + list($tmp, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 1), 2); $this->_currency = substr($tmp, 0, 3); $this->_price = substr($tmp, 3); $this->_date = substr($this->_data, 0, 8); @@ -107,6 +111,14 @@ final class ID3_Frame_OWNE extends ID3_Frame */ public function getEncoding() { return $this->_encoding; } + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the currency used in transaction, encoded according to * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm @@ -116,6 +128,15 @@ final class ID3_Frame_OWNE extends ID3_Frame */ public function getCurrency() { return $this->_currency; } + /** + * Sets the currency used in transaction, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @param string $currency The currency code. + */ + public function setCurrency($currency) { $this->_currency = $currency; } + /** * Returns the price as a numerical string using "." as the decimal separator. * @@ -123,17 +144,74 @@ final class ID3_Frame_OWNE extends ID3_Frame */ public function getPrice() { return $this->_price; } + /** + * Sets the price. + * + * @param integer $price The price. + */ + public function setPrice($price) + { + $this->_price = number_format($price, 2, ".", ""); + } + /** * Returns the date of purchase as an 8 character date string (YYYYMMDD). * * @return string */ - public function getDate() { return $this->_price; } - + public function getDate() { return $this->_date; } + + /** + * Sets the date of purchase. The date must be an 8 character date string + * (YYYYMMDD). + * + * @param string $date The date string. + */ + public function setDate($date) { $this->_date = $date; } + /** * Returns the name of the seller. * * @return string */ public function getSeller() { return $this->_seller; } + + /** + * Sets the name of the seller using given encoding. + * + * @param string $seller The name of the seller. + * @param integer $encoding The text encoding. + */ + public function setSeller($seller, $encoding = false) + { + $this->_seller = $seller; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_currency . + $this->_price . "\0" . $this->_date; + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_seller); + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_seller); + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_seller); + break; + default: + $data .= $this->_seller; + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/PCNT.php b/src/ID3/Frame/PCNT.php index 0e30c4b..3f3e35f 100644 --- a/src/ID3/Frame/PCNT.php +++ b/src/ID3/Frame/PCNT.php @@ -54,31 +54,56 @@ require_once("ID3/Frame.php"); final class ID3_Frame_PCNT extends ID3_Frame { /** @var integer */ - private $_counter; + private $_counter = 0; /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - switch (strlen($this->_data)) { - case 8: + if (strlen($this->_data) > 4) $this->_counter = Transform::fromInt64BE($this->_data); - break; - case 4: - $this->_counter = Transform::fromInt32BE($this->_data); - break; - } + else + $this->_counter = Transform::fromUInt32BE($this->_data); } - + /** * Returns the counter. * * @return integer */ public function getCounter() { return $this->_counter; } + + /** + * Adds counter by one. + */ + public function addCounter() { $this->_counter++; } + + /** + * Sets the counter value. + * + * @param integer $counter The counter value. + */ + public function setCounter($counter) { $this->_counter = $counter; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + ($this->_counter > 4294967295 ? + Transform::toInt64BE($this->_counter) : + Transform::toInt32BE($this->_counter)); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/POPM.php b/src/ID3/Frame/POPM.php index c1bb149..5133aea 100644 --- a/src/ID3/Frame/POPM.php +++ b/src/ID3/Frame/POPM.php @@ -68,42 +68,47 @@ final class ID3_Frame_POPM extends ID3_Frame private $_id; /** @var integer */ - private $_rating; + private $_rating = 0; /** @var integer */ - private $_counter; + private $_counter = 0; /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); - $this->_rating = substr($this->_data, 0, 1); + $this->_rating = Transform::fromInt8($this->_data[0]); $this->_data = substr($this->_data, 1); - switch (strlen($this->_data)) { - case 8: + if (strlen($this->_data) > 4) $this->_counter = Transform::fromInt64BE($this->_data); - break; - case 4: - $this->_counter = Transform::fromInt32BE($this->_data); - break; - } + else if (strlen($this->_data) > 0) + $this->_counter = Transform::fromUInt32BE($this->_data); } - + /** * Returns the user identifier string. * * @return string */ public function getIdentifier() { return $this->_id; } - - + + /** + * Sets the user identifier string. + * + * @param string $id The user identifier string. + */ + public function setIdentifier($id) { return $this->_id = $id; } + /** * Returns the user rating. * @@ -111,10 +116,44 @@ final class ID3_Frame_POPM extends ID3_Frame */ public function getRating() { return $this->_rating; } + /** + * Sets the user rating. + * + * @param integer $rating The user rating. + */ + public function setRating($rating) { $this->_rating = $rating; } + /** * Returns the counter. * * @return integer */ public function getCounter() { return $this->_counter; } + + /** + * Adds counter by one. + */ + public function addCounter() { $this->_counter++; } + + /** + * Sets the counter value. + * + * @param integer $counter The counter value. + */ + public function setCounter($counter) { $this->_counter = $counter; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + ($this->_id . "\0" . Transform::toInt8($this->_rating) . + ($this->_counter > 4294967295 ? + Transform::toInt64BE($this->_counter) : + ($this->_counter > 0 ? Transform::toInt32BE($this->_counter) : 0))); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/POSS.php b/src/ID3/Frame/POSS.php index d2770ed..3d7795d 100644 --- a/src/ID3/Frame/POSS.php +++ b/src/ID3/Frame/POSS.php @@ -57,7 +57,7 @@ final class ID3_Frame_POSS extends ID3_Frame implements ID3_Timing { /** @var integer */ - private $_format; + private $_format = 1; /** @var string */ private $_position; @@ -67,12 +67,15 @@ final class ID3_Frame_POSS extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_format = ord($this->_data{0}); - $this->_position = Transform::fromInt32BE(substr($this->_data, 1, 4)); + $this->_format = Transform::fromInt8($this->_data[0]); + $this->_position = Transform::fromUInt32BE(substr($this->_data, 1, 4)); } /** @@ -82,6 +85,14 @@ final class ID3_Frame_POSS extends ID3_Frame */ public function getFormat() { return $this->_format; } + /** + * Sets the timing format. + * + * @see ID3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) { $this->_format = $format; } + /** * Returns the position where in the audio the listener starts to receive, * i.e. the beginning of the next frame. @@ -89,4 +100,31 @@ final class ID3_Frame_POSS extends ID3_Frame * @return integer */ public function getPosition() { return $this->_position; } + + /** + * Sets the position where in the audio the listener starts to receive, + * i.e. the beginning of the next frame, using given format. + * + * @param integer $position The position. + * @param integer $format The timing format. + */ + public function setPosition($position, $format = false) + { + $this->_position = $position; + if ($format !== false) + $this->_format = $format; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + (Transform::toInt8($this->_format) . + Transform::toUInt32($this->_position)); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/PRIV.php b/src/ID3/Frame/PRIV.php index 617ad94..e056331 100644 --- a/src/ID3/Frame/PRIV.php +++ b/src/ID3/Frame/PRIV.php @@ -61,29 +61,61 @@ final class ID3_Frame_PRIV extends ID3_Frame /** @var string */ private $_id; + /** @var string */ + private $_privateData; + /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + + if ($reader === null) + return; + + list($this->_id, $this->_privateData) = + preg_split("/\\x00/", $this->_data, 2); } - + /** * Returns the owner identifier string. * * @return string */ public function getIdentifier() { return $this->_id; } - + + /** + * Sets the owner identifier string. + * + * @param string $id The owner identifier string. + */ + public function setIdentifier($id) { $this->_id = $id; } + /** * Returns the private binary data associated with the frame. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_privateData; } + + /** + * Sets the private binary data associated with the frame. + * + * @param string $privateData The private binary data string. + */ + public function setData($privateData) { $this->_privateData = $privateData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + parent::setData($this->_id . "\0" . $this->_privateData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/RBUF.php b/src/ID3/Frame/RBUF.php index c020763..fbe26f1 100644 --- a/src/ID3/Frame/RBUF.php +++ b/src/ID3/Frame/RBUF.php @@ -60,7 +60,7 @@ require_once("ID3/Frame.php"); * is connected to a arbitrary point in the stream, such as radio or multicast, * then the recommended buffer size frame should be included in every tag. * - * The buffer size should be kept to a minimum. There may only be one "RBUF" + * The buffer size should be kept to a minimum. There may only be one RBUF * frame in each tag. * * @package php-reader @@ -92,22 +92,32 @@ final class ID3_Frame_RBUF extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; $this->_size = Transform::fromInt32BE(substr($this->_data, 0, 3)); - $this->_flags = substr($this->_data, 3, 1); + $this->_flags = Transform::fromInt8($this->_data[3]); $this->_offset = Transform::fromInt32BE(substr($this->_data, 4, 4)); } - + /** * Returns the buffer size. * * @return integer */ public function getSize() { return $this->_size; } - + + /** + * Sets the buffer size. + * + * @param integer $size The buffer size. + */ + public function setSize($size) { $this->_size = $size; } + /** * Checks whether or not the flag is set. Returns true if the flag * is set, false otherwise. @@ -117,10 +127,44 @@ final class ID3_Frame_RBUF extends ID3_Frame */ public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } + /** + * Returns the flags byte. + * + * @return integer + */ + public function getFlags($flags) { return $this->_flags; } + + /** + * Sets the flags byte. + * + * @param string $flags The flags byte. + */ + public function setFlags($flags) { $this->_flags = $flags; } + /** * Returns the offset to next tag. * * @return integer */ - public function getOffset() { return $this->_size; } + public function getOffset() { return $this->_offset; } + + /** + * Sets the offset to next tag. + * + * @param integer $offset The offset. + */ + public function setOffset($offset) { $this->_offset = $offset; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + (substr(Transform::toInt32BE($this->_size) << 8, 0, 3) . + Transform::toInt8($this->_flags) . Transform::toInt32BE($this->_offset)); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/RVA2.php b/src/ID3/Frame/RVA2.php index 5904975..c0ba3ff 100644 --- a/src/ID3/Frame/RVA2.php +++ b/src/ID3/Frame/RVA2.php @@ -70,15 +70,8 @@ final class ID3_Frame_RVA2 extends ID3_Frame * @var Array */ public static $types = array - (0x00 => "Other", - 0x01 => "Master volume", - 0x02 => "Front right", - 0x03 => "Front left", - 0x04 => "Back right", - 0x05 => "Back left", - 0x06 => "Front centre", - 0x07 => "Back centre", - 0x08 => "Subwoofer"); + ("Other", "Master volume", "Front right", "Front left", "Back right", + "Back left", "Front centre", "Back centre", "Subwoofer"); /** @var string */ private $_device; @@ -91,33 +84,44 @@ final class ID3_Frame_RVA2 extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - + + if ($reader === null) + return; + list ($this->_device, $this->_data) = preg_split("/\\x00/", $this->_data, 2); for ($i = $j = 0; $i < 9; $i++) { $this->_adjustments[$i] = array - ("channelType" => substr($this->_data, $j++, 1), + ("channelType" => Transform::fromInt8($this->_data[$j++]), "volumeAdjustment" => Transform::fromInt16BE(substr($this->_data, $j++, 2))); - $bitsInPeak = ord(substr($this->_data, (++$j)++, 1)); + $bitsInPeak = Transform::fromInt8($this->_data[(++$j)++]); $bytesInPeak = $bitsInPeak > 0 ? ceil($bitsInPeak / 8) : 0; switch ($bytesInPeak) { - case 32: - case 24: - $this->_adjustments[$i]["peakVolume"] = - Transform::fromInt32BE(substr($this->_data, $j, $bytesInPeak)); - $j += $bytesInPeak; - break; - case 16: - $this->_adjustments[$i]["peakVolume"] = - Transform::fromInt16BE(substr($this->_data, $j, $bytesInPeak)); - $j += $bytesInPeak; - break; case 8: + case 7: + case 6: + case 5: + $this->_adjustments[$i]["peakVolume"] = + Transform::fromInt64BE(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + break; + case 4: + case 3: + $this->_adjustments[$i]["peakVolume"] = + Transform::fromUInt32BE(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + break; + case 2: + $this->_adjustments[$i]["peakVolume"] = + Transform::fromUInt16BE(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + break; + case 1: $this->_adjustments[$i]["peakVolume"] = Transform::fromInt8(substr($this->_data, $j, $bytesInPeak)); $j += $bytesInPeak; @@ -132,6 +136,13 @@ final class ID3_Frame_RVA2 extends ID3_Frame */ public function getDevice() { return $this->_device; } + /** + * Sets the device where the adjustments should apply. + * + * @param string $device The device. + */ + public function setDevice($device) { $this->_device = $device; } + /** * Returns the array containing volume adjustments for each channel. Volume * adjustments are arrays themselves containing the following keys: @@ -140,4 +151,44 @@ final class ID3_Frame_RVA2 extends ID3_Frame * @return Array */ public function getAdjustments() { return $this->_adjustments; } + + /** + * Sets the array of volume adjustments for each channel. Each volume + * adjustment is an array too containing the following keys: channelType, + * volumeAdjustment, peakVolume. + * + * @param Array $adjustments The volume adjustments array. + */ + public function setAdjustments($adjustments) + { + $this->_adjustments = $adjustments; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = $this->_device . "\0"; + foreach ($this->_adjustments as $channel) { + $data .= Transform::toInt8($channel["channelType"]) . + Transform::toInt16BE($channel["volumeAdjustment"]); + if ($channel["peakVolume"] < 255) + $data .= Transform::toInt8(8) . + Transform::toInt8($channel["peakVolume"]); + else if ($channel["peakVolume"] < 65535) + $data .= Transform::toInt8(16) . + Transform::toUInt16BE($channel["peakVolume"]); + else if ($channel["peakVolume"] < 4294967295) + $data .= Transform::toInt8(32) . + Transform::toUInt32BE($channel["peakVolume"]); + else + $data .= Transform::toInt8(64) . + Transform::toUInt64BE($channel["peakVolume"]); + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/RVRB.php b/src/ID3/Frame/RVRB.php index b3cba72..74cc233 100644 --- a/src/ID3/Frame/RVRB.php +++ b/src/ID3/Frame/RVRB.php @@ -100,20 +100,23 @@ final class ID3_Frame_RVRB extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_reverbLeft = substr($this->_data, 0, 2); - $this->_reverbRight = substr($this->_data, 2, 2); - $this->_reverbBouncesLeft = substr($this->_data, 4, 1); - $this->_reverbBouncesRight = substr($this->_data, 5, 1); - $this->_reverbFeedbackLtoL = substr($this->_data, 6, 1); - $this->_reverbFeedbackLtoR = substr($this->_data, 7, 1); - $this->_reverbFeedbackRtoR = substr($this->_data, 8, 1); - $this->_reverbFeedbackRtoL = substr($this->_data, 9, 1); - $this->_premixLtoR = substr($this->_data, 10, 1); - $this->_premixRtoL = substr($this->_data, 11, 1); + $this->_reverbLeft = Transform::fromInt16BE(substr($this->_data, 0, 2)); + $this->_reverbRight = Transform::fromInt16BE(substr($this->_data, 2, 2)); + $this->_reverbBouncesLeft = Transform::fromInt8($this->_data[4]); + $this->_reverbBouncesRight = Transform::fromInt8($this->_data[5]); + $this->_reverbFeedbackLtoL = Transform::fromInt8($this->_data[6]); + $this->_reverbFeedbackLtoR = Transform::fromInt8($this->_data[7]); + $this->_reverbFeedbackRtoR = Transform::fromInt8($this->_data[8]); + $this->_reverbFeedbackRtoL = Transform::fromInt8($this->_data[9]); + $this->_premixLtoR = Transform::fromInt8($this->_data[10]); + $this->_premixRtoL = Transform::fromInt8($this->_data[11]); } /** @@ -122,85 +125,188 @@ final class ID3_Frame_RVRB extends ID3_Frame * @return integer */ public function getReverbLeft() { return $this->_reverbLeft; } - + + /** + * Sets the left reverb. + * + * @param integer $reverbLeft The left reverb. + */ + public function setReverbLeft($reverbLeft) + { + return $this->_reverbLeft = $reverbLeft; + } + /** * Returns the right reverb. * * @return integer */ public function getReverbRight() { return $this->_reverbRight; } - + + /** + * Sets the right reverb. + * + * @param integer $reverbRight The right reverb. + */ + public function setReverbRight($reverbRight) + { + return $this->_reverbRight = $reverbRight; + } + /** * Returns the left reverb bounces. * * @return integer */ public function getReverbBouncesLeft() { return $this->_reverbBouncesLeft; } - + + /** + * Sets the left reverb bounces. + * + * @param integer $reverbBouncesLeft The left reverb bounces. + */ + public function setReverbBouncesLeft($reverbBouncesLeft) + { + $this->_reverbBouncesLeft = $reverbBouncesLeft; + } + /** * Returns the right reverb bounces. * * @return integer */ public function getReverbBouncesRight() { return $this->_reverbBouncesRight; } - + + /** + * Sets the right reverb bounces. + * + * @param integer $reverbBouncesRight The right reverb bounces. + */ + public function setReverbBouncesRight($reverbBouncesRight) + { + $this->_reverbBouncesRight = $reverbBouncesRight; + } + /** * Returns the left-to-left reverb feedback. * * @return integer */ - public function getReverbFeedbackLtoL() + public function getReverbFeedbackLtoL() { return $this->_reverbFeedbackLtoL; } + + /** + * Sets the left-to-left reverb feedback. + * + * @param integer $reverbFeedbackLtoL The left-to-left reverb feedback. + */ + public function setReverbFeedbackLtoL($reverbFeedbackLtoL) { - return $this->_reverbFeedbackLtoL; + $this->_reverbFeedbackLtoL = $reverbFeedbackLtoL; } - + /** * Returns the left-to-right reverb feedback. * * @return integer */ - public function getReverbFeedbackLtoR() + public function getReverbFeedbackLtoR() { return $this->_reverbFeedbackLtoR; } + + /** + * Sets the left-to-right reverb feedback. + * + * @param integer $reverbFeedbackLtoR The left-to-right reverb feedback. + */ + public function setReverbFeedbackLtoR($reverbFeedbackLtoR) { - return $this->_reverbFeedbackLtoR; + $this->_reverbFeedbackLtoR = $reverbFeedbackLtoR; } - + /** * Returns the right-to-right reverb feedback. * * @return integer */ - public function getReverbFeedbackRtoR() + public function getReverbFeedbackRtoR() { return $this->_reverbFeedbackRtoR; } + + /** + * Sets the right-to-right reverb feedback. + * + * @param integer $reverbFeedbackRtoR The right-to-right reverb feedback. + */ + public function setReverbFeedbackRtoR($reverbFeedbackRtoR) { - return $this->_reverbFeedbackRtoR; + $this->_reverbFeedbackRtoR = $reverbFeedbackRtoR; } - + /** * Returns the right-to-left reverb feedback. * * @return integer */ - public function getReverbFeedbackRtoL() + public function getReverbFeedbackRtoL() { return $this->_reverbFeedbackRtoL; } + + /** + * Sets the right-to-left reverb feedback. + * + * @param integer $reverbFeedbackRtoL The right-to-left reverb feedback. + */ + public function setReverbFeedbackRtoL($reverbFeedbackRtoL) { - return $this->_reverbFeedbackRtoL; + $this->_reverbFeedbackRtoL = $reverbFeedbackRtoL; } - + /** * Returns the left-to-right premix. * * @return integer */ - public function getPremixLtoR() + public function getPremixLtoR() { return $this->_premixLtoR; } + + /** + * Sets the left-to-right premix. + * + * @param integer $premixLtoR The left-to-right premix. + */ + public function setPremixLtoR($premixLtoR) { - return $this->_premixLtoR; + $this->_premixLtoR = $premixLtoR; } - + /** * Returns the right-to-left premix. * * @return integer */ - public function getPremixRtoL() + public function getPremixRtoL() { return $this->_premixRtoL; } + + /** + * Sets the right-to-left premix. + * + * @param integer $premixRtoL The right-to-left premix. + */ + public function setPremixRtoL($premixRtoL) { - return $this->_premixRtoL; + $this->_premixRtoL = $premixRtoL; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData + (Transform::toInt16BE($this->_reverbLeft) . + Transform::toInt16BE($this->_reverbRight) . + Transform::toInt8($this->_reverbBouncesLeft) . + Transform::toInt8($this->_reverbBouncesRight) . + Transform::toInt8($this->_reverbFeedbackLtoL) . + Transform::toInt8($this->_reverbFeedbackLtoR) . + Transform::toInt8($this->_reverbFeedbackRtoR) . + Transform::toInt8($this->_reverbFeedbackRtoL) . + Transform::toInt8($this->_premixLtoR) . + Transform::toInt8($this->_premixRtoL)); + return parent::__toString(); } } diff --git a/src/ID3/Frame/SEEK.php b/src/ID3/Frame/SEEK.php index 5e9be27..bf987c9 100644 --- a/src/ID3/Frame/SEEK.php +++ b/src/ID3/Frame/SEEK.php @@ -63,17 +63,41 @@ final class ID3_Frame_SEEK extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; $this->_minOffset = Transform::fromInt32BE($this->_data); } - + /** * Returns the minimum offset to next tag in bytes. * * @return integer */ public function getMinimumOffset() { return $this->_minOffset; } + + /** + * Sets the minimum offset to next tag in bytes. + * + * @param integer $minOffset The minimum offset. + */ + public function setMinimumOffset($minOffset) + { + $this->_minOffset = $minOffset; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData(Transform::toInt32BE($this->_minOffset)); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/SIGN.php b/src/ID3/Frame/SIGN.php index bdef371..d37fc82 100644 --- a/src/ID3/Frame/SIGN.php +++ b/src/ID3/Frame/SIGN.php @@ -68,25 +68,53 @@ final class ID3_Frame_SIGN extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; $this->_group = substr($this->_data, 0, 1); $this->_signature = substr($this->_data, 1); } - + /** - * Returns the group symbol. + * Returns the group symbol byte. * * @return integer */ public function getGroup() { return $this->_group; } - + + /** + * Sets the group symbol byte. + * + * @param integer $group The group symbol byte. + */ + public function setGroup($group) { $this->_group = $group; } + /** * Returns the signature binary data. * * @return string */ public function getSignature() { return $this->_signature; } + + /** + * Sets the signature binary data. + * + * @param string $signature The signature binary data string. + */ + public function setSignature($signature) { $this->_signature = $signature; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $this->setData(Transform::toInt8($this->_group) . $this->_signature); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/SYLT.php b/src/ID3/Frame/SYLT.php index 2f9f0c7..ae6efd5 100644 --- a/src/ID3/Frame/SYLT.php +++ b/src/ID3/Frame/SYLT.php @@ -51,6 +51,7 @@ require_once("ID3/Timing.php"); * There may be more than one SYLT frame in each tag, but only one with the * same language and content descriptor. * + * @todo The data could be parsed further; data samples needed * @package php-reader * @subpackage ID3 * @author Sven Vollbehr @@ -71,36 +72,39 @@ final class ID3_Frame_SYLT extends ID3_Frame "Chord", "Trivia", "URLs to webpages", "URLs to images"); /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_language; + private $_language = "eng"; /** @var integer */ - private $_format; + private $_format = 1; /** @var integer */ - private $_type; + private $_type = 0; /** @var string */ private $_description; /** @var Array */ - private $_text = array(); + private $_text; /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_encoding = ord($this->_data{0}); + + if ($reader === null) + return; + + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_language = substr($this->_data, 1, 3); - $this->_format = ord($this->_data{3}); - $this->_type = ord($this->_data{4}); + $this->_format = Transform::fromInt8($this->_data[3]); + $this->_type = Transform::fromInt8($this->_data[4]); $this->_data = substr($this->_data, 5); switch ($this->_encoding) { @@ -129,6 +133,14 @@ final class ID3_Frame_SYLT extends ID3_Frame * @return integer */ public function getEncoding() { return $this->_encoding; } + + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } /** * Returns the language code as specified in the @@ -138,32 +150,120 @@ final class ID3_Frame_SYLT extends ID3_Frame * @return string */ public function getLanguage() { return $this->_language; } - + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language + * @param string $language The language code. + */ + public function setLanguage($language) { $this->_language = $language; } + /** * Returns the timing format. * * @return integer */ public function getFormat() { return $this->_format; } - + + /** + * Sets the timing format. + * + * @see ID3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) { $this->_format = $format; } + /** * Returns the content type code. * * @return integer */ public function getType() { return $this->_type; } - + + /** + * Sets the content type code. + * + * @param integer $type The content type code. + */ + public function setType($type) { $this->_type = $type; } + /** * Returns the content description. * * @return string */ public function getDescription() { return $this->_description; } - + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $language = false, + $encoding = false) + { + $this->_description = $description; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the texts with their timestamps. * * @return Array */ public function getText() { return $this->_text; } + + /** + * Sets the text using given encoding. The text language and encoding must be + * that of the description text. + * + * @param mixed $text The test string. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setText($text, $language = false, $encoding = false) + { + $this->_text = $text; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_language . + Transform::toInt8($this->_format) . Transform::toInt8($this->_type); + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_description) . "\0\0" . + Transform::toString16($this->_text); + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_description) . "\0\0" . + Transform::toString16BE($this->_text); + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_description) . "\0\0" . + Transform::toString16LE($this->_text); + break; + default: + $data .= $this->_description . "\0" . $this->_text; + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/SYTC.php b/src/ID3/Frame/SYTC.php index e489df1..eef0ee4 100644 --- a/src/ID3/Frame/SYTC.php +++ b/src/ID3/Frame/SYTC.php @@ -56,8 +56,9 @@ require_once("ID3/Timing.php"); * music changes, a tempo descriptor may indicate this for the player. All tempo * descriptors must be sorted in chronological order. The first beat-stroke in * a time-period is at the same time as the beat description occurs. There may - * only be one "SYTC" frame in each tag. + * only be one SYTC frame in each tag. * + * @todo The data could be parsed further; data samples needed * @package php-reader * @subpackage ID3 * @author Sven Vollbehr @@ -69,19 +70,25 @@ final class ID3_Frame_SYTC extends ID3_Frame implements ID3_Timing { /** @var integer */ - private $_format; + private $_format = 1; + + /** @var string */ + private $_tempoData; /** * Constructs the class with given parameters and parses object related data. * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); + + if ($reader === null) + return; - $this->_format = ord($this->_data{0}); - $this->_data = substr($this->_data, 1); // FIXME: Better parsing of data + $this->_format = Transform::fromInt8($this->_data[0]); + $this->_tempoData = substr($this->_data, 1); // FIXME: Better parsing of data } /** @@ -91,10 +98,36 @@ final class ID3_Frame_SYTC extends ID3_Frame */ public function getFormat() { return $this->_format; } + /** + * Sets the timing format. + * + * @see ID3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) { $this->_format = $format; } + /** * Returns the tempo data. * * @return string */ - public function getData() { return $this->_data; } + public function getData() { return $this->_tempoData; } + + /** + * Sets the tempo data. + * + * @param string $data The data string. + */ + public function setData($tempoData) { $this->_tempoData = $tempoData; } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + parent::setData(Transform::toInt8($this->_format) . $this->_tempoData); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/TALB.php b/src/ID3/Frame/TALB.php index 74d8a67..8a7492b 100644 --- a/src/ID3/Frame/TALB.php +++ b/src/ID3/Frame/TALB.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TBPM.php b/src/ID3/Frame/TBPM.php index e679e8e..442b680 100644 --- a/src/ID3/Frame/TBPM.php +++ b/src/ID3/Frame/TBPM.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TCOM.php b/src/ID3/Frame/TCOM.php index eb6de22..c7f73ad 100644 --- a/src/ID3/Frame/TCOM.php +++ b/src/ID3/Frame/TCOM.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TCON.php b/src/ID3/Frame/TCON.php index 858fc9f..28826e3 100644 --- a/src/ID3/Frame/TCON.php +++ b/src/ID3/Frame/TCON.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TCOP.php b/src/ID3/Frame/TCOP.php index 882eab4..a389935 100644 --- a/src/ID3/Frame/TCOP.php +++ b/src/ID3/Frame/TCOP.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDEN.php b/src/ID3/Frame/TDEN.php index 2499d7d..4b21494 100644 --- a/src/ID3/Frame/TDEN.php +++ b/src/ID3/Frame/TDEN.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDLY.php b/src/ID3/Frame/TDLY.php index 4f192e7..df52531 100644 --- a/src/ID3/Frame/TDLY.php +++ b/src/ID3/Frame/TDLY.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDOR.php b/src/ID3/Frame/TDOR.php index 39ae270..7e5a3e1 100644 --- a/src/ID3/Frame/TDOR.php +++ b/src/ID3/Frame/TDOR.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDRC.php b/src/ID3/Frame/TDRC.php index c727586..5d761e3 100644 --- a/src/ID3/Frame/TDRC.php +++ b/src/ID3/Frame/TDRC.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDRL.php b/src/ID3/Frame/TDRL.php index eec36db..454490f 100644 --- a/src/ID3/Frame/TDRL.php +++ b/src/ID3/Frame/TDRL.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TDTG.php b/src/ID3/Frame/TDTG.php index bf418de..17525fb 100644 --- a/src/ID3/Frame/TDTG.php +++ b/src/ID3/Frame/TDTG.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TENC.php b/src/ID3/Frame/TENC.php index c6759a5..d3cbf27 100644 --- a/src/ID3/Frame/TENC.php +++ b/src/ID3/Frame/TENC.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TEXT.php b/src/ID3/Frame/TEXT.php index c943288..bf632ab 100644 --- a/src/ID3/Frame/TEXT.php +++ b/src/ID3/Frame/TEXT.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TFLT.php b/src/ID3/Frame/TFLT.php index ee0b9b7..f1e9a01 100644 --- a/src/ID3/Frame/TFLT.php +++ b/src/ID3/Frame/TFLT.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TIPL.php b/src/ID3/Frame/TIPL.php index 9c41952..dfcadde 100644 --- a/src/ID3/Frame/TIPL.php +++ b/src/ID3/Frame/TIPL.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TIT1.php b/src/ID3/Frame/TIT1.php index 40d0f8c..2f29e77 100644 --- a/src/ID3/Frame/TIT1.php +++ b/src/ID3/Frame/TIT1.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TIT2.php b/src/ID3/Frame/TIT2.php index 8bcc6fc..384de2d 100644 --- a/src/ID3/Frame/TIT2.php +++ b/src/ID3/Frame/TIT2.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TIT3.php b/src/ID3/Frame/TIT3.php index fd5e789..c593da2 100644 --- a/src/ID3/Frame/TIT3.php +++ b/src/ID3/Frame/TIT3.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TKEY.php b/src/ID3/Frame/TKEY.php index 6687c49..dd8d6c4 100644 --- a/src/ID3/Frame/TKEY.php +++ b/src/ID3/Frame/TKEY.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TLAN.php b/src/ID3/Frame/TLAN.php index 5a973fe..14fd104 100644 --- a/src/ID3/Frame/TLAN.php +++ b/src/ID3/Frame/TLAN.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TLEN.php b/src/ID3/Frame/TLEN.php index 652cc9d..faf81c1 100644 --- a/src/ID3/Frame/TLEN.php +++ b/src/ID3/Frame/TLEN.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TMCL.php b/src/ID3/Frame/TMCL.php index 0051618..ca75f48 100644 --- a/src/ID3/Frame/TMCL.php +++ b/src/ID3/Frame/TMCL.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TMED.php b/src/ID3/Frame/TMED.php index 5e1ad0c..d4db37f 100644 --- a/src/ID3/Frame/TMED.php +++ b/src/ID3/Frame/TMED.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TMOO.php b/src/ID3/Frame/TMOO.php index cde8358..72059e6 100644 --- a/src/ID3/Frame/TMOO.php +++ b/src/ID3/Frame/TMOO.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TOAL.php b/src/ID3/Frame/TOAL.php index 1827147..144e09f 100644 --- a/src/ID3/Frame/TOAL.php +++ b/src/ID3/Frame/TOAL.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TOFN.php b/src/ID3/Frame/TOFN.php index 8db2f6f..572a59d 100644 --- a/src/ID3/Frame/TOFN.php +++ b/src/ID3/Frame/TOFN.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TOLY.php b/src/ID3/Frame/TOLY.php index 9d76203..a4d0eff 100644 --- a/src/ID3/Frame/TOLY.php +++ b/src/ID3/Frame/TOLY.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TOPE.php b/src/ID3/Frame/TOPE.php index 6e4b895..b3d4fe6 100644 --- a/src/ID3/Frame/TOPE.php +++ b/src/ID3/Frame/TOPE.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TOWN.php b/src/ID3/Frame/TOWN.php index 7f206e4..072f4b9 100644 --- a/src/ID3/Frame/TOWN.php +++ b/src/ID3/Frame/TOWN.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPE1.php b/src/ID3/Frame/TPE1.php index 2cb5c1a..bd82147 100644 --- a/src/ID3/Frame/TPE1.php +++ b/src/ID3/Frame/TPE1.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPE2.php b/src/ID3/Frame/TPE2.php index 0c8af67..0104db9 100644 --- a/src/ID3/Frame/TPE2.php +++ b/src/ID3/Frame/TPE2.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPE3.php b/src/ID3/Frame/TPE3.php index 2b43763..a1d172c 100644 --- a/src/ID3/Frame/TPE3.php +++ b/src/ID3/Frame/TPE3.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPE4.php b/src/ID3/Frame/TPE4.php index 5432893..6977164 100644 --- a/src/ID3/Frame/TPE4.php +++ b/src/ID3/Frame/TPE4.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPOS.php b/src/ID3/Frame/TPOS.php index b917583..5fd1458 100644 --- a/src/ID3/Frame/TPOS.php +++ b/src/ID3/Frame/TPOS.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPRO.php b/src/ID3/Frame/TPRO.php index 9a0b3ef..f4073f1 100644 --- a/src/ID3/Frame/TPRO.php +++ b/src/ID3/Frame/TPRO.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TPUB.php b/src/ID3/Frame/TPUB.php index 99bfe26..b54efdb 100644 --- a/src/ID3/Frame/TPUB.php +++ b/src/ID3/Frame/TPUB.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TRCK.php b/src/ID3/Frame/TRCK.php index e5079ef..bffc7c6 100644 --- a/src/ID3/Frame/TRCK.php +++ b/src/ID3/Frame/TRCK.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TRSN.php b/src/ID3/Frame/TRSN.php index 774f225..e12c048 100644 --- a/src/ID3/Frame/TRSN.php +++ b/src/ID3/Frame/TRSN.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TRSO.php b/src/ID3/Frame/TRSO.php index a60e8ae..7d5a164 100644 --- a/src/ID3/Frame/TRSO.php +++ b/src/ID3/Frame/TRSO.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSOA.php b/src/ID3/Frame/TSOA.php index c2472d4..5e6942a 100644 --- a/src/ID3/Frame/TSOA.php +++ b/src/ID3/Frame/TSOA.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSOP.php b/src/ID3/Frame/TSOP.php index 9a24310..04f3523 100644 --- a/src/ID3/Frame/TSOP.php +++ b/src/ID3/Frame/TSOP.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSOT.php b/src/ID3/Frame/TSOT.php index c435ef9..0fb1e82 100644 --- a/src/ID3/Frame/TSOT.php +++ b/src/ID3/Frame/TSOT.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSRC.php b/src/ID3/Frame/TSRC.php index 48c9f36..93f604a 100644 --- a/src/ID3/Frame/TSRC.php +++ b/src/ID3/Frame/TSRC.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSSE.php b/src/ID3/Frame/TSSE.php index 568118f..9c1122b 100644 --- a/src/ID3/Frame/TSSE.php +++ b/src/ID3/Frame/TSSE.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TSST.php b/src/ID3/Frame/TSST.php index 083242f..c997ace 100644 --- a/src/ID3/Frame/TSST.php +++ b/src/ID3/Frame/TSST.php @@ -37,7 +37,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/TXXX.php b/src/ID3/Frame/TXXX.php index e107e74..5658b41 100644 --- a/src/ID3/Frame/TXXX.php +++ b/src/ID3/Frame/TXXX.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractText.php"); +require_once("ID3/Frame/AbstractText.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/USER.php b/src/ID3/Frame/USER.php index 3e8160c..596eb4e 100644 --- a/src/ID3/Frame/USER.php +++ b/src/ID3/Frame/USER.php @@ -59,10 +59,10 @@ final class ID3_Frame_USER extends ID3_Frame implements ID3_Encoding, ID3_Language { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_language; + private $_language = "eng"; /** @var string */ private $_text; @@ -72,11 +72,14 @@ final class ID3_Frame_USER extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_encoding = ord($this->_data{0}); + + if ($reader === null) + return; + + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_language = substr($this->_data, 1, 3); $this->_data = substr($this->_data, 4); @@ -91,7 +94,7 @@ final class ID3_Frame_USER extends ID3_Frame $this->_text = Transform::fromString8($this->_data); } } - + /** * Returns the text encoding. * @@ -99,19 +102,76 @@ final class ID3_Frame_USER extends ID3_Frame */ public function getEncoding() { return $this->_encoding; } + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the language code as specified in the * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. * - * @see ID3_Language#ISO_639_2 * @return string */ public function getLanguage() { return $this->_language; } - + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language + * @param string $language The language code. + */ + public function setLanguage($language) { $this->_language = $language; } + /** * Returns the text. * * @return string */ public function getText() { return $this->_text; } + + /** + * Sets the text using given language and encoding. + * + * @param string $text The text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setText($text, $language = false, $encoding = false) + { + $this->_text = $text; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_language; + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_text); + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_text); + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_text); + break; + default: + $data .= $this->_text; + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/USLT.php b/src/ID3/Frame/USLT.php index 83d0b2b..21c5c4a 100644 --- a/src/ID3/Frame/USLT.php +++ b/src/ID3/Frame/USLT.php @@ -58,10 +58,10 @@ final class ID3_Frame_USLT extends ID3_Frame implements ID3_Encoding, ID3_Language { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ - private $_language; + private $_language = "eng"; /** @var string */ private $_description; @@ -74,11 +74,14 @@ final class ID3_Frame_USLT extends ID3_Frame * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_encoding = ord($this->_data{0}); + + if ($reader === null) + return; + + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_language = substr($this->_data, 1, 3); $this->_data = substr($this->_data, 4); @@ -110,14 +113,30 @@ final class ID3_Frame_USLT extends ID3_Frame */ public function getEncoding() { return $this->_encoding; } + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the language code as specified in the * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. * - * @see ID3_Language#ISO_639_2 * @return string */ public function getLanguage() { return $this->_language; } + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language + * @param string $language The language code. + */ + public function setLanguage($language) { $this->_language = $language; } /** * Returns the short content description. @@ -125,11 +144,74 @@ final class ID3_Frame_USLT extends ID3_Frame * @return string */ public function getDescription() { return $this->_description; } - + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $language = false, + $encoding = false) + { + $this->_description = $description; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + /** * Returns the lyrics/text. * * @return string */ public function getText() { return $this->_text; } + + /** + * Sets the text using given encoding. The text language and encoding must be + * that of the description text. + * + * @param mixed $text The test string. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setText($text, $language = false, $encoding = false) + { + $this->_text = $text; + if ($language !== false) + $this->_language = $language; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * + * @return string + */ + public function __toString() + { + $data = Transform::toInt8($this->_encoding) . $this->_language; + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_description) . "\0\0" . + Transform::toString16($this->_text); + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_description) . "\0\0" . + Transform::toString16BE($this->_text); + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_description) . "\0\0" . + Transform::toString16LE($this->_text); + break; + default: + $data .= $this->_description . "\0" . $this->_text; + } + $this->setData($data); + return parent::__toString(); + } } diff --git a/src/ID3/Frame/WCOM.php b/src/ID3/Frame/WCOM.php index 9ba0880..d976f29 100644 --- a/src/ID3/Frame/WCOM.php +++ b/src/ID3/Frame/WCOM.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WCOP.php b/src/ID3/Frame/WCOP.php index 16bb817..0115a32 100644 --- a/src/ID3/Frame/WCOP.php +++ b/src/ID3/Frame/WCOP.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WOAF.php b/src/ID3/Frame/WOAF.php index f888847..50df02a 100644 --- a/src/ID3/Frame/WOAF.php +++ b/src/ID3/Frame/WOAF.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WOAR.php b/src/ID3/Frame/WOAR.php index 0631679..ec32302 100644 --- a/src/ID3/Frame/WOAR.php +++ b/src/ID3/Frame/WOAR.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WOAS.php b/src/ID3/Frame/WOAS.php index d8ef494..7961bea 100644 --- a/src/ID3/Frame/WOAS.php +++ b/src/ID3/Frame/WOAS.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WORS.php b/src/ID3/Frame/WORS.php index 9d95419..1ea09a8 100644 --- a/src/ID3/Frame/WORS.php +++ b/src/ID3/Frame/WORS.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WPAY.php b/src/ID3/Frame/WPAY.php index 69cbd4a..1c724da 100644 --- a/src/ID3/Frame/WPAY.php +++ b/src/ID3/Frame/WPAY.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WPUB.php b/src/ID3/Frame/WPUB.php index d7ef149..d5461b6 100644 --- a/src/ID3/Frame/WPUB.php +++ b/src/ID3/Frame/WPUB.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); /**#@-*/ /** diff --git a/src/ID3/Frame/WXXX.php b/src/ID3/Frame/WXXX.php index 4038ec3..6aa36f4 100644 --- a/src/ID3/Frame/WXXX.php +++ b/src/ID3/Frame/WXXX.php @@ -36,7 +36,7 @@ */ /**#@+ @ignore */ -require_once("AbstractLink.php"); +require_once("ID3/Frame/AbstractLink.php"); require_once("ID3/Encoding.php"); /**#@-*/ @@ -58,7 +58,7 @@ final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink implements ID3_Encoding { /** @var integer */ - private $_encoding; + private $_encoding = ID3_Encoding::UTF8; /** @var string */ private $_description; @@ -68,11 +68,14 @@ final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink * * @param Reader $reader The reader object. */ - public function __construct($reader) + public function __construct($reader = null) { parent::__construct($reader); - - $this->_encoding = ord($this->_data{0}); + + if ($reader === null) + return; + + $this->_encoding = Transform::fromInt8($this->_data[0]); $this->_data = substr($this->_data, 1); switch ($this->_encoding) { @@ -102,17 +105,56 @@ final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink */ public function getEncoding() { return $this->_encoding; } + /** + * Sets the text encoding. + * + * @see ID3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) { $this->_encoding = $encoding; } + /** * Returns the link description. * * @return string */ public function getDescription() { return $this->_description; } - + /** - * Returns the link. + * Sets the content description text using given encoding. * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = false) + { + $this->_description = $description; + if ($encoding !== false) + $this->_encoding = $encoding; + } + + /** + * Returns the frame raw data. + * * @return string */ - public function getLink() { return $this->_link; } + public function __toString() + { + $data = Transform::toInt8($this->_encoding); + switch ($this->_encoding) { + case self::UTF16: + $data .= Transform::toString16($this->_description) . "\0\0"; + break; + case self::UTF16BE: + $data .= Transform::toString16BE($this->_description) . "\0\0"; + break; + case self::UTF16LE: + $data .= Transform::toString16LE($this->_description) . "\0\0"); + break; + default: + $data .= $this->_description . "\0"; + } + $this->setData($data . $this->_link); + return parent::__toString(); + } } diff --git a/src/ID3v2.php b/src/ID3v2.php index 6990265..50415bb 100644 --- a/src/ID3v2.php +++ b/src/ID3v2.php @@ -112,6 +112,7 @@ final class ID3v2 * * @todo Only limited subset of flags are processed. * @todo Utilize the SEEK frame and search for a footer to find the tag + * @todo Utilize the LINK frame to fetch frames from other sources * @param string $filename The path to the file. * @param Array $options The options array. */ @@ -426,8 +427,6 @@ final class ID3v2 public function __toString() { $data = ""; - if ($this->hasExtendedHeader()) - $data .= $this->getExtendedHeader(); foreach ($this->_frames as $frames) foreach ($frames as $frame) $data .= $frame; @@ -447,10 +446,21 @@ final class ID3v2 else $padlen = ceil(log(0.2 * ($datalen / 1024 + 10), 10) * 1024); } + $data = str_pad($data, $datalen + $padlen, "\0"); - $this->_header->setSize($datalen + $padlen); + if ($this->hasExtendedHeader()) { + if ($this->_extendedHeader->hasFlag(ID3_ExtendedHeader::CRC32)) { + $crc = crc32($data); + if ($crc & 0x80000000) + $crc = -(($crc ^ 0xffffffff) + 1); + $this->_extendedHeader->setCrc($crc); + } + $data = $this->getExtendedHeader() . $data; + } - return "ID3" . $this->_header . str_pad($data, $datalen + $padlen, "\0") . + $this->_header->setSize(strlen($data)); + + return "ID3" . $this->_header . $data . ($this->hasFooter() ? "3DI" . $this->getFooter() : ""); } } diff --git a/src/Transform.php b/src/Transform.php index 59cddcb..66ff939 100644 --- a/src/Transform.php +++ b/src/Transform.php @@ -331,7 +331,7 @@ final class Transform */ public static function fromString16($value) { - if ($value{0} == 0xfe && $value{1} = 0xff) + if ($value[0] == 0xfe && $value[1] = 0xff) return self::fromString16BE(substr($value, 2)); else return self::fromString16LE(substr($value, 2)); diff --git a/tests/TestID3v2.php b/tests/TestID3v2.php index f5eedad..4addc45 100644 --- a/tests/TestID3v2.php +++ b/tests/TestID3v2.php @@ -41,7 +41,7 @@ require_once("ID3v2.php"); /**#@-*/ /** - * Unit test case for ID3v1 class. + * Unit test case for ID3v2 class. * * @package php-reader * @subpackage Tests @@ -55,6 +55,7 @@ final class TestID3v2 extends PHPUnit_Framework_TestCase function testTagCreate() { $id3 = new ID3v2(); + $id3->tit2->text = "Title 1"; $this->assertEquals("Title 1", $id3->tit2->text); $id3->tope->text = "Artist 1"; @@ -71,13 +72,12 @@ final class TestID3v2 extends PHPUnit_Framework_TestCase $this->assertEquals("Classical", $id3->tcon->text); $id3->write("id3v2.tag"); - echo "create"; } function testTagReadAfterCreate() { $id3 = new ID3v2("id3v2.tag"); - echo "read after create"; + $this->assertEquals("Title 1", $id3->tit2->text); $this->assertEquals("Artist 1", $id3->tope->text); $this->assertEquals("Album 1", $id3->talb->text); @@ -112,6 +112,7 @@ final class TestID3v2 extends PHPUnit_Framework_TestCase function testTagReadAfterChange() { $id3 = new ID3v2("id3v2.tag"); + $this->assertEquals("Title 2", $id3->tit2->text); $this->assertEquals("Artist 2", $id3->tope->text); $this->assertEquals("Album 2", $id3->talb->text);