Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/ftp/ftp_util.h" | 5 #include "net/ftp/ftp_util.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 11 #include "base/string_tokenizer.h" | 11 #include "base/string_tokenizer.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/time.h" | 13 #include "base/time.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "unicode/dtfmtsym.h" | |
| 15 | 16 |
| 16 // For examples of Unix<->VMS path conversions, see the unit test file. On VMS | 17 // For examples of Unix<->VMS path conversions, see the unit test file. On VMS |
| 17 // a path looks differently depending on whether it's a file or directory. | 18 // a path looks differently depending on whether it's a file or directory. |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 // static | 22 // static |
| 22 std::string FtpUtil::UnixFilePathToVMS(const std::string& unix_path) { | 23 std::string FtpUtil::UnixFilePathToVMS(const std::string& unix_path) { |
| 23 if (unix_path.empty()) | 24 if (unix_path.empty()) |
| 24 return std::string(); | 25 return std::string(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 std::replace(result.begin(), result.end(), ']', '/'); | 102 std::replace(result.begin(), result.end(), ']', '/'); |
| 102 | 103 |
| 103 // Make sure the result doesn't end with a slash. | 104 // Make sure the result doesn't end with a slash. |
| 104 if (result.length() && result[result.length() - 1] == '/') | 105 if (result.length() && result[result.length() - 1] == '/') |
| 105 result = result.substr(0, result.length() - 1); | 106 result = result.substr(0, result.length() - 1); |
| 106 | 107 |
| 107 return result; | 108 return result; |
| 108 } | 109 } |
| 109 | 110 |
| 110 // static | 111 // static |
| 111 bool FtpUtil::ThreeLetterMonthToNumber(const string16& text, int* number) { | 112 bool FtpUtil::AbbreviatedMonthToNumber(const string16& text, int* number) { |
| 112 const static char* months[] = { "jan", "feb", "mar", "apr", "may", "jun", | 113 icu::UnicodeString unicode_text(text.data(), text.size()); |
| 113 "jul", "aug", "sep", "oct", "nov", "dec" }; | |
| 114 | 114 |
| 115 for (size_t i = 0; i < arraysize(months); i++) { | 115 int32_t locales_count; |
| 116 if (LowerCaseEqualsASCII(text, months[i])) { | 116 const icu::Locale* locales = icu::Locale::getAvailableLocales(locales_count); |
|
jungshik at Google
2011/03/17 22:59:08
This will return a lot more entries than we have d
Paweł Hajdan Jr.
2011/03/18 09:04:41
Good idea, done.
| |
| 117 *number = i + 1; | 117 |
| 118 return true; | 118 // Some FTP servers localize the date listings. To guess the locale, |
| 119 // we loop over all available ones. | |
| 120 for (int32_t locale = 0; locale < locales_count; locale++) { | |
|
jungshik at Google
2011/03/17 22:59:08
Every time this function is called, we have to go
Paweł Hajdan Jr.
2011/03/18 09:04:41
I was considering some ways to make it faster, but
| |
| 121 UErrorCode status(U_ZERO_ERROR); | |
| 122 | |
| 123 icu::DateFormatSymbols format_symbols(locales[locale], status); | |
| 124 | |
| 125 // If we cannot get format symbols for some locale, it's not a fatal error. | |
| 126 // Just try another one. | |
| 127 if (U_FAILURE(status)) | |
| 128 continue; | |
| 129 | |
| 130 int32_t months_count; | |
| 131 const icu::UnicodeString* months = | |
| 132 format_symbols.getShortMonths(months_count); | |
| 133 | |
| 134 // Loop over all abbreviated month names in given locale. | |
| 135 // An alternative solution (to parse |text| in given locale) is more | |
| 136 // lenient, and may accept more than we want even with setLenient(false). | |
|
jungshik at Google
2011/03/17 22:59:08
Have you tried parsing a whole 'date string' inste
Paweł Hajdan Jr.
2011/03/18 09:04:41
Parsing a whole date string may accept more than w
| |
| 137 for (int32_t month = 0; month < months_count; month++) { | |
| 138 if (months[month].caseCompare(unicode_text, 0) == 0) { | |
| 139 *number = month + 1; | |
| 140 return true; | |
| 141 } | |
| 119 } | 142 } |
| 120 } | 143 } |
| 121 | 144 |
| 122 // Special cases for directory listings in German (other three-letter month | |
| 123 // abbreviations are the same as in English). Note that we don't need to do | |
| 124 // a case-insensitive compare here. Only "ls -l" style listings may use | |
| 125 // localized month names, and they will always start capitalized. Also, | |
| 126 // converting non-ASCII characters to lowercase would be more complicated. | |
| 127 if (text == UTF8ToUTF16("M\xc3\xa4r")) { | |
| 128 // The full month name is M-(a-umlaut)-rz (March), which is M-(a-umlaut)r | |
| 129 // when abbreviated. | |
| 130 *number = 3; | |
| 131 return true; | |
| 132 } | |
| 133 if (text == ASCIIToUTF16("Mai")) { | |
| 134 *number = 5; | |
| 135 return true; | |
| 136 } | |
| 137 if (text == ASCIIToUTF16("Okt")) { | |
| 138 *number = 10; | |
| 139 return true; | |
| 140 } | |
| 141 if (text == ASCIIToUTF16("Dez")) { | |
| 142 *number = 12; | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 return false; | 145 return false; |
| 147 } | 146 } |
| 148 | 147 |
| 149 // static | 148 // static |
| 150 bool FtpUtil::LsDateListingToTime(const string16& month, const string16& day, | 149 bool FtpUtil::LsDateListingToTime(const string16& month, const string16& day, |
| 151 const string16& rest, | 150 const string16& rest, |
| 152 const base::Time& current_time, | 151 const base::Time& current_time, |
| 153 base::Time* result) { | 152 base::Time* result) { |
|
jungshik at Google
2011/03/17 22:59:08
Hmm... Do all the ftp servers use 'day month year'
Paweł Hajdan Jr.
2011/03/18 09:04:41
They do. I consider that a part of the listing for
| |
| 154 base::Time::Exploded time_exploded = { 0 }; | 153 base::Time::Exploded time_exploded = { 0 }; |
| 155 | 154 |
| 156 if (!ThreeLetterMonthToNumber(month, &time_exploded.month)) | 155 if (!AbbreviatedMonthToNumber(month, &time_exploded.month)) |
| 157 return false; | 156 return false; |
| 158 | 157 |
| 159 if (!base::StringToInt(day, &time_exploded.day_of_month)) | 158 if (!base::StringToInt(day, &time_exploded.day_of_month)) |
| 160 return false; | 159 return false; |
| 161 | 160 |
| 162 if (!base::StringToInt(rest, &time_exploded.year)) { | 161 if (!base::StringToInt(rest, &time_exploded.year)) { |
| 163 // Maybe it's time. Does it look like time (HH:MM)? | 162 // Maybe it's time. Does it look like time (HH:MM)? |
| 164 if (rest.length() == 5 && rest[2] == ':') { | 163 if (rest.length() == 5 && rest[2] == ':') { |
| 165 if (!base::StringToInt(rest.begin(), | 164 if (!base::StringToInt(rest.begin(), |
| 166 rest.begin() + 2, | 165 rest.begin() + 2, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 while (pos < text.length() && !isspace(text[pos])) | 218 while (pos < text.length() && !isspace(text[pos])) |
| 220 pos++; | 219 pos++; |
| 221 } | 220 } |
| 222 | 221 |
| 223 string16 result(text.substr(pos)); | 222 string16 result(text.substr(pos)); |
| 224 TrimWhitespace(result, TRIM_ALL, &result); | 223 TrimWhitespace(result, TRIM_ALL, &result); |
| 225 return result; | 224 return result; |
| 226 } | 225 } |
| 227 | 226 |
| 228 } // namespace | 227 } // namespace |
| OLD | NEW |