PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Zend/Media/Asf/Object/Metadata.php

http://php-reader.googlecode.com/
PHP | 218 lines | 123 code | 11 blank | 84 comment | 15 complexity | 9b939df583a534a060cacd566e61fb3d MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Media
 17 * @subpackage ASF
 18 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Metadata.php 177 2010-03-09 13:13:34Z svollbehr $
 21 */
 22
 23/**#@+ @ignore */
 24require_once 'Zend/Media/Asf/Object.php';
 25/**#@-*/
 26
 27/**
 28 * The <i>Metadata Object</i> permits authors to store stream-based metadata in
 29 * a file. This object supports the same types of metadata information as the
 30 * <i>Extended Content Description Object</i> except that it also allows a
 31 * stream number to be specified.
 32 *
 33 * @todo       Implement better handling of various types of attributes
 34 *     according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx
 35 * @category   Zend
 36 * @package    Zend_Media
 37 * @subpackage ASF
 38 * @author     Sven Vollbehr <sven@vollbehr.eu>
 39 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 
 40 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 41 * @version    $Id: Metadata.php 177 2010-03-09 13:13:34Z svollbehr $
 42 */
 43final class Zend_Media_Asf_Object_Metadata extends Zend_Media_Asf_Object
 44{
 45    /** @var Array */
 46    private $_descriptionRecords = array();
 47
 48    /**
 49     * Constructs the class with given parameters and reads object related data
 50     * from the ASF file.
 51     *
 52     * @param Zend_Io_Reader $reader  The reader object.
 53     * @param Array          $options The options array.
 54     */
 55    public function __construct($reader = null, &$options = array())
 56    {
 57        parent::__construct($reader, $options);
 58
 59        if ($reader === null) {
 60            return;
 61        }
 62
 63        $descriptionRecordsCount = $this->_reader->readUInt16LE();
 64        for ($i = 0; $i < $descriptionRecordsCount; $i++) {
 65            $this->_reader->skip(2);
 66            $descriptionRecord =
 67                array('streamNumber' => $this->_reader->readUInt16LE());
 68            $nameLength = $this->_reader->readUInt16LE();
 69            $dataType = $this->_reader->readUInt16LE();
 70            $dataLength = $this->_reader->readUInt32LE();
 71            $descriptionRecord['name'] = iconv
 72                ('utf-16le', $this->getOption('encoding'),
 73                 $this->_reader->readString16($nameLength));
 74            switch ($dataType) {
 75                case 0: // Unicode string
 76                    $descriptionRecord['data'] = iconv
 77                        ('utf-16le', $this->getOption('encoding'),
 78                         $this->_reader->readString16($dataLength));
 79                    break;
 80                case 1: // BYTE array
 81                    $descriptionRecord['data'] = $this->_reader->read($dataLength);
 82                    break;
 83                case 2: // BOOL
 84                    $descriptionRecord['data'] = $this->_reader->readUInt16LE() == 1;
 85                    break;
 86                case 3: // DWORD
 87                    $descriptionRecord['data'] = $this->_reader->readUInt32LE();
 88                    break;
 89                case 4: // QWORD
 90                    $descriptionRecord['data'] = $this->_reader->readInt64LE();
 91                    break;
 92                case 5: // WORD
 93                    $descriptionRecord['data'] = $this->_reader->readUInt16LE();
 94                    break;
 95                default:
 96                    break;
 97            }
 98            $this->_descriptionRecords[] = $descriptionRecord;
 99        }
100    }
101
102    /**
103     * Returns the array of description records. Each record consists of the
104     * following keys.
105     *
106     *   o streamNumber -- Specifies the stream number. Valid values are between
107     *     1 and 127.
108     *
109     *   o name -- Specifies the name that uniquely identifies the attribute
110     *     being described. Names are case-sensitive.
111     *
112     *   o data -- Specifies the actual metadata being stored.
113     *
114     * @return Array
115     */
116    public function getDescriptionRecords() 
117    {
118        return $this->_descriptionRecords; 
119    }
120
121    /**
122     * Sets the array of description records. Each record must consist of the
123     * following keys.
124     *
125     *   o streamNumber -- Specifies the stream number. Valid values are between
126     *     1 and 127.
127     *
128     *   o name -- Specifies the name that uniquely identifies the attribute
129     *     being described. Names are case-sensitive.
130     *
131     *   o data -- Specifies the actual metadata being stored.
132     *
133     * @param Array $descriptionRecords The array of description records.
134     */
135    public function setDescriptionRecords($descriptionRecords)
136    {
137        $this->_descriptionRecords = $descriptionRecords;
138    }
139
140    /**
141     * Writes the object data.
142     *
143     * @param Zend_Io_Writer $writer The writer object.
144     * @return void
145     */
146    public function write($writer)
147    {
148        require_once 'Zend/Io/StringWriter.php';
149        $descriptionRecordsCount = count($this->_descriptionRecords);
150        $descriptionRecordsWriter = new Zend_Io_StringWriter();
151        for ($i = 0; $i < $descriptionRecordsCount; $i++) {
152            $descriptionRecordsWriter
153                ->writeUInt16LE(0)
154                ->writeUInt16LE($this->_descriptionRecords[$i]['streamNumber'])
155                ->writeUInt16LE(strlen($name = iconv
156                    ($this->getOption('encoding'), 'utf-16le',
157                     $this->_descriptionRecords[$i]['name']) . "\0\0"));
158            if (is_string($this->_descriptionRecords[$i]['data'])) {
159                /* There is no way to distinguish byte arrays from unicode
160                 * strings and hence the need for a list of fields of type byte
161                 * array */
162                static $byteArray = array (
163                    ''
164                ); // TODO: Add to the list if you encounter one
165
166                if (in_array($name, $byteArray)) {
167                    $descriptionRecordsWriter
168                        ->writeUInt16LE(1)
169                        ->writeUInt32LE
170                            (strlen($this->_descriptionRecords[$i]['data']))
171                        ->write($name)
172                        ->write($this->_descriptionRecords[$i]['data']);
173                } else {
174                    $value = iconv
175                        ($this->getOption('encoding'), 'utf-16le',
176                         $this->_descriptionRecords[$i]['data']);
177                    $value = ($value ? $value . "\0\0" : '');
178                    $descriptionRecordsWriter
179                        ->writeUInt16LE(0)
180                        ->writeUInt32LE(strlen($value))
181                        ->write($name)
182                        ->writeString16($value);
183                }
184            } else if (is_bool($this->_descriptionRecords[$i]['data'])) {
185                $descriptionRecordsWriter
186                    ->writeUInt16LE(2)
187                    ->writeUInt32LE(2)
188                    ->write($name)
189                    ->writeUInt16LE
190                        ($this->_descriptionRecords[$i]['data'] ? 1 : 0);
191            } else if (is_int($this->_descriptionRecords[$i]['data'])) {
192                $descriptionRecordsWriter
193                    ->writeUInt16LE(3)
194                    ->writeUInt32LE(4)
195                    ->write($name)
196                    ->writeUInt32LE($this->_descriptionRecords[$i]['data']);
197            } else if (is_float($this->_descriptionRecords[$i]['data'])) {
198                $descriptionRecordsWriter
199                    ->writeUInt16LE(4)
200                    ->writeUInt32LE(8)
201                    ->write($name)
202                    ->writeInt64LE($this->_descriptionRecords[$i]['data']);
203            } else {
204                // Invalid value and there is nothing to be done
205                require_once 'Zend/Media/Asf/Exception.php';
206                throw new Zend_Media_Asf_Exception('Invalid data type');
207            }
208        }
209
210        $this->setSize
211            (24 /* for header */ + 2 + $descriptionRecordsWriter->getSize());
212
213        $writer->writeGuid($this->getIdentifier())
214               ->writeInt64LE($this->getSize())
215               ->writeUInt16LE($descriptionRecordsCount)
216               ->write($descriptionRecordsWriter->toString());
217    }
218}