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 |