See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 3 /** 4 * This file is part of FPDI 5 * 6 * @package setasign\Fpdi 7 * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com) 8 * @license http://opensource.org/licenses/mit-license The MIT License 9 */ 10 11 namespace setasign\Fpdi\PdfParser; 12 13 /** 14 * A tokenizer class. 15 */ 16 class Tokenizer 17 { 18 /** 19 * @var StreamReader 20 */ 21 protected $streamReader; 22 23 /** 24 * A token stack. 25 * 26 * @var string[] 27 */ 28 protected $stack = []; 29 30 /** 31 * Tokenizer constructor. 32 * 33 * @param StreamReader $streamReader 34 */ 35 public function __construct(StreamReader $streamReader) 36 { 37 $this->streamReader = $streamReader; 38 } 39 40 /** 41 * Get the stream reader instance. 42 * 43 * @return StreamReader 44 */ 45 public function getStreamReader() 46 { 47 return $this->streamReader; 48 } 49 50 /** 51 * Clear the token stack. 52 */ 53 public function clearStack() 54 { 55 $this->stack = []; 56 } 57 58 /** 59 * Push a token onto the stack. 60 * 61 * @param string $token 62 */ 63 public function pushStack($token) 64 { 65 $this->stack[] = $token; 66 } 67 68 /** 69 * Get next token. 70 * 71 * @return bool|string 72 */ 73 public function getNextToken() 74 { 75 $token = \array_pop($this->stack); 76 if ($token !== null) { 77 return $token; 78 } 79 80 if (($byte = $this->streamReader->readByte()) === false) { 81 return false; 82 } 83 84 if (\in_array($byte, ["\x20", "\x0A", "\x0D", "\x0C", "\x09", "\x00"], true)) { 85 if ($this->leapWhiteSpaces() === false) { 86 return false; 87 } 88 $byte = $this->streamReader->readByte(); 89 } 90 91 switch ($byte) { 92 case '/': 93 case '[': 94 case ']': 95 case '(': 96 case ')': 97 case '{': 98 case '}': 99 case '<': 100 case '>': 101 return $byte; 102 case '%': 103 $this->streamReader->readLine(); 104 return $this->getNextToken(); 105 } 106 107 /* This way is faster than checking single bytes. 108 */ 109 $bufferOffset = $this->streamReader->getOffset(); 110 do { 111 $lastBuffer = $this->streamReader->getBuffer(false); 112 $pos = \strcspn( 113 $lastBuffer, 114 "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%", 115 $bufferOffset 116 ); 117 } while ( 118 // Break the loop if a delimiter or white space char is matched 119 // in the current buffer or increase the buffers length 120 $lastBuffer !== false && 121 ( 122 $bufferOffset + $pos === \strlen($lastBuffer) && 123 $this->streamReader->increaseLength() 124 ) 125 ); 126 127 $result = \substr($lastBuffer, $bufferOffset - 1, $pos + 1); 128 $this->streamReader->setOffset($bufferOffset + $pos); 129 130 return $result; 131 } 132 133 /** 134 * Leap white spaces. 135 * 136 * @return boolean 137 */ 138 public function leapWhiteSpaces() 139 { 140 do { 141 if (!$this->streamReader->ensureContent()) { 142 return false; 143 } 144 145 $buffer = $this->streamReader->getBuffer(false); 146 $matches = \strspn($buffer, "\x20\x0A\x0C\x0D\x09\x00", $this->streamReader->getOffset()); 147 if ($matches > 0) { 148 $this->streamReader->addOffset($matches); 149 } 150 } while ($this->streamReader->getOffset() >= $this->streamReader->getBufferLength()); 151 152 return true; 153 } 154 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body