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

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

Issue 244008: Beginnings of our own FTP LIST parsing code. (Closed)
Patch Set: test even more (slightly) 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
(Empty)
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
3 // LICENSE file.
4
5 #include "net/ftp/ftp_directory_listing_parsers.h"
6
7 #include "base/string_util.h"
8
9 namespace {
10
11 bool LooksLikeUnixPermission(const string16& text) {
12 if (text.length() != 3)
13 return false;
14
15 return ((text[0] == 'r' || text[0] == '-') &&
16 (text[1] == 'w' || text[1] == '-') &&
17 (text[2] == 'x' || text[2] == 's' || text[2] == 'S' ||
18 text[2] == '-'));
19 }
20
21 bool LooksLikeUnixPermissionsListing(const string16& text) {
22 if (text.length() != 10)
23 return false;
24
25 if (text[0] != 'b' && text[0] != 'c' && text[0] != 'd' &&
26 text[0] != 'l' && text[0] != 'p' && text[0] != 's' &&
27 text[0] != '-')
28 return false;
29
30 return (LooksLikeUnixPermission(text.substr(1, 3)) &&
31 LooksLikeUnixPermission(text.substr(4, 3)) &&
32 LooksLikeUnixPermission(text.substr(7, 3)));
33 }
34
35 bool IsStringNonNegativeNumber(const string16& text) {
36 int number;
37 if (!StringToInt(text, &number))
38 return false;
39
40 return number >= 0;
41 }
42
43 bool ThreeLetterMonthToNumber(const string16& text, int* number) {
44 const static char* months[] = { "jan", "feb", "mar", "apr", "may", "jun",
45 "jul", "aug", "sep", "oct", "nov", "dec" };
46
47 for (size_t i = 0; i < arraysize(months); i++) {
48 if (LowerCaseEqualsASCII(text, months[i])) {
49 *number = i + 1;
50 return true;
51 }
52 }
53
54 return false;
55 }
56
57 bool UnixDateListingToTime(const std::vector<string16>& columns,
58 base::Time* time) {
59 DCHECK_EQ(9U, columns.size());
60
61 base::Time::Exploded time_exploded = { 0 };
62
63 if (!ThreeLetterMonthToNumber(columns[5], &time_exploded.month))
64 return false;
65
66 if (!StringToInt(columns[6], &time_exploded.day_of_month))
67 return false;
68
69 if (!StringToInt(columns[7], &time_exploded.year)) {
70 // Maybe it's time. Does it look like time (MM:HH)?
71 if (columns[7].length() != 5 || columns[7][2] != ':')
72 return false;
73
74 if (!StringToInt(columns[7].substr(0, 2), &time_exploded.hour))
75 return false;
76
77 if (!StringToInt(columns[7].substr(3, 2), &time_exploded.minute))
78 return false;
79
80 // Use current year.
81 base::Time::Exploded now_exploded;
82 base::Time::Now().LocalExplode(&now_exploded);
83 time_exploded.year = now_exploded.year;
84 }
85
86 // We don't know the time zone of the server, so just use local time.
87 *time = base::Time::FromLocalExploded(time_exploded);
88 return true;
89 }
90
91 } // namespace
92
93 namespace net {
94
95 FtpDirectoryListingParser::~FtpDirectoryListingParser() {
96 }
97
98 FtpLsDirectoryListingParser::FtpLsDirectoryListingParser() {
99 }
100
101 bool FtpLsDirectoryListingParser::ConsumeLine(const string16& line) {
102 std::vector<string16> columns;
103 SplitString(CollapseWhitespace(line, false), ' ', &columns);
104 if (columns.size() == 11) {
105 // Check if it is a symlink.
106 if (columns[9] != ASCIIToUTF16("->"))
107 return false;
108
109 // Drop the symlink target from columns, we don't use it.
110 columns.resize(9);
111 }
112
113 if (columns.size() != 9)
114 return false;
115
116 if (!LooksLikeUnixPermissionsListing(columns[0]))
117 return false;
118
119 FtpDirectoryListingEntry entry;
120 if (columns[0][0] == 'l') {
121 entry.type = FtpDirectoryListingEntry::SYMLINK;
122 } else if (columns[0][0] == 'd') {
123 entry.type = FtpDirectoryListingEntry::DIRECTORY;
124 } else {
125 entry.type = FtpDirectoryListingEntry::FILE;
126 }
127
128 if (!IsStringNonNegativeNumber(columns[1]))
129 return false;
130
131 if (!IsStringNonNegativeNumber(columns[4]))
132 return false;
133
134 if (!UnixDateListingToTime(columns, &entry.last_modified))
135 return false;
136
137 entry.name = columns[8];
138
139 entries_.push(entry);
140 return true;
141 }
142
143 bool FtpLsDirectoryListingParser::EntryAvailable() const {
144 return !entries_.empty();
145 }
146
147 FtpDirectoryListingEntry FtpLsDirectoryListingParser::PopEntry() {
148 FtpDirectoryListingEntry entry = entries_.front();
149 entries_.pop();
150 return entry;
151 }
152
153 } // 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