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

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

Issue 374010: Implement Windows FTP directory listing parser. (Closed)
Patch Set: fixes Created 11 years, 1 month 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "net/ftp/ftp_directory_listing_parsers.h" 5 #include "net/ftp/ftp_directory_listing_parsers.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 8
9 namespace { 9 namespace {
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 base::Time::Exploded now_exploded; 81 base::Time::Exploded now_exploded;
82 base::Time::Now().LocalExplode(&now_exploded); 82 base::Time::Now().LocalExplode(&now_exploded);
83 time_exploded.year = now_exploded.year; 83 time_exploded.year = now_exploded.year;
84 } 84 }
85 85
86 // We don't know the time zone of the server, so just use local time. 86 // We don't know the time zone of the server, so just use local time.
87 *time = base::Time::FromLocalExploded(time_exploded); 87 *time = base::Time::FromLocalExploded(time_exploded);
88 return true; 88 return true;
89 } 89 }
90 90
91 bool WindowsDateListingToTime(const std::vector<string16>& columns,
92 base::Time* time) {
93 DCHECK_EQ(4U, columns.size());
94
95 base::Time::Exploded time_exploded = { 0 };
96
97 // Date should be in format MM-DD-YY[YY].
98 std::vector<string16> date_parts;
99 SplitString(columns[0], '-', &date_parts);
100 if (date_parts.size() != 3)
101 return false;
102 if (!StringToInt(date_parts[0], &time_exploded.month))
103 return false;
104 if (!StringToInt(date_parts[1], &time_exploded.day_of_month))
105 return false;
106 if (!StringToInt(date_parts[2], &time_exploded.year))
107 return false;
108 if (time_exploded.year < 0)
109 return false;
110 // If year has only two digits then assume that 00-79 is 2000-2079,
111 // and 80-99 is 1980-1999.
112 if (time_exploded.year < 80)
113 time_exploded.year += 2000;
114 else if (time_exploded.year < 100)
115 time_exploded.year += 1900;
116
117 // Time should be in format HH:MM(AM|PM)
118 if (columns[1].length() != 7)
119 return false;
120 std::vector<string16> time_parts;
121 SplitString(columns[1].substr(0, 5), ':', &time_parts);
122 if (time_parts.size() != 2)
123 return false;
124 if (!StringToInt(time_parts[0], &time_exploded.hour))
125 return false;
126 if (!StringToInt(time_parts[1], &time_exploded.minute))
127 return false;
128 string16 am_or_pm(columns[1].substr(5, 2));
129 if (EqualsASCII(am_or_pm, "PM"))
130 time_exploded.hour += 12;
131 else if (!EqualsASCII(am_or_pm, "AM"))
132 return false;
133
134 // We don't know the time zone of the server, so just use local time.
135 *time = base::Time::FromLocalExploded(time_exploded);
136 return true;
137 }
138
91 // Converts the filename component in listing to the filename we can display. 139 // Converts the filename component in listing to the filename we can display.
92 // Returns true on success. 140 // Returns true on success.
93 bool ParseVmsFilename(const string16& raw_filename, string16* parsed_filename, 141 bool ParseVmsFilename(const string16& raw_filename, string16* parsed_filename,
94 bool* is_directory) { 142 bool* is_directory) {
95 // On VMS, the files and directories are versioned. The version number is 143 // On VMS, the files and directories are versioned. The version number is
96 // separated from the file name by a semicolon. Example: ANNOUNCE.TXT;2. 144 // separated from the file name by a semicolon. Example: ANNOUNCE.TXT;2.
97 std::vector<string16> listing_parts; 145 std::vector<string16> listing_parts;
98 SplitString(raw_filename, ';', &listing_parts); 146 SplitString(raw_filename, ';', &listing_parts);
99 if (listing_parts.size() != 2) 147 if (listing_parts.size() != 2)
100 return false; 148 return false;
101 if (!IsStringNonNegativeInteger(listing_parts[1])) 149 if (!IsStringNonNegativeInteger(listing_parts[1]))
102 return false; 150 return false;
103 151
104 // Even directories have extensions in the listings. Don't display extensions 152 // Even directories have extensions in the listings. Don't display extensions
105 // for directories; it's awkward for non-VMS users. Also, VMS is 153 // for directories; it's awkward for non-VMS users. Also, VMS is
106 // case-insensitive, but generally uses uppercase characters. This may look 154 // case-insensitive, but generally uses uppercase characters. This may look
107 // awkward, so we convert them to lower case. 155 // awkward, so we convert them to lower case.
108 std::vector<string16> filename_parts; 156 std::vector<string16> filename_parts;
109 SplitString(listing_parts[0], '.', &filename_parts); 157 SplitString(listing_parts[0], '.', &filename_parts);
110 if (filename_parts.size() != 2) 158 if (filename_parts.size() != 2)
111 return false; 159 return false;
112 if (filename_parts[1] == ASCIIToUTF16("DIR")) { 160 if (EqualsASCII(filename_parts[1], "DIR")) {
113 *parsed_filename = StringToLowerASCII(filename_parts[0]); 161 *parsed_filename = StringToLowerASCII(filename_parts[0]);
114 *is_directory = true; 162 *is_directory = true;
115 } else { 163 } else {
116 *parsed_filename = StringToLowerASCII(listing_parts[0]); 164 *parsed_filename = StringToLowerASCII(listing_parts[0]);
117 *is_directory = false; 165 *is_directory = false;
118 } 166 }
119 return true; 167 return true;
120 } 168 }
121 169
122 bool ParseVmsFilesize(const string16& input, int64* size) { 170 bool ParseVmsFilesize(const string16& input, int64* size) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 // systems in Unix emulation mode add an empty line before the first listing 293 // systems in Unix emulation mode add an empty line before the first listing
246 // entry. 294 // entry.
247 if (line.empty() && !received_nonempty_line_) 295 if (line.empty() && !received_nonempty_line_)
248 return true; 296 return true;
249 received_nonempty_line_ = true; 297 received_nonempty_line_ = true;
250 298
251 std::vector<string16> columns; 299 std::vector<string16> columns;
252 SplitString(CollapseWhitespace(line, false), ' ', &columns); 300 SplitString(CollapseWhitespace(line, false), ' ', &columns);
253 if (columns.size() == 11) { 301 if (columns.size() == 11) {
254 // Check if it is a symlink. 302 // Check if it is a symlink.
255 if (columns[9] != ASCIIToUTF16("->")) 303 if (!EqualsASCII(columns[9], "->"))
256 return false; 304 return false;
257 305
258 // Drop the symlink target from columns, we don't use it. 306 // Drop the symlink target from columns, we don't use it.
259 columns.resize(9); 307 columns.resize(9);
260 } 308 }
261 309
262 if (columns.size() != 9) 310 if (columns.size() != 9)
263 return false; 311 return false;
264 312
265 if (!LooksLikeUnixPermissionsListing(columns[0])) 313 if (!LooksLikeUnixPermissionsListing(columns[0]))
(...skipping 30 matching lines...) Expand all
296 bool FtpLsDirectoryListingParser::EntryAvailable() const { 344 bool FtpLsDirectoryListingParser::EntryAvailable() const {
297 return !entries_.empty(); 345 return !entries_.empty();
298 } 346 }
299 347
300 FtpDirectoryListingEntry FtpLsDirectoryListingParser::PopEntry() { 348 FtpDirectoryListingEntry FtpLsDirectoryListingParser::PopEntry() {
301 FtpDirectoryListingEntry entry = entries_.front(); 349 FtpDirectoryListingEntry entry = entries_.front();
302 entries_.pop(); 350 entries_.pop();
303 return entry; 351 return entry;
304 } 352 }
305 353
354 FtpWindowsDirectoryListingParser::FtpWindowsDirectoryListingParser() {
355 }
356
357 bool FtpWindowsDirectoryListingParser::ConsumeLine(const string16& line) {
358 std::vector<string16> columns;
359 SplitString(CollapseWhitespace(line, false), ' ', &columns);
360 if (columns.size() != 4)
361 return false;
362
363 FtpDirectoryListingEntry entry;
364 entry.name = columns[3];
365
366 if (EqualsASCII(columns[2], "<DIR>")) {
367 entry.type = FtpDirectoryListingEntry::DIRECTORY;
368 entry.size = -1;
369 } else {
370 entry.type = FtpDirectoryListingEntry::FILE;
371 if (!StringToInt64(columns[2], &entry.size))
372 return false;
373 if (entry.size < 0)
374 return false;
375 }
376
377 if (!WindowsDateListingToTime(columns, &entry.last_modified))
378 return false;
379
380 entries_.push(entry);
381 return true;
382 }
383
384 bool FtpWindowsDirectoryListingParser::EntryAvailable() const {
385 return !entries_.empty();
386 }
387
388 FtpDirectoryListingEntry FtpWindowsDirectoryListingParser::PopEntry() {
389 FtpDirectoryListingEntry entry = entries_.front();
390 entries_.pop();
391 return entry;
392 }
393
306 FtpVmsDirectoryListingParser::FtpVmsDirectoryListingParser() 394 FtpVmsDirectoryListingParser::FtpVmsDirectoryListingParser()
307 : state_(STATE_INITIAL), 395 : state_(STATE_INITIAL),
308 last_is_directory_(false) { 396 last_is_directory_(false) {
309 } 397 }
310 398
311 bool FtpVmsDirectoryListingParser::ConsumeLine(const string16& line) { 399 bool FtpVmsDirectoryListingParser::ConsumeLine(const string16& line) {
312 switch (state_) { 400 switch (state_) {
313 case STATE_INITIAL: 401 case STATE_INITIAL:
314 DCHECK(last_filename_.empty()); 402 DCHECK(last_filename_.empty());
315 if (line.empty()) 403 if (line.empty())
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 if (entry.type != FtpDirectoryListingEntry::FILE) 513 if (entry.type != FtpDirectoryListingEntry::FILE)
426 entry.size = -1; 514 entry.size = -1;
427 if (!VmsDateListingToTime(columns, &entry.last_modified)) 515 if (!VmsDateListingToTime(columns, &entry.last_modified))
428 return false; 516 return false;
429 517
430 entries_.push(entry); 518 entries_.push(entry);
431 return true; 519 return true;
432 } 520 }
433 521
434 } // namespace net 522 } // namespace net
OLDNEW
« no previous file with comments | « net/ftp/ftp_directory_listing_parsers.h ('k') | net/ftp/ftp_directory_listing_parsers_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698