| 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 |