diff --git a/src/ASF.php b/src/ASF.php
new file mode 100644
index 0000000..75df1cb
--- /dev/null
+++ b/src/ASF.php
@@ -0,0 +1,119 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+class ASF
+{
+ /** @var Reader The Reader object */
+ private $_reader;
+
+ /**
+ * The default constructor. Initiates the reader for the given file.
+ */
+ public function __construct($filename)
+ {
+ $this->_reader = new Reader($filename);
+ }
+
+ /**
+ * Checks whether the reader was successfully initiated and whether there are
+ * objects left in the stream.
+ *
+ * @return Boolean value corresponding whether there is more to read.
+ */
+ public function hasObjects()
+ {
+ return $this->_reader->available();
+ }
+
+ /**
+ * Returns the next ASF object or false if end of stream has been reached.
+ *
+ * @todo Only the ASF_Header_Object top level object is regognized.
+ * @return ASFObject Returns the appropriate object. Returned objects are of
+ * the type ASFObject or of any of the other object types that inherit
+ * from that base class.
+ */
+ public function nextObject()
+ {
+ $object = false;
+ if ($this->hasObjects()) {
+ $guid = $this->_reader->getGUID();
+ $size = $this->_reader->getInt64LE();
+ $offset = $this->_reader->getOffset();
+
+ switch ($guid) {
+ case "75b22630-668e-11cf-a6d9-00aa0062ce6c": /* ASF_Header_Object */
+ $object = new ASF_HeaderObject($this->_reader, $guid, $size);
+ break;
+ default:
+ $object = new ASF_Object($this->_reader, $guid, $size);
+ }
+
+ $this->_reader->setOffset($offset - 24 + $size);
+ }
+ return $object;
+ }
+}
diff --git a/src/ASF/ContentDescriptionObject.php b/src/ASF/ContentDescriptionObject.php
new file mode 100644
index 0000000..e0b8aa0
--- /dev/null
+++ b/src/ASF/ContentDescriptionObject.php
@@ -0,0 +1,134 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+final class ASF_ContentDescriptionObject extends ASF_Object
+{
+ /**
+ * @var string The title field.
+ */
+ private $_title;
+
+ /**
+ * @var string The author field.
+ */
+ private $_author;
+
+ /**
+ * @var string The copyright field.
+ */
+ private $_copyright;
+
+ /**
+ * @var string The description field.
+ */
+ private $_description;
+
+ /**
+ * @var string The rating field.
+ */
+ private $_rating;
+
+ /**
+ * Default constructor. Initiates the class with given parameters and reads
+ * object related data from the ASF file.
+ */
+ public function __construct($reader, $id, $size)
+ {
+ parent::__construct($reader, $id, $size);
+
+ $titleLen = $this->_reader->getUInt16LE();
+ $authorLen = $this->_reader->getUInt16LE();
+ $copyrightLen = $this->_reader->getUInt16LE();
+ $descriptionLen = $this->_reader->getUInt16LE();
+ $ratingLen = $this->_reader->getUInt16LE();
+
+ $this->_title = $this->_reader->getString16LE($titleLen);
+ $this->_author = $this->_reader->getString16LE($authorLen);
+ $this->_copyright = $this->_reader->getString16LE($copyrightLen);
+ $this->_description = $this->_reader->getString16LE($descriptionLen);
+ $this->_rating = $this->_reader->getString16LE($ratingLen);
+ }
+
+ /**
+ * Returns the title field.
+ *
+ * @return string Returns the title field.
+ */
+ public function getTitle() { return $this->_title; }
+
+ /**
+ * Returns the author field.
+ *
+ * @return string Returns the author field.
+ */
+ public function getAuthor() { return $this->_author; }
+
+ /**
+ * Returns the copyright field.
+ *
+ * @return string Returns the copyright field.
+ */
+ public function getCopyright() { return $this->_copyright; }
+
+ /**
+ * Returns the description field.
+ *
+ * @return string Returns the description field.
+ */
+ public function getDescription() { return $this->_description; }
+
+ /**
+ * Returns the rating field.
+ *
+ * @return string Returns the rating field.
+ */
+ public function getRating() { return $this->_rating; }
+}
diff --git a/src/ASF/ExtendedContentDescriptionObject.php b/src/ASF/ExtendedContentDescriptionObject.php
new file mode 100644
index 0000000..d126dcd
--- /dev/null
+++ b/src/ASF/ExtendedContentDescriptionObject.php
@@ -0,0 +1,107 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+final class ASF_ExtendedContentDescriptionObject extends ASF_Object
+{
+ /**
+ * @var Array An associate array of descriptors and their values.
+ */
+ private $_contentDescriptors = array();
+
+ /**
+ * Initiates the object class with given parameters and reads and processes
+ * the object information from the ASF file.
+ */
+ public function __construct($reader, $id, $size)
+ {
+ parent::__construct($reader, $id, $size);
+
+ $contentDescriptorsCount = $this->_reader->getUInt16LE();
+ for ($i = 0; $i < $contentDescriptorsCount; $i++) {
+ $nameLen = $this->_reader->getUInt16LE();
+ $name = $this->_reader->getString16LE($nameLen);
+ $valueDataType = $this->_reader->getUInt16LE();
+ $valueLen = $this->_reader->getUInt16LE();
+ switch ($valueDataType) {
+ case 0:
+ case 1: // string
+ $this->_contentDescriptors[$name] =
+ $this->_reader->getString16LE($valueLen);
+ break;
+ case 2: // bool
+ case 3: // 32-bit integer
+ $this->_contentDescriptors[$name] = $this->_reader->getUInt32LE();
+ break;
+ case 4: // 64-bit integer
+ $this->_contentDescriptors[$name] = $this->_reader->getInt64LE();
+ break;
+ case 5: // 16-bit integer
+ $this->_contentDescriptors[$name] = $this->_reader->getUInt16LE();
+ break;
+ default:
+ }
+ }
+ }
+
+ /**
+ * Returns the value of the specified descriptor or false if there
+ * is no such descriptor defined.
+ *
+ * @param string $name The name of the descriptor (ie the name of the field).
+ * @return string Returns the value of a descriptor.
+ */
+ public function getDescriptor($name)
+ {
+ if (isset($this->_contentDescriptors[$name]))
+ return $this->_contentDescriptors[$name];
+ return false;
+ }
+}
diff --git a/src/ASF/FilePropertiesObject.php b/src/ASF/FilePropertiesObject.php
new file mode 100644
index 0000000..0c3007f
--- /dev/null
+++ b/src/ASF/FilePropertiesObject.php
@@ -0,0 +1,231 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+final class ASF_FilePropertiesObject extends ASF_Object
+{
+ /**
+ * @var string The file id field.
+ */
+ private $_fileId;
+
+ /**
+ * @var string The file size field.
+ */
+ private $_fileSize;
+
+ /**
+ * @var string The creation date field.
+ */
+ private $_creationDate;
+
+ /**
+ * @var string The data packets count field.
+ */
+ private $_dataPacketsCount;
+
+ /**
+ * @var string The play duration field.
+ */
+ private $_playDuration;
+
+ /**
+ * @var string The send duration field.
+ */
+ private $_sendDuration;
+
+ /**
+ * @var string The preroll field.
+ */
+ private $_preroll;
+
+ /**
+ * @var string The flags field.
+ */
+ private $_flags;
+
+ /**
+ * @var string The minimum data packet size field.
+ */
+ private $_minimumDataPacketSize;
+
+ /**
+ * @var string The maximum data packet size field.
+ */
+ private $_maximumDataPacketSize;
+
+ /**
+ * @var string The maximum bitrate field.
+ */
+ private $_maximumBitrate;
+
+ /**
+ * Initiates the object class with given parameters and reads and processes
+ * the object information from the ASF file.
+ */
+ public function __construct($reader, $id, $size)
+ {
+ parent::__construct($reader, $id, $size);
+
+ $this->_fileId = $this->_reader->getGUID();
+ $this->_fileSize = $this->_reader->getInt64LE();
+ $this->_creationDate = $this->_reader->getInt64LE();
+ $this->_dataPacketsCount = $this->_reader->getInt64LE();
+
+ $seconds = floor($this->_reader->getInt64LE() / 10000000);
+ $minutes = floor($seconds / 60);
+ $hours = floor($minutes / 60);
+ $this->_playDuration =
+ ($minutes > 0 ?
+ ($hours > 0 ? $hours . ":" .
+ str_pad($minutes % 60, 2, "0", STR_PAD_LEFT) : $minutes % 60) . ":" .
+ str_pad($seconds % 60, 2, "0", STR_PAD_LEFT) : $seconds % 60);
+
+ $seconds = floor($this->_reader->getInt64LE() / 10000000);
+ $minutes = floor($seconds / 60);
+ $hours = floor($minutes / 60);
+ $this->_sendDuration =
+ ($minutes > 0 ?
+ ($hours > 0 ? $hours . ":" .
+ str_pad($minutes % 60, 2, "0", STR_PAD_LEFT) : $minutes % 60) . ":" .
+ str_pad($seconds % 60, 2, "0", STR_PAD_LEFT) : $seconds % 60);
+
+ $this->_preroll = $this->_reader->getInt64LE();
+ $this->_flags = $this->_reader->getUInt32LE();
+ $this->_minimumDataPacketSize = $this->_reader->getUInt32LE();
+ $this->_maximumDataPacketSize = $this->_reader->getUInt32LE();
+ $this->_maximumBitrate = $this->_reader->getUInt32LE();
+ }
+
+ /**
+ * Returns the file id field.
+ *
+ * @return integer Returns the file id field.
+ */
+ public function getFileId() { return $this->_fileId; }
+
+ /**
+ * Returns the file size field.
+ *
+ * @return integer Returns the file size field.
+ */
+ public function getFileSize() { return $this->_fileSize; }
+
+ /**
+ * Returns the creation date field.
+ *
+ * @return integer Returns the creation date field.
+ */
+ public function getCreationDate() { return $this->_creationDate; }
+
+ /**
+ * Returns the data packets field.
+ *
+ * @return integer Returns the data packets field.
+ */
+ public function getDataPacketsCount() { return $this->_dataPacketsCount; }
+
+ /**
+ * Returns the play duration field.
+ *
+ * @return integer Returns the play duration field.
+ */
+ public function getPlayDuration() { return $this->_playDuration; }
+
+ /**
+ * Returns the send duration field.
+ *
+ * @return integer Returns the send duration field.
+ */
+ public function getSendDuration() { return $this->_sendDuration; }
+
+ /**
+ * Returns the preroll field.
+ *
+ * @return integer Returns the preroll field.
+ */
+ public function getPreroll() { return $this->_preroll; }
+
+ /**
+ * Returns the flags field.
+ *
+ * @return integer Returns the flags field.
+ */
+ public function getFlags() { return $this->_flags; }
+
+ /**
+ * Returns the minimum data packet size field.
+ *
+ * @return integer Returns the minimum data packet size field.
+ */
+ public function getMinimumDataPacketSize()
+ {
+ return $this->_minimumDataPacketSize;
+ }
+
+ /**
+ * Returns the maximum data packet size field.
+ *
+ * @return integer Returns the maximum data packet size field.
+ */
+ public function getMaximumDataPacketSize()
+ {
+ return $this->_maximumDataPacketSize;
+ }
+
+ /**
+ * Returns the maximum bitrate field.
+ *
+ * @return integer Returns the maximum bitrate field.
+ */
+ public function getMaximumBitrate()
+ {
+ return $this->_maximumBitrate;
+ }
+}
diff --git a/src/ASF/HeaderObject.php b/src/ASF/HeaderObject.php
new file mode 100644
index 0000000..433fd0a
--- /dev/null
+++ b/src/ASF/HeaderObject.php
@@ -0,0 +1,147 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+final class ASF_HeaderObject extends ASF_Object
+{
+ /**
+ * @var integer The number of the objects the header contains.
+ */
+ private $_objectCount;
+
+ /**
+ * @var integer Internal variable to have the start of the stream stored in.
+ */
+ private $_readerSOffset;
+
+ /**
+ * @var integer Internal variable to have the current position of the
+ * stream pointer stored in.
+ */
+ private $_readerCOffset;
+
+ /**
+ * Default constructor. Initiates the class with given parameters and reads
+ * object information from the file.
+ */
+ public function __construct($reader, $id, $size)
+ {
+ parent::__construct($reader, $id, $size);
+
+ $this->_readerSOffset = $this->_reader->getOffset();
+ $this->_objectCount = $this->_reader->getUInt32LE();
+ $this->_reader->skip(2);
+ $this->_readerCOffset = $this->_reader->getOffset();
+ }
+
+ /**
+ * Returns the number of standard ASF header objects this object contains.
+ *
+ * @return integer The number of objects the header contains.
+ */
+ public function getObjectCount() { return $this->_objectCount; }
+
+ /**
+ * Checks whether there is more to be read within the bounds of the parent
+ * object size.
+ *
+ * @return boolean Boolean value corresponding whether there is more to read.
+ */
+ public function hasChildObjects()
+ {
+ return ($this->_readerSOffset + $this->_size) > $this->_readerCOffset;
+ }
+
+ /**
+ * Returns the next standard ASF object or false if end of stream
+ * has been reached.
+ *
+ * @todo Only limited subset of possible child objects are regognized.
+ * @return ASF_Object Returns the appropriate object. Returned objects are of
+ * the type ASFObject or of any of the other object types that inherit
+ * from that base class.
+ */
+ public function nextChildObject()
+ {
+ $object = false;
+ if ($this->hasChildObjects()) {
+ $this->_reader->setOffset($this->_readerCOffset);
+ $guid = $this->_reader->getGUID();
+ $size = $this->_reader->getInt64LE();
+ $offset = $this->_reader->getOffset();
+ switch ($guid) {
+ /* ASF_Content_Description_Object */
+ case "75b22633-668e-11cf-a6d9-00aa0062ce6c":
+ $object =
+ new ASF_ContentDescriptionObject($this->_reader, $guid, $size);
+ break;
+ /* ASF_Header_Extension_Object */
+ case "5fbf03b5-a92e-11cf-8ee3-00c00c205365":
+ $this->_reader->skip(48);
+ $this->_readerCOffset = $this->_reader->getOffset();
+ $object = $this->nextChildObject();
+ break;
+ /* ASF_Extended_Content_Description_Object */
+ case "d2d0a440-e307-11d2-97f0-00a0c95ea850":
+ $object = new ASF_ExtendedContentDescriptionObject
+ ($this->_reader, $guid, $size);
+ break;
+ /* ASF_File_Properties_Object */
+ case "8cabdca1-a947-11cf-8ee4-00c00c205365":
+ $object = new ASF_FilePropertiesObject($this->_reader, $guid, $size);
+ break;
+ default: // not implemented
+ $object = new ASF_Object($this->_reader, $guid, $size);
+ }
+ $this->_reader->setOffset(($this->_readerCOffset = $offset - 24 + $size));
+ }
+ return $object;
+ }
+}
diff --git a/src/ASF/Object.php b/src/ASF/Object.php
new file mode 100644
index 0000000..8e69d4a
--- /dev/null
+++ b/src/ASF/Object.php
@@ -0,0 +1,79 @@
+
+ * @copyright 2006, 2007 The Bearpaw Project Work Group
+ * @copyright 2007, 2008 BEHR Software Systems
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version $Rev$
+ */
+class ASF_Object
+{
+ /**
+ * @var Reader The reader associated with this object.
+ */
+ protected $_reader;
+
+ /**
+ * @var string Object's ID
+ */
+ private $_id;
+
+ /**
+ * @var integer Object size in bytes.
+ */
+ protected $_size;
+
+ /**
+ * Constructs the object with the given parameters.
+ */
+ public function __construct($reader, $id, $size)
+ {
+ $this->_reader = $reader;
+ $this->_id = $id;
+ $this->_size = $size;
+ }
+
+ /**
+ * Returns the GUID of the ASF object.
+ *
+ * @return string Returns the GUID of the ASF object.
+ */
+ public function getID() { return $this->_id; }
+}