QpContentEncoder.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * Handles Quoted Printable (QP) Transfer Encoding in Swift Mailer.
  11. *
  12. * @author Chris Corbyn
  13. */
  14. class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder implements Swift_Mime_ContentEncoder
  15. {
  16. protected $dotEscape;
  17. /**
  18. * Creates a new QpContentEncoder for the given CharacterStream.
  19. *
  20. * @param Swift_CharacterStream $charStream to use for reading characters
  21. * @param Swift_StreamFilter $filter if canonicalization should occur
  22. * @param bool $dotEscape if dot stuffing workaround must be enabled
  23. */
  24. public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null, $dotEscape = false)
  25. {
  26. $this->dotEscape = $dotEscape;
  27. parent::__construct($charStream, $filter);
  28. }
  29. public function __sleep()
  30. {
  31. return ['charStream', 'filter', 'dotEscape'];
  32. }
  33. protected function getSafeMapShareId()
  34. {
  35. return static::class.($this->dotEscape ? '.dotEscape' : '');
  36. }
  37. protected function initSafeMap()
  38. {
  39. parent::initSafeMap();
  40. if ($this->dotEscape) {
  41. /* Encode . as =2e for buggy remote servers */
  42. unset($this->safeMap[0x2e]);
  43. }
  44. }
  45. /**
  46. * Encode stream $in to stream $out.
  47. *
  48. * QP encoded strings have a maximum line length of 76 characters.
  49. * If the first line needs to be shorter, indicate the difference with
  50. * $firstLineOffset.
  51. *
  52. * @param Swift_OutputByteStream $os output stream
  53. * @param Swift_InputByteStream $is input stream
  54. * @param int $firstLineOffset
  55. * @param int $maxLineLength
  56. */
  57. public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
  58. {
  59. if ($maxLineLength > 76 || $maxLineLength <= 0) {
  60. $maxLineLength = 76;
  61. }
  62. $thisLineLength = $maxLineLength - $firstLineOffset;
  63. $this->charStream->flushContents();
  64. $this->charStream->importByteStream($os);
  65. $currentLine = '';
  66. $prepend = '';
  67. $size = $lineLen = 0;
  68. while (false !== $bytes = $this->nextSequence()) {
  69. // If we're filtering the input
  70. if (isset($this->filter)) {
  71. // If we can't filter because we need more bytes
  72. while ($this->filter->shouldBuffer($bytes)) {
  73. // Then collect bytes into the buffer
  74. if (false === $moreBytes = $this->nextSequence(1)) {
  75. break;
  76. }
  77. foreach ($moreBytes as $b) {
  78. $bytes[] = $b;
  79. }
  80. }
  81. // And filter them
  82. $bytes = $this->filter->filter($bytes);
  83. }
  84. $enc = $this->encodeByteSequence($bytes, $size);
  85. $i = strpos($enc, '=0D=0A');
  86. $newLineLength = $lineLen + (false === $i ? $size : $i);
  87. if ($currentLine && $newLineLength >= $thisLineLength) {
  88. $is->write($prepend.$this->standardize($currentLine));
  89. $currentLine = '';
  90. $prepend = "=\r\n";
  91. $thisLineLength = $maxLineLength;
  92. $lineLen = 0;
  93. }
  94. $currentLine .= $enc;
  95. if (false === $i) {
  96. $lineLen += $size;
  97. } else {
  98. // 6 is the length of '=0D=0A'.
  99. $lineLen = $size - strrpos($enc, '=0D=0A') - 6;
  100. }
  101. }
  102. if (\strlen($currentLine)) {
  103. $is->write($prepend.$this->standardize($currentLine));
  104. }
  105. }
  106. /**
  107. * Get the name of this encoding scheme.
  108. * Returns the string 'quoted-printable'.
  109. *
  110. * @return string
  111. */
  112. public function getName()
  113. {
  114. return 'quoted-printable';
  115. }
  116. }