| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_directory_listing_parser_ls.h" | 5 #include "net/ftp/ftp_directory_listing_parser_ls.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "net/ftp/ftp_directory_listing_parser.h" | 14 #include "net/ftp/ftp_directory_listing_parser.h" |
| 15 #include "net/ftp/ftp_util.h" | 15 #include "net/ftp/ftp_util.h" |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 bool TwoColumnDateListingToTime(const base::string16& date, | 21 bool TwoColumnDateListingToTime(const base::string16& date, |
| 22 const base::string16& time, | 22 const base::string16& time, |
| 23 base::Time* result) { | 23 base::Time* result) { |
| 24 base::Time::Exploded time_exploded = { 0 }; | 24 base::Time::Exploded time_exploded = { 0 }; |
| 25 | 25 |
| 26 // Date should be in format YYYY-MM-DD. | 26 // Date should be in format YYYY-MM-DD. |
| 27 std::vector<base::string16> date_parts; | 27 std::vector<base::string16> date_parts = |
| 28 base::SplitString(date, '-', &date_parts); | 28 base::SplitString(date, base::ASCIIToUTF16("-"), base::TRIM_WHITESPACE, |
| 29 base::SPLIT_WANT_ALL); |
| 29 if (date_parts.size() != 3) | 30 if (date_parts.size() != 3) |
| 30 return false; | 31 return false; |
| 31 if (!base::StringToInt(date_parts[0], &time_exploded.year)) | 32 if (!base::StringToInt(date_parts[0], &time_exploded.year)) |
| 32 return false; | 33 return false; |
| 33 if (!base::StringToInt(date_parts[1], &time_exploded.month)) | 34 if (!base::StringToInt(date_parts[1], &time_exploded.month)) |
| 34 return false; | 35 return false; |
| 35 if (!base::StringToInt(date_parts[2], &time_exploded.day_of_month)) | 36 if (!base::StringToInt(date_parts[2], &time_exploded.day_of_month)) |
| 36 return false; | 37 return false; |
| 37 | 38 |
| 38 // Time should be in format HH:MM | 39 // Time should be in format HH:MM |
| 39 if (time.length() != 5) | 40 if (time.length() != 5) |
| 40 return false; | 41 return false; |
| 41 | 42 |
| 42 std::vector<base::string16> time_parts; | 43 std::vector<base::string16> time_parts = |
| 43 base::SplitString(time, ':', &time_parts); | 44 base::SplitString(time, base::ASCIIToUTF16(":"), base::TRIM_WHITESPACE, |
| 45 base::SPLIT_WANT_ALL); |
| 44 if (time_parts.size() != 2) | 46 if (time_parts.size() != 2) |
| 45 return false; | 47 return false; |
| 46 if (!base::StringToInt(time_parts[0], &time_exploded.hour)) | 48 if (!base::StringToInt(time_parts[0], &time_exploded.hour)) |
| 47 return false; | 49 return false; |
| 48 if (!base::StringToInt(time_parts[1], &time_exploded.minute)) | 50 if (!base::StringToInt(time_parts[1], &time_exploded.minute)) |
| 49 return false; | 51 return false; |
| 50 if (!time_exploded.HasValidValues()) | 52 if (!time_exploded.HasValidValues()) |
| 51 return false; | 53 return false; |
| 52 | 54 |
| 53 // We don't know the time zone of the server, so just use local time. | 55 // We don't know the time zone of the server, so just use local time. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 const base::Time& current_time, | 123 const base::Time& current_time, |
| 122 std::vector<FtpDirectoryListingEntry>* entries) { | 124 std::vector<FtpDirectoryListingEntry>* entries) { |
| 123 // True after we have received a "total n" listing header, where n is an | 125 // True after we have received a "total n" listing header, where n is an |
| 124 // integer. Only one such header is allowed per listing. | 126 // integer. Only one such header is allowed per listing. |
| 125 bool received_total_line = false; | 127 bool received_total_line = false; |
| 126 | 128 |
| 127 for (size_t i = 0; i < lines.size(); i++) { | 129 for (size_t i = 0; i < lines.size(); i++) { |
| 128 if (lines[i].empty()) | 130 if (lines[i].empty()) |
| 129 continue; | 131 continue; |
| 130 | 132 |
| 131 std::vector<base::string16> columns; | 133 std::vector<base::string16> columns = base::SplitString( |
| 132 base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns); | 134 base::CollapseWhitespace(lines[i], false), base::ASCIIToUTF16(" "), |
| 135 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 133 | 136 |
| 134 // Some FTP servers put a "total n" line at the beginning of the listing | 137 // Some FTP servers put a "total n" line at the beginning of the listing |
| 135 // (n is an integer). Allow such a line, but only once, and only if it's | 138 // (n is an integer). Allow such a line, but only once, and only if it's |
| 136 // the first non-empty line. Do not match the word exactly, because it may | 139 // the first non-empty line. Do not match the word exactly, because it may |
| 137 // be in different languages (at least English and German have been seen | 140 // be in different languages (at least English and German have been seen |
| 138 // in the field). | 141 // in the field). |
| 139 if (columns.size() == 2 && !received_total_line) { | 142 if (columns.size() == 2 && !received_total_line) { |
| 140 received_total_line = true; | 143 received_total_line = true; |
| 141 | 144 |
| 142 int64 total_number; | 145 int64 total_number; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 entry.name = entry.name.substr(0, pos); | 222 entry.name = entry.name.substr(0, pos); |
| 220 } | 223 } |
| 221 | 224 |
| 222 entries->push_back(entry); | 225 entries->push_back(entry); |
| 223 } | 226 } |
| 224 | 227 |
| 225 return true; | 228 return true; |
| 226 } | 229 } |
| 227 | 230 |
| 228 } // namespace net | 231 } // namespace net |
| OLD | NEW |