Chromium Code Reviews| Index: chrome/browser/net/quoted_printable.cc |
| diff --git a/chrome/browser/net/quoted_printable.cc b/chrome/browser/net/quoted_printable.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..217045d92824355183d4f15176b776ab7a93925b |
| --- /dev/null |
| +++ b/chrome/browser/net/quoted_printable.cc |
| @@ -0,0 +1,144 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/net/quoted_printable.h" |
| + |
| +#include "base/logging.h" |
| + |
| +namespace { |
| + |
| +const int kMaxCharPerLine = 76; |
| +const char* const kEOL = "\r\n"; |
| + |
| +const char kHexTable[] = { |
|
tfarina
2011/02/28 18:38:21
You can simplify this as:
const char kHexTable[]
Jay Civelli
2011/02/28 19:25:53
Done.
|
| + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' |
| +}; |
| + |
| +// Returns the value of |c| as it reads in hexa, -1 if |c| is not a valid hexa |
| +// char. |
| +int HexASCIICharToInt(char c) { |
|
brettw
2011/02/28 17:33:14
You should be able to use HexDigitToInt in string_
Jay Civelli
2011/02/28 19:25:53
Done.
|
| + if (c >= 48 && c <=57) // '0' to '9'. |
| + return c - 48; |
| + |
| + if (c >= 65 && c <= 70) // 'A' to 'F'. |
| + return c - 65 + 10; |
| + |
| + if (c >= 97 && c <= 102) // 'a' to 'f'. |
| + return c - 97 + 10; |
| + |
| + return -1; |
| +} |
| + |
| +} // namespace |
| + |
| +namespace chrome_browser_net { |
| + |
| +void QuotedPrintableEncode(const std::string& input, std::string* output) { |
| + // The number of characters in the current line. |
| + int char_count = 0; |
| + for (std::string::const_iterator iter = input.begin(); |
| + iter!= input.end(); ++iter) { |
|
brettw
2011/02/28 17:33:14
Space before the !
Jay Civelli
2011/02/28 19:25:53
Done.
|
| + bool last_char = (iter + 1 == input.end()); |
| + char c = *iter; |
| + // Whether this character can be inserted without encoding. |
| + bool as_is = false; |
| + // All printable ASCII characters can be included as is (but for =). |
| + if (c >= 33 && c <= 126 && c != 61) { |
|
tfarina
2011/02/28 18:32:44
Is there a reason for not using the letters instea
Jay Civelli
2011/02/28 19:25:53
Done.
|
| + as_is = true; |
| + } |
| + |
| + // Space and tab characters can be included as is if they don't appear at |
| + // the end of a line or at then end of the input. |
| + if (!as_is && (c == 9 || c == 32) && !last_char && |
| + !IsEOL(iter + 1, input)) { |
| + as_is = true; |
| + } |
| + |
| + // End of line should be converted to CR-LF sequences. |
| + if (!last_char) { |
| + int eol_len = IsEOL(iter, input); |
| + if (eol_len > 0) { |
| + output->append(kEOL); |
| + char_count = 0; |
| + iter += (eol_len - 1); // -1 because we'll ++ in the for() above. |
| + continue; |
| + } |
| + } |
| + |
| + // Insert a soft line break if necessary. |
| + int min_chars_needed = as_is ? kMaxCharPerLine - 2 : kMaxCharPerLine - 4; |
| + if (!last_char && char_count > min_chars_needed) { |
| + output->append("="); |
| + output->append(kEOL); |
| + char_count = 0; |
| + } |
| + |
| + // Finally, insert the actual character(s). |
| + if (as_is) { |
| + output->append(1, c); |
| + char_count++; |
| + } else { |
| + output->append("="); |
| + output->append(1, kHexTable[static_cast<int>((c >> 4) & 0xF)]); |
| + output->append(1, kHexTable[static_cast<int>(c & 0x0F)]); |
| + char_count += 3; |
| + } |
| + } |
| +} |
| + |
| +bool QuotedPrintableDecode(const std::string& input, std::string* output) { |
| + bool success = true; |
| + for (std::string::const_iterator iter = input.begin(); |
| + iter!= input.end(); ++iter) { |
| + char c = *iter; |
| + if (c != '=') { |
| + output->append(1, c); |
| + continue; |
| + } |
| + if (input.end() - iter < 3) { |
| + LOG(ERROR) << "unfinished = sequence in input string."; |
| + success = false; |
| + output->append(1, c); |
| + continue; |
| + } |
| + char c2 = *(++iter); |
| + char c3 = *(++iter); |
| + if (c2 == 13 && c3 == 10) { |
| + // Soft line break, ignored. |
| + continue; |
| + } |
| + |
| + int i1 = HexASCIICharToInt(c2); |
| + int i2 = HexASCIICharToInt(c3); |
| + if (i1 == -1 || i2 == -1) { |
| + LOG(ERROR) << "invalid = sequence, = followed by non hexa digit " << |
| + "chars: " << c2 << " " << c3; |
| + success = false; |
| + // Just insert the chars as is. |
| + output->append("="); |
| + output->append(1, c2); |
| + output->append(1, c3); |
| + continue; |
| + } |
| + |
| + char r = static_cast<char>((i1 << 4 & 0xF0) | (i2 &0x0F)); |
|
brettw
2011/02/28 17:33:14
Can you use an extra set of parens around the firs
Jay Civelli
2011/02/28 19:25:53
Done.
|
| + output->append(1, r); |
| + } |
| + return success; |
| +} |
| + |
| +int IsEOL(const std::string::const_iterator& iter, const std::string& input) { |
| + if (*iter == 10) |
| + return 1; // Single LF. |
| + |
| + if (*iter == 13) { |
| + if ((iter + 1) == input.end() || *(iter + 1) != 10) |
| + return 1; // Single CR (Commodore and Old Macs). |
| + return 2; // CR-LF. |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +} // chrome_browser_net |