| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "net/ftp/ftp_directory_listing_parser.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/i18n/icu_encoding_detection.h" | 9 #include "base/i18n/icu_encoding_detection.h" |
| 10 #include "base/i18n/icu_string_conversions.h" | 10 #include "base/i18n/icu_string_conversions.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 namespace net { | 23 namespace net { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Fills in |raw_name| for all |entries| using |encoding|. Returns network | 27 // Fills in |raw_name| for all |entries| using |encoding|. Returns network |
| 28 // error code. | 28 // error code. |
| 29 int FillInRawName(const std::string& encoding, | 29 int FillInRawName(const std::string& encoding, |
| 30 std::vector<FtpDirectoryListingEntry>* entries) { | 30 std::vector<FtpDirectoryListingEntry>* entries) { |
| 31 for (size_t i = 0; i < entries->size(); i++) { | 31 for (size_t i = 0; i < entries->size(); i++) { |
| 32 if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(), | 32 if (!base::UTF16ToCodepage(entries->at(i).name, |
| 33 encoding.c_str(), |
| 33 base::OnStringConversionError::FAIL, | 34 base::OnStringConversionError::FAIL, |
| 34 &entries->at(i).raw_name)) { | 35 &entries->at(i).raw_name)) { |
| 35 return ERR_ENCODING_CONVERSION_FAILED; | 36 return ERR_ENCODING_CONVERSION_FAILED; |
| 36 } | 37 } |
| 37 } | 38 } |
| 38 | 39 |
| 39 return OK; | 40 return OK; |
| 40 } | 41 } |
| 41 | 42 |
| 42 // Parses |text| as an FTP directory listing. Fills in |entries| | 43 // Parses |text| as an FTP directory listing. Fills in |entries| |
| 43 // and |server_type| and returns network error code. | 44 // and |server_type| and returns network error code. |
| 44 int ParseListing(const base::string16& text, | 45 int ParseListing(const base::string16& text, |
| 45 const base::string16& newline_separator, | 46 const base::string16& newline_separator, |
| 46 const std::string& encoding, | 47 const std::string& encoding, |
| 47 const base::Time& current_time, | 48 const base::Time& current_time, |
| 48 std::vector<FtpDirectoryListingEntry>* entries, | 49 std::vector<FtpDirectoryListingEntry>* entries, |
| 49 FtpServerType* server_type) { | 50 FtpServerType* server_type) { |
| 50 std::vector<base::string16> lines; | 51 std::vector<base::string16> lines; |
| 51 base::SplitStringUsingSubstr(text, newline_separator, &lines); | 52 base::SplitStringUsingSubstr(text, newline_separator, &lines); |
| 52 | 53 |
| 53 struct { | 54 struct { |
| 54 base::Callback<bool(void)> callback; | 55 base::Callback<bool(void)> callback; |
| 55 FtpServerType server_type; | 56 FtpServerType server_type; |
| 56 } parsers[] = { | 57 } parsers[] = { |
| 57 { | 58 {base::Bind(&ParseFtpDirectoryListingLs, lines, current_time, entries), |
| 58 base::Bind(&ParseFtpDirectoryListingLs, lines, current_time, entries), | 59 SERVER_LS}, |
| 59 SERVER_LS | 60 {base::Bind(&ParseFtpDirectoryListingWindows, lines, entries), |
| 60 }, | 61 SERVER_WINDOWS}, |
| 61 { | 62 {base::Bind(&ParseFtpDirectoryListingVms, lines, entries), SERVER_VMS}, |
| 62 base::Bind(&ParseFtpDirectoryListingWindows, lines, entries), | 63 {base::Bind( |
| 63 SERVER_WINDOWS | 64 &ParseFtpDirectoryListingNetware, lines, current_time, entries), |
| 64 }, | 65 SERVER_NETWARE}, |
| 65 { | 66 {base::Bind(&ParseFtpDirectoryListingOS2, lines, entries), SERVER_OS2}}; |
| 66 base::Bind(&ParseFtpDirectoryListingVms, lines, entries), | |
| 67 SERVER_VMS | |
| 68 }, | |
| 69 { | |
| 70 base::Bind(&ParseFtpDirectoryListingNetware, | |
| 71 lines, current_time, entries), | |
| 72 SERVER_NETWARE | |
| 73 }, | |
| 74 { | |
| 75 base::Bind(&ParseFtpDirectoryListingOS2, lines, entries), | |
| 76 SERVER_OS2 | |
| 77 } | |
| 78 }; | |
| 79 | 67 |
| 80 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(parsers); i++) { | 68 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(parsers); i++) { |
| 81 entries->clear(); | 69 entries->clear(); |
| 82 if (parsers[i].callback.Run()) { | 70 if (parsers[i].callback.Run()) { |
| 83 *server_type = parsers[i].server_type; | 71 *server_type = parsers[i].server_type; |
| 84 return FillInRawName(encoding, entries); | 72 return FillInRawName(encoding, entries); |
| 85 } | 73 } |
| 86 } | 74 } |
| 87 | 75 |
| 88 entries->clear(); | 76 entries->clear(); |
| 89 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; | 77 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; |
| 90 } | 78 } |
| 91 | 79 |
| 92 // Detects encoding of |text| and parses it as an FTP directory listing. | 80 // Detects encoding of |text| and parses it as an FTP directory listing. |
| 93 // Fills in |entries| and |server_type| and returns network error code. | 81 // Fills in |entries| and |server_type| and returns network error code. |
| 94 int DecodeAndParse(const std::string& text, | 82 int DecodeAndParse(const std::string& text, |
| 95 const base::Time& current_time, | 83 const base::Time& current_time, |
| 96 std::vector<FtpDirectoryListingEntry>* entries, | 84 std::vector<FtpDirectoryListingEntry>* entries, |
| 97 FtpServerType* server_type) { | 85 FtpServerType* server_type) { |
| 98 const char* kNewlineSeparators[] = { "\n", "\r\n" }; | 86 const char* kNewlineSeparators[] = {"\n", "\r\n"}; |
| 99 | 87 |
| 100 std::vector<std::string> encodings; | 88 std::vector<std::string> encodings; |
| 101 if (!base::DetectAllEncodings(text, &encodings)) | 89 if (!base::DetectAllEncodings(text, &encodings)) |
| 102 return ERR_ENCODING_DETECTION_FAILED; | 90 return ERR_ENCODING_DETECTION_FAILED; |
| 103 | 91 |
| 104 // Use first encoding that can be used to decode the text. | 92 // Use first encoding that can be used to decode the text. |
| 105 for (size_t i = 0; i < encodings.size(); i++) { | 93 for (size_t i = 0; i < encodings.size(); i++) { |
| 106 base::string16 converted_text; | 94 base::string16 converted_text; |
| 107 if (base::CodepageToUTF16(text, | 95 if (base::CodepageToUTF16(text, |
| 108 encodings[i].c_str(), | 96 encodings[i].c_str(), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 121 } | 109 } |
| 122 } | 110 } |
| 123 | 111 |
| 124 entries->clear(); | 112 entries->clear(); |
| 125 *server_type = SERVER_UNKNOWN; | 113 *server_type = SERVER_UNKNOWN; |
| 126 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; | 114 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; |
| 127 } | 115 } |
| 128 | 116 |
| 129 } // namespace | 117 } // namespace |
| 130 | 118 |
| 131 FtpDirectoryListingEntry::FtpDirectoryListingEntry() | 119 FtpDirectoryListingEntry::FtpDirectoryListingEntry() : type(UNKNOWN), size(-1) { |
| 132 : type(UNKNOWN), | |
| 133 size(-1) { | |
| 134 } | 120 } |
| 135 | 121 |
| 136 int ParseFtpDirectoryListing(const std::string& text, | 122 int ParseFtpDirectoryListing(const std::string& text, |
| 137 const base::Time& current_time, | 123 const base::Time& current_time, |
| 138 std::vector<FtpDirectoryListingEntry>* entries) { | 124 std::vector<FtpDirectoryListingEntry>* entries) { |
| 139 FtpServerType server_type = SERVER_UNKNOWN; | 125 FtpServerType server_type = SERVER_UNKNOWN; |
| 140 int rv = DecodeAndParse(text, current_time, entries, &server_type); | 126 int rv = DecodeAndParse(text, current_time, entries, &server_type); |
| 141 UpdateFtpServerTypeHistograms(server_type); | 127 UpdateFtpServerTypeHistograms(server_type); |
| 142 return rv; | 128 return rv; |
| 143 } | 129 } |
| 144 | 130 |
| 145 } // namespace net | 131 } // namespace net |
| OLD | NEW |