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
3// found in the LICENSE file.
4
5#include "net/ftp/ftp_directory_listing_parser_os2.h"
6
7#include <vector>
8
9#include "base/strings/string_number_conversions.h"
10#include "base/strings/string_split.h"
11#include "base/strings/string_util.h"
12#include "base/time/time.h"
13#include "net/ftp/ftp_directory_listing_parser.h"
14#include "net/ftp/ftp_util.h"
15
16namespace net {
17
18bool ParseFtpDirectoryListingOS2(
19    const std::vector<base::string16>& lines,
20    std::vector<FtpDirectoryListingEntry>* entries) {
21  for (size_t i = 0; i < lines.size(); i++) {
22    if (lines[i].empty())
23      continue;
24
25    std::vector<base::string16> columns;
26    base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns);
27
28    // Every line of the listing consists of the following:
29    //
30    //   1. size in bytes (0 for directories)
31    //   2. type (A for files, DIR for directories)
32    //   3. date
33    //   4. time
34    //   5. filename (may be empty or contain spaces)
35    //
36    // For now, make sure we have 1-4, and handle 5 later.
37    if (columns.size() < 4)
38      return false;
39
40    FtpDirectoryListingEntry entry;
41    if (!base::StringToInt64(columns[0], &entry.size))
42      return false;
43    if (EqualsASCII(columns[1], "DIR")) {
44      if (entry.size != 0)
45        return false;
46      entry.type = FtpDirectoryListingEntry::DIRECTORY;
47      entry.size = -1;
48    } else if (EqualsASCII(columns[1], "A")) {
49      entry.type = FtpDirectoryListingEntry::FILE;
50      if (entry.size < 0)
51        return false;
52    } else {
53      return false;
54    }
55
56    if (!FtpUtil::WindowsDateListingToTime(columns[2],
57                                           columns[3],
58                                           &entry.last_modified)) {
59      return false;
60    }
61
62    entry.name = FtpUtil::GetStringPartAfterColumns(lines[i], 4);
63    if (entry.name.empty()) {
64      // Some FTP servers send listing entries with empty names.
65      // It's not obvious how to display such an entry, so ignore them.
66      // We don't want to make the parsing fail at this point though.
67      // Other entries can still be useful.
68      continue;
69    }
70
71    entries->push_back(entry);
72  }
73
74  return true;
75}
76
77}  // namespace net
78