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