OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // source code is governed by a BSD-style license that can be found in the | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // 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 namespace net { | 7 #include "base/i18n/icu_encoding_detection.h" |
8 #include "base/i18n/icu_string_conversions.h" | |
9 #include "base/stl_util-inl.h" | |
10 #include "base/string_split.h" | |
11 #include "base/string_util.h" | |
12 #include "net/base/net_errors.h" | |
13 #include "net/ftp/ftp_directory_listing_parser_ls.h" | |
14 #include "net/ftp/ftp_directory_listing_parser_netware.h" | |
15 #include "net/ftp/ftp_directory_listing_parser_vms.h" | |
16 #include "net/ftp/ftp_directory_listing_parser_windows.h" | |
17 #include "net/ftp/ftp_server_type_histograms.h" | |
8 | 18 |
9 FtpDirectoryListingParser::~FtpDirectoryListingParser() { | 19 namespace { |
20 | |
21 // Converts a string with unknown character encoding to UTF-16. On success | |
22 // fills in |converted_text| and |encoding|. Returns network error code. | |
23 int ConvertStringToUTF16(const std::string& text, | |
24 string16* converted_text, | |
25 std::string* encoding) { | |
26 std::vector<std::string> encodings; | |
27 if (!base::DetectAllEncodings(text, &encodings)) | |
28 return net::ERR_ENCODING_DETECTION_FAILED; | |
29 | |
30 // Use first encoding that can be used to decode the text. | |
eroman
2011/03/24 23:09:35
I wander if it would be more flexible to move this
Paweł Hajdan Jr.
2011/03/26 09:47:50
Yes, it sounds like a good idea. I'd prefer to do
| |
31 for (size_t i = 0; i < encodings.size(); i++) { | |
32 if (base::CodepageToUTF16(text, | |
33 encodings[i].c_str(), | |
34 base::OnStringConversionError::FAIL, | |
35 converted_text)) { | |
36 *encoding = encodings[i]; | |
37 return net::OK; | |
38 } | |
39 } | |
40 | |
41 return net::ERR_ENCODING_DETECTION_FAILED; | |
42 } | |
43 | |
44 int FillInRawName(const std::string& encoding, | |
45 std::vector<net::FtpDirectoryListingEntry>* entries) { | |
46 for (size_t i = 0; i < entries->size(); i++) { | |
47 if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(), | |
48 base::OnStringConversionError::FAIL, | |
49 &entries->at(i).raw_name)) { | |
50 return net::ERR_ENCODING_CONVERSION_FAILED; | |
51 } | |
52 } | |
53 | |
54 return net::OK; | |
10 } | 55 } |
11 | 56 |
12 } // namespace | 57 } // namespace |
58 | |
59 namespace net { | |
60 | |
61 int ParseFtpDirectoryListing(const std::string& text, | |
62 const base::Time& current_time, | |
63 std::vector<FtpDirectoryListingEntry>* entries) { | |
64 std::string encoding; | |
65 | |
66 string16 converted_text; | |
67 int rv = ConvertStringToUTF16(text, &converted_text, &encoding); | |
68 if (rv != OK) | |
69 return rv; | |
70 | |
71 std::vector<string16> lines; | |
72 base::SplitString(converted_text, '\n', &lines); | |
73 | |
74 // TODO(phajdan.jr): Use a table of callbacks instead of repeating code. | |
75 | |
76 entries->clear(); | |
77 if (ParseFtpDirectoryListingLs(lines, current_time, entries)) { | |
78 UpdateFtpServerTypeHistograms(SERVER_LS); | |
79 return FillInRawName(encoding, entries); | |
80 } | |
81 | |
82 entries->clear(); | |
83 if (ParseFtpDirectoryListingWindows(lines, entries)) { | |
84 UpdateFtpServerTypeHistograms(SERVER_WINDOWS); | |
85 return FillInRawName(encoding, entries); | |
86 } | |
87 | |
88 entries->clear(); | |
89 if (ParseFtpDirectoryListingVms(lines, entries)) { | |
90 UpdateFtpServerTypeHistograms(SERVER_VMS); | |
91 return FillInRawName(encoding, entries); | |
92 } | |
93 | |
94 entries->clear(); | |
95 if (ParseFtpDirectoryListingNetware(lines, current_time, entries)) { | |
96 UpdateFtpServerTypeHistograms(SERVER_NETWARE); | |
97 return FillInRawName(encoding, entries); | |
98 } | |
99 | |
100 entries->clear(); | |
101 UpdateFtpServerTypeHistograms(SERVER_UNKNOWN); | |
102 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; | |
103 } | |
104 | |
105 } // namespace | |
OLD | NEW |