Example #1
0
 /**
  * Parses the SRR data and stores a list of valid blocks locally.
  *
  * @return  boolean  false if parsing fails
  */
 protected function analyze()
 {
     // Find the SRR MARKER block, or abort if none is found
     if (($startPos = $this->findMarker()) === false) {
         $this->error = 'Could not find Marker block, not a valid SRR file';
         return false;
     }
     // Start at the SRR MARKER block
     $this->seek($startPos);
     // Analyze all valid blocks
     while ($this->offset < $this->length) {
         try {
             // Get the next block header
             $block = $this->getNextBlock();
             // Block type: SRR MARKER
             if ($block['head_type'] == self::SRR_BLOCK_MARK) {
                 if ($block['head_flags'] & self::APP_NAME_PRESENT) {
                     $block += self::unpack('vapp_name_size', $this->read(2), false);
                     $block['app_name'] = $this->read($block['app_name_size']);
                     $this->client = $block['app_name'];
                 }
                 if ($block['head_flags'] > 1 || $this->offset != $block['next_offset']) {
                     $this->error = 'Could not find Marker block, not a valid SRR file';
                     return false;
                 }
                 // Block type: STORED FILE
             } elseif ($block['head_type'] == self::SRR_STORED_FILE) {
                 $block += self::unpack('vname_size', $this->read(2), false);
                 $block['file_name'] = $this->read($block['name_size']);
                 $block['file_data'] = $this->read(isset($block['add_size']) ? $block['add_size'] : 0);
                 // Block type: OSO HASH
             } elseif ($block['head_type'] == self::SRR_OSO_HASH) {
                 $block += self::unpack(self::FORMAT_SRR_OSO_HASH, $this->read(18));
                 $block['file_hash'] = strrev($block['file_hash']);
                 $block['file_size'] = self::int64($block['file_size'], $block['file_size_high']);
                 $block['file_name'] = $this->read($block['name_size']);
                 // Block type: SRR RAR FILE
             } elseif ($block['head_type'] == self::SRR_RAR_FILE) {
                 $block += self::unpack('vname_size', $this->read(2), false);
                 $block['file_name'] = $this->read($block['name_size']);
                 // Default to RAR block processing
             } else {
                 parent::processBlock($block);
             }
             // Add current block to the list
             $this->blocks[] = $block;
             // Skip to the next block, if any
             if ($this->offset != $block['next_offset']) {
                 $this->seek($block['next_offset']);
             }
             // Sanity check
             if ($block['offset'] == $this->offset) {
                 $this->error = 'Parsing seems to be stuck';
                 $this->close();
                 return false;
             }
             // No more readable data, or read error
         } catch (Exception $e) {
             if ($this->error) {
                 $this->close();
                 return false;
             }
             break;
         }
     }
     // Analysis was successful
     return true;
 }