OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_vms.h" | 5 #include "net/ftp/ftp_directory_listing_parser_vms.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 // The first non-empty line is the listing header. It often | 199 // The first non-empty line is the listing header. It often |
200 // starts with "Directory ", but not always. We set a flag after | 200 // starts with "Directory ", but not always. We set a flag after |
201 // seing the header. | 201 // seing the header. |
202 bool seen_header = false; | 202 bool seen_header = false; |
203 | 203 |
204 // Sometimes the listing doesn't end with a "Total" line, but | 204 // Sometimes the listing doesn't end with a "Total" line, but |
205 // it's only okay when it contains some errors (it's needed | 205 // it's only okay when it contains some errors (it's needed |
206 // to distinguish it from "ls -l" format). | 206 // to distinguish it from "ls -l" format). |
207 bool seen_error = false; | 207 bool seen_error = false; |
208 | 208 |
| 209 base::string16 total_of = base::ASCIIToUTF16("Total of "); |
| 210 base::char16 space[2] = { ' ', 0 }; |
209 for (size_t i = 0; i < lines.size(); i++) { | 211 for (size_t i = 0; i < lines.size(); i++) { |
210 if (lines[i].empty()) | 212 if (lines[i].empty()) |
211 continue; | 213 continue; |
212 | 214 |
213 if (base::StartsWith(lines[i], base::ASCIIToUTF16("Total of "), true)) { | 215 if (base::StartsWith(lines[i], total_of, base::CompareCase::SENSITIVE)) { |
214 // After the "total" line, all following lines must be empty. | 216 // After the "total" line, all following lines must be empty. |
215 for (size_t j = i + 1; j < lines.size(); j++) | 217 for (size_t j = i + 1; j < lines.size(); j++) |
216 if (!lines[j].empty()) | 218 if (!lines[j].empty()) |
217 return false; | 219 return false; |
218 | 220 |
219 return true; | 221 return true; |
220 } | 222 } |
221 | 223 |
222 if (!seen_header) { | 224 if (!seen_header) { |
223 seen_header = true; | 225 seen_header = true; |
224 continue; | 226 continue; |
225 } | 227 } |
226 | 228 |
227 if (LooksLikeVMSError(lines[i])) { | 229 if (LooksLikeVMSError(lines[i])) { |
228 seen_error = true; | 230 seen_error = true; |
229 continue; | 231 continue; |
230 } | 232 } |
231 | 233 |
232 std::vector<base::string16> columns; | 234 std::vector<base::string16> columns = base::SplitString( |
233 base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns); | 235 base::CollapseWhitespace(lines[i], false), space, |
| 236 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
234 | 237 |
235 if (columns.size() == 1) { | 238 if (columns.size() == 1) { |
236 // There can be no continuation if the current line is the last one. | 239 // There can be no continuation if the current line is the last one. |
237 if (i == lines.size() - 1) | 240 if (i == lines.size() - 1) |
238 return false; | 241 return false; |
239 | 242 |
240 // Skip the next line. | 243 // Skip the next line. |
241 i++; | 244 i++; |
242 | 245 |
243 // This refers to the continuation line. | 246 // This refers to the continuation line. |
244 if (LooksLikeVMSError(lines[i])) { | 247 if (LooksLikeVMSError(lines[i])) { |
245 seen_error = true; | 248 seen_error = true; |
246 continue; | 249 continue; |
247 } | 250 } |
248 | 251 |
249 // Join the current and next line and split them into columns. | 252 // Join the current and next line and split them into columns. |
250 base::SplitString( | 253 columns = base::SplitString( |
251 base::CollapseWhitespace( | 254 base::CollapseWhitespace( |
252 lines[i - 1] + base::ASCIIToUTF16(" ") + lines[i], false), | 255 lines[i - 1] + space + lines[i], false), |
253 ' ', | 256 space, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
254 &columns); | |
255 } | 257 } |
256 | 258 |
257 FtpDirectoryListingEntry entry; | 259 FtpDirectoryListingEntry entry; |
258 if (!ParseVmsFilename(columns[0], &entry.name, &entry.type)) | 260 if (!ParseVmsFilename(columns[0], &entry.name, &entry.type)) |
259 return false; | 261 return false; |
260 | 262 |
261 // There are different variants of a VMS listing. Some display | 263 // There are different variants of a VMS listing. Some display |
262 // the protection listing and user identification code, some do not. | 264 // the protection listing and user identification code, some do not. |
263 if (columns.size() == 6) { | 265 if (columns.size() == 6) { |
264 if (!LooksLikeVmsFileProtectionListing(columns[5])) | 266 if (!LooksLikeVmsFileProtectionListing(columns[5])) |
(...skipping 19 matching lines...) Expand all Loading... |
284 entries->push_back(entry); | 286 entries->push_back(entry); |
285 } | 287 } |
286 | 288 |
287 // The only place where we return true is after receiving the "Total" line, | 289 // The only place where we return true is after receiving the "Total" line, |
288 // that should be present in every VMS listing. Alternatively, if the listing | 290 // that should be present in every VMS listing. Alternatively, if the listing |
289 // contains error messages, it's OK not to have the "Total" line. | 291 // contains error messages, it's OK not to have the "Total" line. |
290 return seen_error; | 292 return seen_error; |
291 } | 293 } |
292 | 294 |
293 } // namespace net | 295 } // namespace net |
OLD | NEW |