note 96697 deleted from function.quoted-printable-encode by danbrown

From: Date: Fri, 12 Mar 2010 01:44:28 +0000
Subject: note 96697 deleted from function.quoted-printable-encode by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-166934@lists.php.net to get a copy of this message
Note Submitter: colin at fusionbox dot com ---- That's a pretty decent start, tzangerl, but I ran into an infinite loop ($i = $i - $whitesp_diff + $addtl_chars;, but I don't know why). Here's a very working, very tested version that had no trouble with long lines and utf8-encoded characters. <?php function quotedPrintable($input, $line_max = 72) { $eol = "\r\n"; // quoted-printable endings $linecontinue = '='. $eol; $linebreak = '=0D=0A='. $eol; $line_max = max(3, $line_max - strlen($linebreak)); $output = ""; // split lines on CR / LF $lines = preg_split('/\r\n|\r|\n/', $input); $lines2 = str_replace("\r\n", "\n", $input); $lines2 = str_replace("\r", "\n", $lines2); foreach($lines as $line) { //blank lines get special treatment; add a $linebreak and continue if ( $line == '' ) { $output .= $linebreak; continue; } // add a line break, unless this is the first line $output .= (strlen($output) ? $linebreak : ''); // encode what needs encoding $line_escaped = ''; foreach(str_split($line) as $c) { $dec = ord($c); if ( ($dec < 32 || $dec == 61 || $dec > 126) && $dec != 9) { $hex = strtoupper(dechex($dec)); if ( strlen($hex) == 1 ) $hex = '0'. $hex; $esc_c = '=' . $hex; } else { $esc_c = $c; } $line_escaped .= $esc_c; } // escape tab/space character that appears at the end of the line $line_escaped = preg_replace('/\t$/', '=09', $line_escaped); $line_escaped = preg_replace('/ $/', '=20', $line_escaped); $line = $line_escaped; // at this point, $line contains an escaped, but possibly long, line of the email. // we will separate $line into a shortened and too-long part. // $truncline will hold the shortened part, $line will continue to hold the // too-long part $truncline = TRUE; while ( $truncline ) { // using back-ref ops, we make sure that the last character is not // preceded by = or =[0-9A-Z] if ( preg_match('/^(.{1,'. $line_max .'}(?<!=)(?<!=[0-9A-Z]))(.*?)$/', $line, $match) ) { $truncline = $match[1]; $line = $match[2]; } else { $truncline = $line; $line = ''; } // if $line has something in it, we need a quoted-printable-continuation if ( $line ) { $output .= $truncline . $linecontinue; } else { // the $linebreak is added at the beginning of the loop $output .= $truncline; } } } return $output; } ?> There isn't enough room to include the tests, so I'll leave that “as an exercise”.

« previous php.notes (#166934) next »