Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: net/ftp/ftp_util.cc

Issue 6697021: FTP: use ICU to parse month abbreviations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed the comments Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/ftp/ftp_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « net/ftp/ftp_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698