Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
1 <?php 2 /** 3 * This file is part of FPDI 4 * 5 * @package setasign\Fpdi 6 * @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com) 7 * @license http://opensource.org/licenses/mit-license The MIT License 8 */ 9 10 namespace setasign\Fpdi\PdfParser\Type; 11 12 use setasign\Fpdi\PdfParser\StreamReader; 13 14 /** 15 * Class representing a PDF string object 16 * 17 * @package setasign\Fpdi\PdfParser\Type 18 */ 19 class PdfString extends PdfType 20 { 21 /** 22 * Parses a string object from the stream reader. 23 * 24 * @param StreamReader $streamReader 25 * @return self 26 */ 27 public static function parse(StreamReader $streamReader) 28 { 29 $pos = $startPos = $streamReader->getOffset(); 30 $openBrackets = 1; 31 do { 32 $buffer = $streamReader->getBuffer(false); 33 for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) { 34 switch ($buffer[$pos]) { 35 case '(': 36 $openBrackets++; 37 break; 38 case ')': 39 $openBrackets--; 40 break; 41 case '\\': 42 $pos++; 43 } 44 } 45 } while ($openBrackets !== 0 && $streamReader->increaseLength()); 46 47 $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1); 48 $streamReader->setOffset($pos); 49 50 $v = new self; 51 $v->value = $result; 52 53 return $v; 54 } 55 56 /** 57 * Helper method to create an instance. 58 * 59 * @param string $value The string needs to be escaped accordingly. 60 * @return self 61 */ 62 public static function create($value) 63 { 64 $v = new self; 65 $v->value = $value; 66 67 return $v; 68 } 69 70 /** 71 * Ensures that the passed value is a PdfString instance. 72 * 73 * @param mixed $string 74 * @return self 75 * @throws PdfTypeException 76 */ 77 public static function ensure($string) 78 { 79 return PdfType::ensureType(self::class, $string, 'String value expected.'); 80 } 81 82 /** 83 * Unescapes escaped sequences in a PDF string according to the PDF specification. 84 * 85 * @param string $s 86 * @return string 87 */ 88 public static function unescape($s) 89 { 90 $out = ''; 91 /** @noinspection ForeachInvariantsInspection */ 92 for ($count = 0, $n = \strlen($s); $count < $n; $count++) { 93 if ($s[$count] !== '\\') { 94 $out .= $s[$count]; 95 } else { 96 // A backslash at the end of the string - ignore it 97 if ($count === ($n - 1)) { 98 break; 99 } 100 101 switch ($s[++$count]) { 102 case ')': 103 case '(': 104 case '\\': 105 $out .= $s[$count]; 106 break; 107 108 case 'f': 109 $out .= "\x0C"; 110 break; 111 112 case 'b': 113 $out .= "\x08"; 114 break; 115 116 case 't': 117 $out .= "\x09"; 118 break; 119 120 case 'r': 121 $out .= "\x0D"; 122 break; 123 124 case 'n': 125 $out .= "\x0A"; 126 break; 127 128 case "\r": 129 if ($count !== $n - 1 && $s[$count + 1] === "\n") { 130 $count++; 131 } 132 break; 133 134 case "\n": 135 break; 136 137 default: 138 $actualChar = \ord($s[$count]); 139 // ascii 48 = number 0 140 // ascii 57 = number 9 141 if ($actualChar >= 48 && 142 $actualChar <= 57) { 143 $oct = '' . $s[$count]; 144 145 /** @noinspection NotOptimalIfConditionsInspection */ 146 if ($count + 1 < $n && 147 \ord($s[$count + 1]) >= 48 && 148 \ord($s[$count + 1]) <= 57 149 ) { 150 $count++; 151 $oct .= $s[$count]; 152 153 /** @noinspection NotOptimalIfConditionsInspection */ 154 if ($count + 1 < $n && 155 \ord($s[$count + 1]) >= 48 && 156 \ord($s[$count + 1]) <= 57 157 ) { 158 $oct .= $s[++$count]; 159 } 160 } 161 162 $out .= \chr(\octdec($oct)); 163 } else { 164 // If the character is not one of those defined, the backslash is ignored 165 $out .= $s[$count]; 166 } 167 } 168 } 169 } 170 return $out; 171 } 172 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body