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 |