This source file includes following definitions.
- TwoColumnDateListingToTime
- DetectColumnOffsetSizeAndModificationTime
- ParseFtpDirectoryListingLs
#include "net/ftp/ftp_directory_listing_parser_ls.h"
#include <vector>
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "net/ftp/ftp_directory_listing_parser.h"
#include "net/ftp/ftp_util.h"
namespace {
bool TwoColumnDateListingToTime(const base::string16& date,
const base::string16& time,
base::Time* result) {
base::Time::Exploded time_exploded = { 0 };
std::vector<base::string16> date_parts;
base::SplitString(date, '-', &date_parts);
if (date_parts.size() != 3)
return false;
if (!base::StringToInt(date_parts[0], &time_exploded.year))
return false;
if (!base::StringToInt(date_parts[1], &time_exploded.month))
return false;
if (!base::StringToInt(date_parts[2], &time_exploded.day_of_month))
return false;
if (time.length() != 5)
return false;
std::vector<base::string16> time_parts;
base::SplitString(time, ':', &time_parts);
if (time_parts.size() != 2)
return false;
if (!base::StringToInt(time_parts[0], &time_exploded.hour))
return false;
if (!base::StringToInt(time_parts[1], &time_exploded.minute))
return false;
if (!time_exploded.HasValidValues())
return false;
*result = base::Time::FromLocalExploded(time_exploded);
return true;
}
bool DetectColumnOffsetSizeAndModificationTime(
const std::vector<base::string16>& columns,
const base::Time& current_time,
size_t* offset,
base::string16* size,
base::Time* modification_time) {
for (size_t i = 5U; i < columns.size(); i++) {
if (net::FtpUtil::LsDateListingToTime(columns[i - 2],
columns[i - 1],
columns[i],
current_time,
modification_time)) {
*size = columns[i - 3];
*offset = i;
return true;
}
}
for (size_t i = 5U; i < columns.size(); i++) {
if (net::FtpUtil::LsDateListingToTime(columns[i - 1],
columns[i - 2],
columns[i],
current_time,
modification_time)) {
*size = columns[i - 3];
*offset = i;
return true;
}
}
for (size_t i = 5U; i < columns.size(); i++) {
if (TwoColumnDateListingToTime(columns[i - 1],
columns[i],
modification_time)) {
*size = columns[i - 2];
*offset = i;
return true;
}
}
return false;
}
}
namespace net {
bool ParseFtpDirectoryListingLs(
const std::vector<base::string16>& lines,
const base::Time& current_time,
std::vector<FtpDirectoryListingEntry>* entries) {
bool received_total_line = false;
for (size_t i = 0; i < lines.size(); i++) {
if (lines[i].empty())
continue;
std::vector<base::string16> columns;
base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns);
if (columns.size() == 2 && !received_total_line) {
received_total_line = true;
int64 total_number;
if (!base::StringToInt64(columns[1], &total_number))
return false;
if (total_number < 0)
return false;
continue;
}
FtpDirectoryListingEntry entry;
size_t column_offset;
base::string16 size;
if (!DetectColumnOffsetSizeAndModificationTime(columns,
current_time,
&column_offset,
&size,
&entry.last_modified)) {
if (lines[i].find(base::ASCIIToUTF16(".:")) != base::string16::npos)
continue;
return false;
}
if (!columns[0].empty() && columns[0][0] == 'l') {
entry.type = FtpDirectoryListingEntry::SYMLINK;
} else if (!columns[0].empty() && columns[0][0] == 'd') {
entry.type = FtpDirectoryListingEntry::DIRECTORY;
} else {
entry.type = FtpDirectoryListingEntry::FILE;
}
if (!base::StringToInt64(size, &entry.size)) {
entry.size = 0;
}
if (entry.size < 0) {
entry.size = -1;
}
if (entry.type != FtpDirectoryListingEntry::FILE)
entry.size = -1;
if (column_offset == columns.size() - 1) {
continue;
}
entry.name = FtpUtil::GetStringPartAfterColumns(lines[i],
column_offset + 1);
if (entry.type == FtpDirectoryListingEntry::SYMLINK) {
base::string16::size_type pos =
entry.name.rfind(base::ASCIIToUTF16(" -> "));
if (pos != base::string16::npos)
entry.name = entry.name.substr(0, pos);
}
entries->push_back(entry);
}
return true;
}
}