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

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

Issue 6718043: FTP: Multiple fixes for localized directory listings: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update copyright year for the bot Created 9 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « net/data/ftp/dir-listing-ls-27.expected ('k') | net/ftp/ftp_directory_listing_parser_ls.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/i18n/icu_encoding_detection.h" 7 #include "base/i18n/icu_encoding_detection.h"
8 #include "base/i18n/icu_string_conversions.h" 8 #include "base/i18n/icu_string_conversions.h"
9 #include "base/stl_util-inl.h" 9 #include "base/stl_util-inl.h"
10 #include "base/string_split.h" 10 #include "base/string_split.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
13 #include "net/ftp/ftp_directory_listing_parser_ls.h" 13 #include "net/ftp/ftp_directory_listing_parser_ls.h"
14 #include "net/ftp/ftp_directory_listing_parser_netware.h" 14 #include "net/ftp/ftp_directory_listing_parser_netware.h"
15 #include "net/ftp/ftp_directory_listing_parser_vms.h" 15 #include "net/ftp/ftp_directory_listing_parser_vms.h"
16 #include "net/ftp/ftp_directory_listing_parser_windows.h" 16 #include "net/ftp/ftp_directory_listing_parser_windows.h"
17 #include "net/ftp/ftp_server_type_histograms.h" 17 #include "net/ftp/ftp_server_type_histograms.h"
18 18
19 namespace net {
20
19 namespace { 21 namespace {
20 22
21 // Converts a string with unknown character encoding to UTF-16. On success 23 // Fills in |raw_name| for all |entries| using |encoding|. Returns network
22 // fills in |converted_text| and |encoding|. Returns network error code. 24 // 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.
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, 25 int FillInRawName(const std::string& encoding,
45 std::vector<net::FtpDirectoryListingEntry>* entries) { 26 std::vector<FtpDirectoryListingEntry>* entries) {
46 for (size_t i = 0; i < entries->size(); i++) { 27 for (size_t i = 0; i < entries->size(); i++) {
47 if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(), 28 if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(),
48 base::OnStringConversionError::FAIL, 29 base::OnStringConversionError::FAIL,
49 &entries->at(i).raw_name)) { 30 &entries->at(i).raw_name)) {
50 return net::ERR_ENCODING_CONVERSION_FAILED; 31 return ERR_ENCODING_CONVERSION_FAILED;
51 } 32 }
52 } 33 }
53 34
54 return net::OK; 35 return OK;
36 }
37
38 // Parses |text| as an FTP directory listing. Fills in |entries|
39 // and |server_type| and returns network error code.
40 int ParseListing(const string16& text,
41 const std::string& encoding,
42 const base::Time& current_time,
43 std::vector<FtpDirectoryListingEntry>* entries,
44 FtpServerType* server_type) {
45 std::vector<string16> lines;
46 base::SplitString(text, '\n', &lines);
47
48 // TODO(phajdan.jr): Use a table of callbacks instead of repeating code.
49
50 entries->clear();
51 if (ParseFtpDirectoryListingLs(lines, current_time, entries)) {
52 *server_type = SERVER_LS;
53 return FillInRawName(encoding, entries);
54 }
55
56 entries->clear();
57 if (ParseFtpDirectoryListingWindows(lines, entries)) {
58 *server_type = SERVER_WINDOWS;
59 return FillInRawName(encoding, entries);
60 }
61
62 entries->clear();
63 if (ParseFtpDirectoryListingVms(lines, entries)) {
64 *server_type = SERVER_VMS;
65 return FillInRawName(encoding, entries);
66 }
67
68 entries->clear();
69 if (ParseFtpDirectoryListingNetware(lines, current_time, entries)) {
70 *server_type = SERVER_NETWARE;
71 return FillInRawName(encoding, entries);
72 }
73
74 entries->clear();
75 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
76 }
77
78 // Detects encoding of |text| and parses it as an FTP directory listing.
79 // Fills in |entries| and |server_type| and returns network error code.
80 int DecodeAndParse(const std::string& text,
81 const base::Time& current_time,
82 std::vector<FtpDirectoryListingEntry>* entries,
83 FtpServerType* server_type) {
84 std::vector<std::string> encodings;
85 if (!base::DetectAllEncodings(text, &encodings))
86 return ERR_ENCODING_DETECTION_FAILED;
87
88 // Use first encoding that can be used to decode the text.
89 for (size_t i = 0; i < encodings.size(); i++) {
90 string16 converted_text;
91 if (base::CodepageToUTF16(text,
92 encodings[i].c_str(),
93 base::OnStringConversionError::FAIL,
94 &converted_text)) {
95 int rv = ParseListing(converted_text,
96 encodings[i],
97 current_time,
98 entries,
99 server_type);
100 if (rv == OK)
101 return rv;
102 }
103 }
104
105 entries->clear();
106 *server_type = SERVER_UNKNOWN;
107 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
55 } 108 }
56 109
57 } // namespace 110 } // namespace
58 111
59 namespace net {
60
61 FtpDirectoryListingEntry::FtpDirectoryListingEntry() { 112 FtpDirectoryListingEntry::FtpDirectoryListingEntry() {
62 } 113 }
63 114
64 int ParseFtpDirectoryListing(const std::string& text, 115 int ParseFtpDirectoryListing(const std::string& text,
65 const base::Time& current_time, 116 const base::Time& current_time,
66 std::vector<FtpDirectoryListingEntry>* entries) { 117 std::vector<FtpDirectoryListingEntry>* entries) {
67 std::string encoding; 118 FtpServerType server_type = SERVER_UNKNOWN;
68 119 int rv = DecodeAndParse(text, current_time, entries, &server_type);
69 string16 converted_text; 120 UpdateFtpServerTypeHistograms(server_type);
70 int rv = ConvertStringToUTF16(text, &converted_text, &encoding); 121 return rv;
71 if (rv != OK)
72 return rv;
73
74 std::vector<string16> lines;
75 base::SplitString(converted_text, '\n', &lines);
76
77 // TODO(phajdan.jr): Use a table of callbacks instead of repeating code.
78
79 entries->clear();
80 if (ParseFtpDirectoryListingLs(lines, current_time, entries)) {
81 UpdateFtpServerTypeHistograms(SERVER_LS);
82 return FillInRawName(encoding, entries);
83 }
84
85 entries->clear();
86 if (ParseFtpDirectoryListingWindows(lines, entries)) {
87 UpdateFtpServerTypeHistograms(SERVER_WINDOWS);
88 return FillInRawName(encoding, entries);
89 }
90
91 entries->clear();
92 if (ParseFtpDirectoryListingVms(lines, entries)) {
93 UpdateFtpServerTypeHistograms(SERVER_VMS);
94 return FillInRawName(encoding, entries);
95 }
96
97 entries->clear();
98 if (ParseFtpDirectoryListingNetware(lines, current_time, entries)) {
99 UpdateFtpServerTypeHistograms(SERVER_NETWARE);
100 return FillInRawName(encoding, entries);
101 }
102
103 entries->clear();
104 UpdateFtpServerTypeHistograms(SERVER_UNKNOWN);
105 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
106 } 122 }
107 123
108 } // namespace 124 } // namespace net
OLDNEW
« no previous file with comments | « net/data/ftp/dir-listing-ls-27.expected ('k') | net/ftp/ftp_directory_listing_parser_ls.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698