コード例 #1
0
ファイル: Header.php プロジェクト: hausdesign/zf-library
 /**
  * Constructs the class with given parameters and reads object related data
  * from the ID3v2 tag.
  *
  * @param HausDesign_Io_Reader $reader The reader object.
  * @param Array $options The options array.
  */
 public function __construct($reader = null, &$options = array())
 {
     parent::__construct($reader, $options);
     if ($reader === null) {
         return;
     }
     $this->_version = $options['version'] = $this->_reader->readUInt8() + $this->_reader->readUInt8() / 10;
     $this->_flags = $this->_reader->readUInt8();
     $this->_size = $this->_decodeSynchsafe32($this->_reader->readUInt32BE());
 }
コード例 #2
0
ファイル: Id3v2.php プロジェクト: hausdesign/zf-library
 /**
  * Constructs the HausDesign_Media_Id3v2 class with given file and options. The
  * options array may also be given as the only parameter.
  *
  * The following options are currently recognized:
  *   o encoding -- Indicates the encoding that all the texts are presented
  *     with. See the documentation of iconv for supported values. Please
  *     note that write operations do not convert string and thus encodings
  *     are limited to those supported by the {@link HausDesign_Media_Id3_Encoding}
  *     interface.
  *   o version -- The ID3v2 tag version to use in write operation. This
  *     option is automatically set when a tag is read from a file and
  *     defaults to version 4.0 for tag write.
  *   o compat -- Normally unsynchronization is handled automatically behind
  *     the scenes. However, current versions of Windows operating system and
  *     Windows Media Player, just to name a few, do not support ID3v2.4 tags
  *     nor ID3v2.3 tags with unsynchronization. Hence, for compatibility
  *     reasons, this option is made available to disable automatic tag level
  *     unsynchronization scheme that version 3.0 supports.
  *   o readonly -- Indicates that the tag is read from a temporary file or
  *     another source it cannot be written back to. The tag can, however,
  *     still be written to another file.
  *
  * @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|resource|HausDesign_Io_Reader $filename The path to the file,
  *  file descriptor of an opened file, or a {@link HausDesign_Io_Reader} instance.
  * @param Array                          $options  The options array.
  * @throws HausDesign_Media_Id3_Exception if given file descriptor is not valid
  */
 public function __construct($filename = null, $options = array())
 {
     parent::__construct(null, $options);
     if (is_array($filename)) {
         $options = $filename;
         $filename = null;
     }
     if ($filename === null) {
         $this->_header = new HausDesign_Media_Id3_Header(null, $options);
         return;
     }
     if ($filename instanceof HausDesign_Io_Reader) {
         $this->_reader =& $filename;
     } else {
         require_once 'HausDesign/Io/FileReader.php';
         try {
             $this->_reader = new HausDesign_Io_FileReader($filename);
         } catch (HausDesign_Io_Exception $e) {
             $this->_reader = null;
             require_once 'HausDesign/Media/Id3/Exception.php';
             throw new HausDesign_Media_Id3_Exception($e->getMessage());
         }
         if (is_string($filename) && !isset($options['readonly'])) {
             $this->_filename = $filename;
         }
     }
     $startOffset = $this->_reader->getOffset();
     if ($this->_reader->read(3) != 'ID3') {
         require_once 'HausDesign/Media/Id3/Exception.php';
         throw new HausDesign_Media_Id3_Exception('File does not contain ID3v2 tag');
     }
     $this->_header = new HausDesign_Media_Id3_Header($this->_reader, $options);
     $tagSize = $this->_header->getSize();
     if ($this->_header->getVersion() < 3 || $this->_header->getVersion() > 4) {
         require_once 'HausDesign/Media/Id3/Exception.php';
         throw new HausDesign_Media_Id3_Exception('File does not contain ID3v2 tag of supported version: v2.' . $this->_header->getVersion());
     }
     if ($this->_header->getVersion() < 4 && $this->_header->hasFlag(HausDesign_Media_Id3_Header::UNSYNCHRONISATION)) {
         $data = $this->_reader->read($this->_header->getSize());
         require_once 'HausDesign/Io/StringReader.php';
         $this->_reader = new HausDesign_Io_StringReader($this->_decodeUnsynchronisation($data));
         $tagSize = $this->_reader->getSize();
     }
     $this->clearOption('unsynchronisation');
     if ($this->_header->hasFlag(HausDesign_Media_Id3_Header::UNSYNCHRONISATION)) {
         $this->setOption('unsynchronisation', true);
     }
     if ($this->_header->hasFlag(HausDesign_Media_Id3_Header::EXTENDED_HEADER)) {
         require_once 'HausDesign/Media/Id3/ExtendedHeader.php';
         $this->_extendedHeader = new HausDesign_Media_Id3_ExtendedHeader($this->_reader, $options);
     }
     if ($this->_header->hasFlag(HausDesign_Media_Id3_Header::FOOTER)) {
         // skip footer, and rather copy header
         $this->_footer =& $this->_header;
     }
     while (true) {
         $offset = $this->_reader->getOffset();
         // Jump off the loop if we reached the end of the tag
         if ($offset - $startOffset - 10 >= $tagSize - ($this->hasFooter() ? 10 : 0) - 10) {
             break;
         }
         // Jump off the loop if we reached padding
         if (ord($identifier = $this->_reader->read(1)) === 0) {
             break;
         }
         $identifier .= $this->_reader->read(3);
         // Jump off the loop if we reached invalid entities. This fix is
         // just to make things work. Utility called MP3ext does not seem
         // to know what it is doing as it uses padding to write its
         // version information there.
         if ($identifier == 'MP3e') {
             break;
         }
         $this->_reader->setOffset($offset);
         if (@fopen($file = 'HausDesign/Media/Id3/Frame/' . ucfirst(strtolower($identifier)) . '.php', 'r', true) !== false) {
             require_once $file;
         }
         if (class_exists($classname = 'HausDesign_Media_Id3_Frame_' . ucfirst(strtolower($identifier)))) {
             $frame = new $classname($this->_reader, $options);
         } else {
             require_once 'HausDesign/Media/Id3/Frame/Unknown.php';
             $frame = new HausDesign_Media_Id3_Frame_Unknown($this->_reader, $options);
         }
         if (!isset($this->_frames[$frame->getIdentifier()])) {
             $this->_frames[$frame->getIdentifier()] = array();
         }
         $this->_frames[$frame->getIdentifier()][] = $frame;
     }
 }
