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