Example #1
0
 /**
  *
  * @param array $tokens
  * @param int $indent
  * @return PdfDictionary
  * @throws PdfException
  */
 protected function parseDictionary(array $tokens, $indent = 0)
 {
     $dict = new PdfDictionary();
     $tokenCount = count($tokens);
     // start, stop, want_name_or_end, want_value
     $state = 'start';
     $pos = 0;
     $lastName = '';
     while ($pos < $tokenCount) {
         $token = $tokens[$pos];
         // Debug output
         //echo str_repeat(' ', $indent * 2) . $pos . ' ' .$token['name'] . "\n";
         switch ($token['name']) {
             case 'dictionary_start':
                 if ($state === 'start') {
                     $state = 'want_name_or_end';
                     $pos++;
                 } elseif ($state === 'want_name_or_end') {
                     throw new PdfException('<name> or <dictionary_end> expected, <dictionary_start> given');
                 } elseif ($state === 'want_value') {
                     // Sub-dictionary. Find next balanced dictionary_end
                     // and call this method recursively
                     $dictionaryIndent = 0;
                     $testPos = $pos + 1;
                     while ($testPos <= $tokenCount && ($tokens[$testPos]['name'] !== 'dictionary_end' || $dictionaryIndent > 0)) {
                         if ($tokens[$testPos]['name'] === 'dictonary_start') {
                             $dictionaryIndent++;
                         } elseif ($tokens[$testPos]['name'] === 'dictionary_end') {
                             $dictionaryIndent--;
                         }
                         $testPos++;
                     }
                     if ($testPos > $tokenCount) {
                         throw new PdfException('Unbalanced dictionaries');
                     }
                     $dict->add($lastName, $this->parseDictionary(array_slice($tokens, $pos, $testPos - $pos + 1), $indent + 1));
                     $lastName = '';
                     $state = 'want_name_or_end';
                     $pos = $testPos + 1;
                 }
                 break;
             case 'dictionary_end':
                 if ($state === 'want_name_or_end') {
                     $state = 'stop';
                     $pos++;
                 } else {
                     throw new PdfException('Unexpected <dictionary_end> at ' . $pos);
                 }
                 break;
             case 'array_start':
                 if ($state === 'want_value') {
                     // Find next balanced array_end and call parseArray()
                     $arrayIndent = 0;
                     $testPos = $pos + 1;
                     while ($testPos <= $tokenCount && ($tokens[$testPos]['name'] !== 'array_end' || $arrayIndent > 0)) {
                         if ($tokens[$testPos]['name'] === 'array_start') {
                             $arrayIndent++;
                         } elseif ($tokens[$testPos]['name'] === 'array_end') {
                             $arrayIndent--;
                         }
                         $testPos++;
                     }
                     if ($testPos > $tokenCount) {
                         throw new PdfException('Unbalanced arrays');
                     }
                     $dict->add($lastName, $this->parseArray(array_slice($tokens, $pos, $testPos - $pos + 1), $indent + 1));
                     $lastName = '';
                     $state = 'want_name_or_end';
                     $pos = $testPos + 1;
                 } else {
                     throw new PdfException('Unexpected <' . $token['name'] . '> at ' . $pos);
                 }
                 break;
             case 'name':
                 if ($state === 'want_name_or_end') {
                     $lastName = $token['content'];
                     $state = 'want_value';
                     $pos++;
                 } elseif ($state === 'want_value') {
                     $dict->add($lastName, $token['content']);
                     $lastName = '';
                     $state = 'want_name_or_end';
                     $pos++;
                 } else {
                     throw new PdfException('Unexpected <name> at ' . $pos);
                 }
                 break;
             case 'string':
             case 'boolean':
             case 'null':
                 if ($state === 'want_value') {
                     $dict->add($lastName, $token['content']);
                     $lastName = '';
                     $state = 'want_name_or_end';
                     $pos++;
                 } else {
                     throw new PdfException('Unexpected <' . $token['name'] . '> at ' . $pos);
                 }
                 break;
             case 'numeric':
                 if ($state === 'want_value') {
                     if ($pos + 2 < $tokenCount) {
                         if ($tokens[$pos + 1]['name'] === 'numeric' && $tokens[$pos + 2]['name'] === 'reference') {
                             $dict->add($lastName, new PdfReference((int) $tokens[$pos]['content'], (int) $tokens[$pos + 1]['content']));
                             $lastName = '';
                             $state = 'want_name_or_end';
                             $pos += 3;
                         } else {
                             $dict->add($lastName, $token['content']);
                             $lastName = '';
                             $state = 'want_name_or_end';
                             $pos++;
                         }
                     } else {
                         $dict->add($lastName, $token['content']);
                         $lastName = '';
                         $state = 'want_name_or_end';
                         $pos++;
                     }
                 } else {
                     throw new PdfException('Unexpected <' . $token['name'] . '> at ' . $pos);
                 }
                 break;
             case 'reference':
                 // References are handled by numeric
                 throw new PdfException('Unexpected <' . $token['name'] . '>');
                 break;
             default:
                 throw new PdfException('Unexpected <' . $token['name'] . '>. This is a serious bug');
                 break;
         }
     }
     if ($state !== 'stop') {
         throw new PdfException('Unexpected end of input');
     }
     return $dict;
 }
Example #2
0
 /**
  *
  * @return PdfDictionary
  */
 public function getDocumentCatalog()
 {
     return $this->resolveRef($this->trailer->get('/Root'));
 }