Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/net/quoted_printable.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 | |
| 9 namespace { | |
| 10 | |
| 11 const int kMaxCharPerLine = 76; | |
| 12 const char* const kEOL = "\r\n"; | |
| 13 | |
| 14 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.
| |
| 15 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | |
| 16 }; | |
| 17 | |
| 18 // Returns the value of |c| as it reads in hexa, -1 if |c| is not a valid hexa | |
| 19 // char. | |
| 20 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.
| |
| 21 if (c >= 48 && c <=57) // '0' to '9'. | |
| 22 return c - 48; | |
| 23 | |
| 24 if (c >= 65 && c <= 70) // 'A' to 'F'. | |
| 25 return c - 65 + 10; | |
| 26 | |
| 27 if (c >= 97 && c <= 102) // 'a' to 'f'. | |
| 28 return c - 97 + 10; | |
| 29 | |
| 30 return -1; | |
| 31 } | |
| 32 | |
| 33 } // namespace | |
| 34 | |
| 35 namespace chrome_browser_net { | |
| 36 | |
| 37 void QuotedPrintableEncode(const std::string& input, std::string* output) { | |
| 38 // The number of characters in the current line. | |
| 39 int char_count = 0; | |
| 40 for (std::string::const_iterator iter = input.begin(); | |
| 41 iter!= input.end(); ++iter) { | |
|
brettw
2011/02/28 17:33:14
Space before the !
Jay Civelli
2011/02/28 19:25:53
Done.
| |
| 42 bool last_char = (iter + 1 == input.end()); | |
| 43 char c = *iter; | |
| 44 // Whether this character can be inserted without encoding. | |
| 45 bool as_is = false; | |
| 46 // All printable ASCII characters can be included as is (but for =). | |
| 47 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.
| |
| 48 as_is = true; | |
| 49 } | |
| 50 | |
| 51 // Space and tab characters can be included as is if they don't appear at | |
| 52 // the end of a line or at then end of the input. | |
| 53 if (!as_is && (c == 9 || c == 32) && !last_char && | |
| 54 !IsEOL(iter + 1, input)) { | |
| 55 as_is = true; | |
| 56 } | |
| 57 | |
| 58 // End of line should be converted to CR-LF sequences. | |
| 59 if (!last_char) { | |
| 60 int eol_len = IsEOL(iter, input); | |
| 61 if (eol_len > 0) { | |
| 62 output->append(kEOL); | |
| 63 char_count = 0; | |
| 64 iter += (eol_len - 1); // -1 because we'll ++ in the for() above. | |
| 65 continue; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 // Insert a soft line break if necessary. | |
| 70 int min_chars_needed = as_is ? kMaxCharPerLine - 2 : kMaxCharPerLine - 4; | |
| 71 if (!last_char && char_count > min_chars_needed) { | |
| 72 output->append("="); | |
| 73 output->append(kEOL); | |
| 74 char_count = 0; | |
| 75 } | |
| 76 | |
| 77 // Finally, insert the actual character(s). | |
| 78 if (as_is) { | |
| 79 output->append(1, c); | |
| 80 char_count++; | |
| 81 } else { | |
| 82 output->append("="); | |
| 83 output->append(1, kHexTable[static_cast<int>((c >> 4) & 0xF)]); | |
| 84 output->append(1, kHexTable[static_cast<int>(c & 0x0F)]); | |
| 85 char_count += 3; | |
| 86 } | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 bool QuotedPrintableDecode(const std::string& input, std::string* output) { | |
| 91 bool success = true; | |
| 92 for (std::string::const_iterator iter = input.begin(); | |
| 93 iter!= input.end(); ++iter) { | |
| 94 char c = *iter; | |
| 95 if (c != '=') { | |
| 96 output->append(1, c); | |
| 97 continue; | |
| 98 } | |
| 99 if (input.end() - iter < 3) { | |
| 100 LOG(ERROR) << "unfinished = sequence in input string."; | |
| 101 success = false; | |
| 102 output->append(1, c); | |
| 103 continue; | |
| 104 } | |
| 105 char c2 = *(++iter); | |
| 106 char c3 = *(++iter); | |
| 107 if (c2 == 13 && c3 == 10) { | |
| 108 // Soft line break, ignored. | |
| 109 continue; | |
| 110 } | |
| 111 | |
| 112 int i1 = HexASCIICharToInt(c2); | |
| 113 int i2 = HexASCIICharToInt(c3); | |
| 114 if (i1 == -1 || i2 == -1) { | |
| 115 LOG(ERROR) << "invalid = sequence, = followed by non hexa digit " << | |
| 116 "chars: " << c2 << " " << c3; | |
| 117 success = false; | |
| 118 // Just insert the chars as is. | |
| 119 output->append("="); | |
| 120 output->append(1, c2); | |
| 121 output->append(1, c3); | |
| 122 continue; | |
| 123 } | |
| 124 | |
| 125 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.
| |
| 126 output->append(1, r); | |
| 127 } | |
| 128 return success; | |
| 129 } | |
| 130 | |
| 131 int IsEOL(const std::string::const_iterator& iter, const std::string& input) { | |
| 132 if (*iter == 10) | |
| 133 return 1; // Single LF. | |
| 134 | |
| 135 if (*iter == 13) { | |
| 136 if ((iter + 1) == input.end() || *(iter + 1) != 10) | |
| 137 return 1; // Single CR (Commodore and Old Macs). | |
| 138 return 2; // CR-LF. | |
| 139 } | |
| 140 | |
| 141 return 0; | |
| 142 } | |
| 143 | |
| 144 } // chrome_browser_net | |
| OLD | NEW |