All Unit tests
Current file: C:\code\midiparser\src\Midi\Parsing\TrackParser.php
Legend: executed not executed dead code

  Coverage
  Classes Functions / Methods Lines
Total
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
100.00%100.00%
100.00% 59 / 59
 
Midi\TrackParser
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 8 / 8
100.00%100.00%
100.00% 59 / 59
 public function __construct(EventParser $eventParser = null, DeltaParser $deltaParser = null)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6
 public function getExpectedTrackLength()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function getParsedTrackLength()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 protected function getRawTrackHeader()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 1 / 1
 public function parseTrackHeader($header)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 13 / 13
 protected function afterSetFile()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 3 / 3
 public function parse()
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 27 / 27
 protected function checkTrackLength($length)
100.00%100.00%
100.00% 1 / 1
100.00%100.00%
100.00% 6 / 6


       1                 : <?php                                                                                                                          
       2                 :                                                                                                                                
       3                 :     /**                                                                                                                        
       4                 :      * \Midi\Parsing\TrackParser                                                                                               
       5                 :      *                                                                                                                         
       6                 :      * @package    Midi                                                                                                        
       7                 :      * @subpackage Parsing                                                                                                     
       8                 :      * @copyright  © 2009 Tommy Montgomery <http://phpmidiparser.com/>                                                         
       9                 :      * @since      1.0                                                                                                         
      10                 :      */                                                                                                                        
      11                 :                                                                                                                                
      12                 :     namespace Midi\Parsing;                                                                                                    
      13                 :                                                                                                                                
      14                 :     use Midi\Event;                                                                                                            
      15                 :     use Midi\TrackHeader;                                                                                                      
      16                 :     use Midi\Util\Util;                                                                                                        
      17                 :                                                                                                                                
      18                 :     /**                                                                                                                        
      19                 :      * Class for parsing MIDI tracks                                                                                           
      20                 :      *                                                                                                                         
      21                 :      * The parse state is initialized to {@link ParseState::TRACK_HEADER}.                                                     
      22                 :      *                                                                                                                         
      23                 :      * @package    Midi                                                                                                        
      24                 :      * @subpackage Parsing                                                                                                     
      25                 :      * @since      1.0                                                                                                         
      26                 :      */                                                                                                                        
      27               1 :     class TrackParser extends Parser {                                                                                         
      28                 :                                                                                                                                
      29                 :         /**                                                                                                                    
      30                 :          * @var EventParser                                                                                                    
      31                 :          */                                                                                                                    
      32                 :         private $eventParser;                                                                                                  
      33                 :                                                                                                                                
      34                 :         /**                                                                                                                    
      35                 :          * @var DeltaParser                                                                                                    
      36                 :          */                                                                                                                    
      37                 :         private $deltaParser;                                                                                                  
      38                 :                                                                                                                                
      39                 :         /**                                                                                                                    
      40                 :          * The expected length of the track in bytes                                                                           
      41                 :          *                                                                                                                     
      42                 :          * @var int                                                                                                            
      43                 :          */                                                                                                                    
      44                 :         private $expectedTrackLength;                                                                                          
      45                 :                                                                                                                                
      46                 :         /**                                                                                                                    
      47                 :          * The number of bytes that have been parsed so far                                                                    
      48                 :          *                                                                                                                     
      49                 :          * @var int                                                                                                            
      50                 :          */                                                                                                                    
      51                 :         private $parsedTrackLength;                                                                                            
      52                 :                                                                                                                                
      53                 :         /**                                                                                                                    
      54                 :          * Constructor                                                                                                         
      55                 :          *                                                                                                                     
      56                 :          * @since 1.0                                                                                                          
      57                 :          * @uses  setState()                                                                                                   
      58                 :          *                                                                                                                     
      59                 :          * @param  EventParser $eventParser                                                                                    
      60                 :          * @param  DeltaParser $deltaParser                                                                                    
      61                 :          */                                                                                                                    
      62                 :         public function __construct(EventParser $eventParser = null, DeltaParser $deltaParser = null) {                        
      63              28 :             $this->eventParser         = ($eventParser === null) ? new EventParser() : $eventParser;                           
      64              28 :             $this->deltaParser         = ($deltaParser === null) ? new DeltaParser() : $deltaParser;                           
      65              28 :             $this->expectedTrackLength = 0;                                                                                    
      66              28 :             $this->parsedTrackLength   = 0;                                                                                    
      67                 :                                                                                                                                
      68              28 :             $this->setState(ParseState::TRACK_HEADER);                                                                         
      69              28 :         }                                                                                                                      
      70                 :                                                                                                                                
      71                 :         /**                                                                                                                    
      72                 :          * Gets the expected length of the track in bytes                                                                      
      73                 :          *                                                                                                                     
      74                 :          * @since 1.0                                                                                                          
      75                 :          *                                                                                                                     
      76                 :          * @return int                                                                                                         
      77                 :          */                                                                                                                    
      78                 :         public function getExpectedTrackLength() {                                                                             
      79               1 :             return $this->expectedTrackLength;                                                                                 
      80                 :         }                                                                                                                      
      81                 :                                                                                                                                
      82                 :         /**                                                                                                                    
      83                 :          * Gets the total number of bytes that have already been                                                               
      84                 :          * parsed in the track                                                                                                 
      85                 :          *                                                                                                                     
      86                 :          * @since 1.0                                                                                                          
      87                 :          *                                                                                                                     
      88                 :          * @return int                                                                                                         
      89                 :          */                                                                                                                    
      90                 :         public function getParsedTrackLength() {                                                                               
      91               1 :             return $this->parsedTrackLength;                                                                                   
      92                 :         }                                                                                                                      
      93                 :                                                                                                                                
      94                 :         /**                                                                                                                    
      95                 :          * Gets the raw binary track header                                                                                    
      96                 :          *                                                                                                                     
      97                 :          * @since 1.0                                                                                                          
      98                 :          * @uses  read()                                                                                                       
      99                 :          * @uses  TrackHeader::LENGTH                                                                                          
     100                 :          *                                                                                                                     
     101                 :          * @return binary                                                                                                      
     102                 :          */                                                                                                                    
     103                 :         protected function getRawTrackHeader() {                                                                               
     104               1 :             return $this->read(TrackHeader::LENGTH, true);                                                                     
     105                 :         }                                                                                                                      
     106                 :                                                                                                                                
     107                 :         /**                                                                                                                    
     108                 :          * Parses the given track header                                                                                       
     109                 :          *                                                                                                                     
     110                 :          * @since 1.0                                                                                                          
     111                 :          * @uses  TrackHeader::LENGTH                                                                                          
     112                 :          * @uses  Util::unpack()                                                                                               
     113                 :          *                                                                                                                     
     114                 :          * @param  binary $header                                                                                              
     115                 :          * @throws InvalidArgumentException                                                                                    
     116                 :          * @throws {@link ParseException} if the header is invalid                                                             
     117                 :          * @return TrackHeader                                                                                                 
     118                 :          */                                                                                                                    
     119                 :         public function parseTrackHeader($header) {                                                                            
     120               3 :             if (strlen($header) !== TrackHeader::LENGTH) {                                                                     
     121               1 :                 throw new \InvalidArgumentException('Track header must be ' . \Midi\TrackHeader::LENGTH . ' bytes');           
     122                 :             }                                                                                                                  
     123                 :                                                                                                                                
     124               2 :             $id   = Util::unpack(substr($header, 0, 4));                                                                       
     125               2 :             $size = array_reverse(Util::unpack(substr($header, 4)));                                                           
     126                 :                                                                                                                                
     127               2 :             if ($id !== array(0x4D, 0x54, 0x72, 0x6B)) {                                                                       
     128               1 :                 throw new ParseException('Invalid track header, expected [4D 54 72 6B]');                                      
     129                 :             }                                                                                                                  
     130                 :                                                                                                                                
     131               1 :             $shift = 0;                                                                                                        
     132               1 :             $trackSize = 0;                                                                                                    
     133               1 :             foreach ($size as $byte) {                                                                                         
     134               1 :                 $trackSize |= ($byte << $shift);                                                                               
     135               1 :                 $shift += 8;                                                                                                   
     136               1 :             }                                                                                                                  
     137                 :                                                                                                                                
     138               1 :             return new TrackHeader($trackSize);                                                                                
     139                 :         }                                                                                                                      
     140                 :                                                                                                                                
     141                 :         /**                                                                                                                    
     142                 :          * @since 1.0                                                                                                          
     143                 :          * @uses  EventParser::setFile()                                                                                       
     144                 :          * @uses  DeltaParser::setFile()                                                                                       
     145                 :          */                                                                                                                    
     146                 :         protected function afterSetFile() {                                                                                    
     147               1 :             $this->eventParser->setFile($this->file);                                                                          
     148               1 :             $this->deltaParser->setFile($this->file);                                                                          
     149               1 :         }                                                                                                                      
     150                 :                                                                                                                                
     151                 :         /**                                                                                                                    
     152                 :          * @since 1.0                                                                                                          
     153                 :          * @uses  parseTrackHeader()                                                                                           
     154                 :          * @uses  getRawTrackHeader()                                                                                          
     155                 :          * @uses  TrackHeader::getSize()                                                                                       
     156                 :          * @uses  DeltaParser::parse()                                                                                         
     157                 :          * @uses  Chunk::getLength()                                                                                           
     158                 :          * @uses  EventParser::parse()                                                                                         
     159                 :          * @uses  checkTrackLength()                                                                                           
     160                 :          *                                                                                                                     
     161                 :          * @throws {@link ParseException}                                                                                      
     162                 :          * @throws {@link StateException}                                                                                      
     163                 :          * @return Chunk                                                                                                       
     164                 :          */                                                                                                                    
     165                 :         public function parse() {                                                                                              
     166               7 :             $state = $this->getState();                                                                                        
     167               7 :             $chunk = null;                                                                                                     
     168                 :             switch ($state) {                                                                                                  
     169               7 :                 case ParseState::TRACK_HEADER:                                                                                 
     170               1 :                     $chunk                     = $this->parseTrackHeader($this->getRawTrackHeader());                          
     171               1 :                     $this->parsedTrackLength   = 0;                                                                            
     172               1 :                     $this->expectedTrackLength = $chunk->getSize();                                                            
     173               1 :                     $this->setState(ParseState::DELTA);                                                                        
     174               1 :                     break;                                                                                                     
     175               6 :                 case ParseState::DELTA:                                                                                        
     176               1 :                     $chunk = $this->deltaParser->parse();                                                                      
     177               1 :                     $this->setState(ParseState::EVENT);                                                                        
     178               1 :                     $this->checkTrackLength($chunk->getLength());                                                              
     179               1 :                     break;                                                                                                     
     180               5 :                 case ParseState::EVENT:                                                                                        
     181               4 :                     $chunk = $this->eventParser->parse();                                                                      
     182               4 :                     $this->checkTrackLength($chunk->getLength());                                                              
     183               3 :                     if ($this->getParsedTrackLength() === $this->getExpectedTrackLength()) {                                   
     184               2 :                         if (!($chunk instanceof Event\EndOfTrackEvent)) {                                                      
     185               1 :                             throw new ParseException('Expected end of track');                                                 
     186                 :                         } else {                                                                                               
     187               1 :                             $this->setState(ParseState::TRACK_HEADER);                                                         
     188                 :                         }                                                                                                      
     189               1 :                     } else {                                                                                                   
     190               1 :                         $this->setState(ParseState::DELTA);                                                                    
     191                 :                     }                                                                                                          
     192               2 :                     break;                                                                                                     
     193               1 :                 default:                                                                                                       
     194               1 :                     throw new StateException('Invalid state: ' . $state);                                                      
     195               1 :             }                                                                                                                  
     196                 :                                                                                                                                
     197               4 :             return $chunk;                                                                                                     
     198                 :         }                                                                                                                      
     199                 :                                                                                                                                
     200                 :         /**                                                                                                                    
     201                 :          * Verifies that the track length does not exceed its                                                                  
     202                 :          * expected length                                                                                                     
     203                 :          *                                                                                                                     
     204                 :          * @since 1.0                                                                                                          
     205                 :          * @todo  The parsed track length increment shouldn't happen here                                                      
     206                 :          *                                                                                                                     
     207                 :          * @param  int $length The number of bytes to add to the parsed track bytes                                            
     208                 :          * @throws {@link ParseException} if the track length exceeds its expected length                                      
     209                 :          */                                                                                                                    
     210                 :         protected function checkTrackLength($length) {                                                                         
     211               2 :             $this->parsedTrackLength += $length;                                                                               
     212               2 :             $expectedLength = $this->getExpectedTrackLength();                                                                 
     213               2 :             $parsedLength = $this->getParsedTrackLength();                                                                     
     214               2 :             if ($parsedLength > $expectedLength) {                                                                             
     215               1 :                 throw new ParseException('Track data exceeds expected length (' . $parsedLength . '/' . $expectedLength . ')');
     216                 :             }                                                                                                                  
     217               1 :         }                                                                                                                      
     218                 :                                                                                                                                
     219                 :     }                                                                                                                          
     220                 :                                                                                                                                

Generated by PHPUnit 3.4.1 and Xdebug 2.0.5 using PHP 5.3.0 at Sun Oct 25 23:35:09 PDT 2009.