| Index: net/ftp/ftp_directory_listing_parser_windows.cc
|
| diff --git a/net/ftp/ftp_directory_listing_parser_windows.cc b/net/ftp/ftp_directory_listing_parser_windows.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3f2818ee54955cd8aff071f4b875ee7878c42476
|
| --- /dev/null
|
| +++ b/net/ftp/ftp_directory_listing_parser_windows.cc
|
| @@ -0,0 +1,109 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
|
| +// source code is governed by a BSD-style license that can be found in the
|
| +// LICENSE file.
|
| +
|
| +#include "net/ftp/ftp_directory_listing_parser_windows.h"
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/string_util.h"
|
| +
|
| +namespace {
|
| +
|
| +bool WindowsDateListingToTime(const std::vector<string16>& columns,
|
| + base::Time* time) {
|
| + DCHECK_EQ(4U, columns.size());
|
| +
|
| + base::Time::Exploded time_exploded = { 0 };
|
| +
|
| + // Date should be in format MM-DD-YY[YY].
|
| + std::vector<string16> date_parts;
|
| + SplitString(columns[0], '-', &date_parts);
|
| + if (date_parts.size() != 3)
|
| + return false;
|
| + if (!StringToInt(date_parts[0], &time_exploded.month))
|
| + return false;
|
| + if (!StringToInt(date_parts[1], &time_exploded.day_of_month))
|
| + return false;
|
| + if (!StringToInt(date_parts[2], &time_exploded.year))
|
| + return false;
|
| + if (time_exploded.year < 0)
|
| + return false;
|
| + // If year has only two digits then assume that 00-79 is 2000-2079,
|
| + // and 80-99 is 1980-1999.
|
| + if (time_exploded.year < 80)
|
| + time_exploded.year += 2000;
|
| + else if (time_exploded.year < 100)
|
| + time_exploded.year += 1900;
|
| +
|
| + // Time should be in format HH:MM(AM|PM)
|
| + if (columns[1].length() != 7)
|
| + return false;
|
| + std::vector<string16> time_parts;
|
| + SplitString(columns[1].substr(0, 5), ':', &time_parts);
|
| + if (time_parts.size() != 2)
|
| + return false;
|
| + if (!StringToInt(time_parts[0], &time_exploded.hour))
|
| + return false;
|
| + if (!StringToInt(time_parts[1], &time_exploded.minute))
|
| + return false;
|
| + string16 am_or_pm(columns[1].substr(5, 2));
|
| + if (EqualsASCII(am_or_pm, "PM"))
|
| + time_exploded.hour += 12;
|
| + else if (!EqualsASCII(am_or_pm, "AM"))
|
| + return false;
|
| +
|
| + // We don't know the time zone of the server, so just use local time.
|
| + *time = base::Time::FromLocalExploded(time_exploded);
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace net {
|
| +
|
| +FtpDirectoryListingParserWindows::FtpDirectoryListingParserWindows() {
|
| +}
|
| +
|
| +bool FtpDirectoryListingParserWindows::ConsumeLine(const string16& line) {
|
| + std::vector<string16> columns;
|
| + SplitString(CollapseWhitespace(line, false), ' ', &columns);
|
| + if (columns.size() != 4)
|
| + return false;
|
| +
|
| + FtpDirectoryListingEntry entry;
|
| + entry.name = columns[3];
|
| +
|
| + if (EqualsASCII(columns[2], "<DIR>")) {
|
| + entry.type = FtpDirectoryListingEntry::DIRECTORY;
|
| + entry.size = -1;
|
| + } else {
|
| + entry.type = FtpDirectoryListingEntry::FILE;
|
| + if (!StringToInt64(columns[2], &entry.size))
|
| + return false;
|
| + if (entry.size < 0)
|
| + return false;
|
| + }
|
| +
|
| + if (!WindowsDateListingToTime(columns, &entry.last_modified))
|
| + return false;
|
| +
|
| + entries_.push(entry);
|
| + return true;
|
| +}
|
| +
|
| +bool FtpDirectoryListingParserWindows::OnEndOfInput() {
|
| + return true;
|
| +}
|
| +
|
| +bool FtpDirectoryListingParserWindows::EntryAvailable() const {
|
| + return !entries_.empty();
|
| +}
|
| +
|
| +FtpDirectoryListingEntry FtpDirectoryListingParserWindows::PopEntry() {
|
| + FtpDirectoryListingEntry entry = entries_.front();
|
| + entries_.pop();
|
| + return entry;
|
| +}
|
| +
|
| +} // namespace net
|
|
|