PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Pdf/Element/String.php

https://bitbucket.org/gkawka/zend-framework
PHP | 263 lines | 129 code | 42 blank | 92 comment | 11 complexity | 82fd8b9cd874f227f718a342272df46c MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Pdf
  17. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: String.php 24593 2012-01-05 20:35:02Z matthew $
  20. */
  21. /** Zend_Pdf_Element */
  22. require_once 'Zend/Pdf/Element.php';
  23. /**
  24. * PDF file 'string' element implementation
  25. *
  26. * @category Zend
  27. * @package Zend_Pdf
  28. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Pdf_Element_String extends Zend_Pdf_Element
  32. {
  33. /**
  34. * Object value
  35. *
  36. * @var string
  37. */
  38. public $value;
  39. /**
  40. * Object constructor
  41. *
  42. * @param string $val
  43. */
  44. public function __construct($val)
  45. {
  46. $this->value = (string)$val;
  47. }
  48. /**
  49. * Return type of the element.
  50. *
  51. * @return integer
  52. */
  53. public function getType()
  54. {
  55. return Zend_Pdf_Element::TYPE_STRING;
  56. }
  57. /**
  58. * Return object as string
  59. *
  60. * @param Zend_Pdf_Factory $factory
  61. * @return string
  62. */
  63. public function toString($factory = null)
  64. {
  65. return '(' . self::escape((string)$this->value) . ')';
  66. }
  67. /**
  68. * Escape string according to the PDF rules
  69. *
  70. * @param string $str
  71. * @return string
  72. */
  73. public static function escape($str)
  74. {
  75. $outEntries = array();
  76. foreach (str_split($str, 128) as $chunk) {
  77. // Collect sequence of unescaped characters
  78. $offset = strcspn($chunk, "\n\r\t\x08\x0C()\\");
  79. $chunkOut = substr($chunk, 0, $offset);
  80. while ($offset < strlen($chunk)) {
  81. $nextCode = ord($chunk[$offset++]);
  82. switch ($nextCode) {
  83. // "\n" - line feed (LF)
  84. case 10:
  85. $chunkOut .= '\\n';
  86. break;
  87. // "\r" - carriage return (CR)
  88. case 13:
  89. $chunkOut .= '\\r';
  90. break;
  91. // "\t" - horizontal tab (HT)
  92. case 9:
  93. $chunkOut .= '\\t';
  94. break;
  95. // "\b" - backspace (BS)
  96. case 8:
  97. $chunkOut .= '\\b';
  98. break;
  99. // "\f" - form feed (FF)
  100. case 12:
  101. $chunkOut .= '\\f';
  102. break;
  103. // '(' - left paranthesis
  104. case 40:
  105. $chunkOut .= '\\(';
  106. break;
  107. // ')' - right paranthesis
  108. case 41:
  109. $chunkOut .= '\\)';
  110. break;
  111. // '\' - backslash
  112. case 92:
  113. $chunkOut .= '\\\\';
  114. break;
  115. default:
  116. // This code is never executed extually
  117. //
  118. // Don't use non-ASCII characters escaping
  119. // if ($nextCode >= 32 && $nextCode <= 126 ) {
  120. // // Visible ASCII symbol
  121. // $chunkEntries[] = chr($nextCode);
  122. // } else {
  123. // $chunkEntries[] = sprintf('\\%03o', $nextCode);
  124. // }
  125. break;
  126. }
  127. // Collect sequence of unescaped characters
  128. $start = $offset;
  129. $offset += strcspn($chunk, "\n\r\t\x08\x0C()\\", $offset);
  130. $chunkOut .= substr($chunk, $start, $offset - $start);
  131. }
  132. $outEntries[] = $chunkOut;
  133. }
  134. return implode("\\\n", $outEntries);
  135. }
  136. /**
  137. * Unescape string according to the PDF rules
  138. *
  139. * @param string $str
  140. * @return string
  141. */
  142. public static function unescape($str)
  143. {
  144. $outEntries = array();
  145. $offset = 0;
  146. while ($offset < strlen($str)) {
  147. // Searche for the next escaped character/sequence
  148. $escapeCharOffset = strpos($str, '\\', $offset);
  149. if ($escapeCharOffset === false || $escapeCharOffset == strlen($str) - 1) {
  150. // There are no escaped characters or '\' char has came at the end of string
  151. $outEntries[] = substr($str, $offset);
  152. break;
  153. } else {
  154. // Collect unescaped characters sequence
  155. $outEntries[] = substr($str, $offset, $escapeCharOffset - $offset);
  156. // Go to the escaped character
  157. $offset = $escapeCharOffset + 1;
  158. switch ($str[$offset]) {
  159. // '\\n' - line feed (LF)
  160. case 'n':
  161. $outEntries[] = "\n";
  162. break;
  163. // '\\r' - carriage return (CR)
  164. case 'r':
  165. $outEntries[] = "\r";
  166. break;
  167. // '\\t' - horizontal tab (HT)
  168. case 't':
  169. $outEntries[] = "\t";
  170. break;
  171. // '\\b' - backspace (BS)
  172. case 'b':
  173. $outEntries[] = "\x08";
  174. break;
  175. // '\\f' - form feed (FF)
  176. case 'f':
  177. $outEntries[] = "\x0C";
  178. break;
  179. // '\\(' - left paranthesis
  180. case '(':
  181. $outEntries[] = '(';
  182. break;
  183. // '\\)' - right paranthesis
  184. case ')':
  185. $outEntries[] = ')';
  186. break;
  187. // '\\\\' - backslash
  188. case '\\':
  189. $outEntries[] = '\\';
  190. break;
  191. // "\\\n" or "\\\n\r"
  192. case "\n":
  193. // skip new line symbol
  194. if ($str[$offset + 1] == "\r") {
  195. $offset++;
  196. }
  197. break;
  198. default:
  199. if (strpos('0123456789', $str[$offset]) !== false) {
  200. // Character in octal representation
  201. // '\\xxx'
  202. $nextCode = '0' . $str[$offset];
  203. if (strpos('0123456789', $str[$offset + 1]) !== false) {
  204. $nextCode .= $str[++$offset];
  205. if (strpos('0123456789', $str[$offset + 1]) !== false) {
  206. $nextCode .= $str[++$offset];
  207. }
  208. }
  209. $outEntries[] = chr(octdec($nextCode));
  210. } else {
  211. $outEntries[] = $str[$offset];
  212. }
  213. break;
  214. }
  215. $offset++;
  216. }
  217. }
  218. return implode($outEntries);
  219. }
  220. }