コード例 #3
0
 /**
  * Constructs the class with given parameters and reads object related data
  * from the ID3v2 tag.
  *
  * @param HausDesign_Io_Reader $reader  The reader object.
  * @param Array          $options The options array.
  */
 public function __construct($reader = null, &$options = array())
 {
     parent::__construct($reader, $options);
     if ($reader === null) {
         return;
     }
     $offset = $this->_reader->getOffset();
     $this->_size = $this->_reader->readUInt32BE();
     /* ID3v2.3.0 ExtendedHeader */
     if ($this->getOption('version', 4) < 4) {
         if ($this->_reader->readUInt16BE() == 0x8000) {
             $this->_flags = self::CRC32;
         }
         $this->_padding = $this->_reader->readUInt32BE();
         if ($this->hasFlag(self::CRC32)) {
             $this->_crc = $this->_reader->readUInt32BE();
         }
     } else {
         $this->_size = $this->_decodeSynchsafe32($this->_size);
         $this->_reader->skip(1);
         $this->_flags = $this->_reader->readInt8();
         if ($this->hasFlag(self::UPDATE)) {
             $this->_reader->skip(1);
         }
         if ($this->hasFlag(self::CRC32)) {
             $this->_reader->skip(1);
             $this->_crc = $this->_reader->readInt8() * (0xfffffff + 1) + $this->_decodeSynchsafe32($this->_reader->readUInt32BE());
         }
         if ($this->hasFlag(self::RESTRICTED)) {
             $this->_reader->skip(1);
             $this->_restrictions = $this->_reader->readInt8();
         }
     }
 }
コード例 #4
0
ファイル: Frame.php プロジェクト: hausdesign/zf-library
 /**
  * Constructs the class with given parameters and reads object related data
  * from the ID3v2 tag.
  *
  * Replaces the reader instance with a string reader object instance that
  * can be used to further process the data in the frame sub class.
  *
  * @todo  Only limited subset of flags are processed.
  * @param HausDesign_Io_Reader $reader The reader object.
  * @param Array $options The options array.
  */
 public function __construct($reader = null, &$options = array())
 {
     parent::__construct($reader, $options);
     if ($reader === null) {
         $this->_identifier = strtoupper(substr(get_class($this), -4));
     } else {
         $this->_identifier = strtoupper($this->_reader->readString8(4, " "));
         /* ID3v2.3.0 size and flags; convert flags to 2.4.0 format */
         if ($this->getOption('version', 4) < 4) {
             $this->_size = $this->_reader->readUInt32BE();
             $flags = $this->_reader->readUInt16BE();
             if (($flags & 0x8000) == 0x8000) {
                 $this->_flags |= self::DISCARD_ON_TAGCHANGE;
             }
             if (($flags & 0x4000) == 0x4000) {
                 $this->_flags |= self::DISCARD_ON_FILECHANGE;
             }
             if (($flags & 0x2000) == 0x2000) {
                 $this->_flags |= self::READ_ONLY;
             }
             if (($flags & 0x80) == 0x80) {
                 $this->_flags |= self::COMPRESSION;
             }
             if (($flags & 0x40) == 0x40) {
                 $this->_flags |= self::ENCRYPTION;
             }
             if (($flags & 0x20) == 0x20) {
                 $this->_flags |= self::GROUPING_IDENTITY;
             }
         } else {
             $this->_size = $this->_decodeSynchsafe32($this->_reader->readUInt32BE());
             $this->_flags = $this->_reader->readUInt16BE();
         }
         $dataLength = $this->_size;
         if ($this->hasFlag(self::DATA_LENGTH_INDICATOR)) {
             $dataLength = $this->_decodeSynchsafe32($this->_reader->readUInt32BE());
             $this->_size -= 4;
         }
         $data = $this->_reader->read($this->_size);
         $this->_size = $dataLength;
         if ($this->hasFlag(self::UNSYNCHRONISATION) || $this->getOption('unsynchronisation', false) === true) {
             $data = $this->_decodeUnsynchronisation($data);
         }
         $this->_reader = new HausDesign_Io_StringReader($data);
     }
 }