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

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

Issue 348036: Implement VMS FTP directory listing parser. (Closed)
Patch Set: fix Created 11 years, 1 month 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "net/ftp/ftp_directory_listing_buffer.h" 5 #include "net/ftp/ftp_directory_listing_buffer.h"
6 6
7 #include "base/i18n/icu_string_conversions.h" 7 #include "base/i18n/icu_string_conversions.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
(...skipping 19 matching lines...) Expand all
30 // Should we check the quality of the match? A rather arbitrary number is 30 // Should we check the quality of the match? A rather arbitrary number is
31 // assigned by ICU and it's hard to come up with a lower limit. 31 // assigned by ICU and it's hard to come up with a lower limit.
32 if (U_FAILURE(status)) 32 if (U_FAILURE(status))
33 return std::string(); 33 return std::string();
34 return encoding; 34 return encoding;
35 } 35 }
36 36
37 } // namespace 37 } // namespace
38 38
39 namespace net { 39 namespace net {
40 40
41 FtpDirectoryListingBuffer::FtpDirectoryListingBuffer() 41 FtpDirectoryListingBuffer::FtpDirectoryListingBuffer()
42 : current_parser_(NULL) { 42 : current_parser_(NULL) {
43 parsers_.insert(new FtpLsDirectoryListingParser()); 43 parsers_.insert(new FtpLsDirectoryListingParser());
44 parsers_.insert(new FtpVmsDirectoryListingParser());
44 } 45 }
45 46
46 FtpDirectoryListingBuffer::~FtpDirectoryListingBuffer() { 47 FtpDirectoryListingBuffer::~FtpDirectoryListingBuffer() {
47 STLDeleteElements(&parsers_); 48 STLDeleteElements(&parsers_);
48 } 49 }
49 50
50 int FtpDirectoryListingBuffer::ConsumeData(const char* data, int data_length) { 51 int FtpDirectoryListingBuffer::ConsumeData(const char* data, int data_length) {
51 buffer_.append(data, data_length); 52 buffer_.append(data, data_length);
52 53
53 if (!encoding_.empty() || buffer_.length() > 1024) { 54 if (!encoding_.empty() || buffer_.length() > 1024) {
54 int rv = ExtractFullLinesFromBuffer(); 55 int rv = ExtractFullLinesFromBuffer();
55 if (rv != OK) 56 if (rv != OK)
56 return rv; 57 return rv;
57 } 58 }
58 59
59 return ParseLines(); 60 return ParseLines();
60 } 61 }
61 62
62 int FtpDirectoryListingBuffer::ProcessRemainingData() { 63 int FtpDirectoryListingBuffer::ProcessRemainingData() {
63 int rv = ExtractFullLinesFromBuffer(); 64 int rv = ExtractFullLinesFromBuffer();
64 if (rv != OK) 65 if (rv != OK)
65 return rv; 66 return rv;
66 67
67 return ParseLines(); 68 return ParseLines();
68 } 69 }
69 70
70 bool FtpDirectoryListingBuffer::EntryAvailable() const { 71 bool FtpDirectoryListingBuffer::EntryAvailable() const {
71 return (current_parser_ ? current_parser_->EntryAvailable() : false); 72 return (current_parser_ ? current_parser_->EntryAvailable() : false);
72 } 73 }
73 74
74 FtpDirectoryListingEntry FtpDirectoryListingBuffer::PopEntry() { 75 FtpDirectoryListingEntry FtpDirectoryListingBuffer::PopEntry() {
75 DCHECK(EntryAvailable()); 76 DCHECK(EntryAvailable());
76 return current_parser_->PopEntry(); 77 return current_parser_->PopEntry();
77 } 78 }
78 79
79 bool FtpDirectoryListingBuffer::ConvertToDetectedEncoding( 80 bool FtpDirectoryListingBuffer::ConvertToDetectedEncoding(
80 const std::string& from, string16* to) { 81 const std::string& from, string16* to) {
81 std::string encoding(encoding_.empty() ? "ascii" : encoding_); 82 std::string encoding(encoding_.empty() ? "ascii" : encoding_);
82 return base::CodepageToUTF16(from, encoding.c_str(), 83 return base::CodepageToUTF16(from, encoding.c_str(),
83 base::OnStringConversionError::FAIL, to); 84 base::OnStringConversionError::FAIL, to);
84 } 85 }
85 86
86 int FtpDirectoryListingBuffer::ExtractFullLinesFromBuffer() { 87 int FtpDirectoryListingBuffer::ExtractFullLinesFromBuffer() {
87 if (encoding_.empty()) 88 if (encoding_.empty())
88 encoding_ = DetectEncoding(buffer_); 89 encoding_ = DetectEncoding(buffer_);
89 90
90 int cut_pos = 0; 91 int cut_pos = 0;
92 // TODO(phajdan.jr): This code accepts all endlines matching \r*\n. Should it
93 // be more strict, or enforce consistent line endings?
91 for (size_t i = 0; i < buffer_.length(); ++i) { 94 for (size_t i = 0; i < buffer_.length(); ++i) {
92 if (i >= 1 && buffer_[i - 1] == '\r' && buffer_[i] == '\n') { 95 if (buffer_[i] != '\n')
93 std::string line(buffer_.substr(cut_pos, i - cut_pos - 1)); 96 continue;
94 cut_pos = i + 1; 97 int line_length = i - cut_pos;
95 string16 line_converted; 98 if (i >= 1 && buffer_[i - 1] == '\r')
96 if (!ConvertToDetectedEncoding(line, &line_converted)) { 99 line_length--;
97 buffer_.erase(0, cut_pos); 100 std::string line(buffer_.substr(cut_pos, line_length));
98 return ERR_ENCODING_CONVERSION_FAILED; 101 cut_pos = i + 1;
99 } 102 string16 line_converted;
100 lines_.push_back(line_converted); 103 if (!ConvertToDetectedEncoding(line, &line_converted)) {
104 buffer_.erase(0, cut_pos);
105 return ERR_ENCODING_CONVERSION_FAILED;
101 } 106 }
107 lines_.push_back(line_converted);
102 } 108 }
103 buffer_.erase(0, cut_pos); 109 buffer_.erase(0, cut_pos);
104 return OK; 110 return OK;
105 } 111 }
106 112
107 int FtpDirectoryListingBuffer::ParseLines() { 113 int FtpDirectoryListingBuffer::ParseLines() {
108 while (!lines_.empty()) { 114 while (!lines_.empty()) {
109 string16 line = lines_.front(); 115 string16 line = lines_.front();
110 lines_.pop_front(); 116 lines_.pop_front();
111 if (current_parser_) { 117 if (current_parser_) {
112 if (!current_parser_->ConsumeLine(line)) 118 if (!current_parser_->ConsumeLine(line))
113 return ERR_FAILED; 119 return ERR_FAILED;
114 } else { 120 } else {
115 ParserSet::iterator i = parsers_.begin(); 121 ParserSet::iterator i = parsers_.begin();
116 while (i != parsers_.end()) { 122 while (i != parsers_.end()) {
117 if ((*i)->ConsumeLine(line)) { 123 if ((*i)->ConsumeLine(line)) {
118 i++; 124 i++;
119 } else { 125 } else {
120 delete *i; 126 delete *i;
121 parsers_.erase(i++); 127 parsers_.erase(i++);
122 } 128 }
123 } 129 }
124 if (parsers_.empty()) 130 if (parsers_.empty())
125 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; 131 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
126 if (parsers_.size() == 1) 132 if (parsers_.size() == 1)
127 current_parser_ = *parsers_.begin(); 133 current_parser_ = *parsers_.begin();
128 } 134 }
129 } 135 }
130 136
131 return OK; 137 return OK;
132 } 138 }
133 139
134 } // namespace net 140 } // namespace net
OLDNEW
« no previous file with comments | « net/data/ftp/dir-listing-vms-4.expected ('k') | net/ftp/ftp_directory_listing_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698