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
3// found in the LICENSE file.
4
5#include "content/browser/download/drag_download_util.h"
6
7#include <string>
8
9#include "base/bind.h"
10#include "base/files/file.h"
11#include "base/files/file_path.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/strings/string_number_conversions.h"
14#include "base/strings/string_util.h"
15#include "base/strings/utf_string_conversions.h"
16#include "base/threading/thread_restrictions.h"
17#include "content/public/browser/browser_thread.h"
18#include "url/gurl.h"
19
20namespace content {
21
22bool ParseDownloadMetadata(const base::string16& metadata,
23                           base::string16* mime_type,
24                           base::FilePath* file_name,
25                           GURL* url) {
26  const base::char16 separator = L':';
27
28  size_t mime_type_end_pos = metadata.find(separator);
29  if (mime_type_end_pos == base::string16::npos)
30    return false;
31
32  size_t file_name_end_pos = metadata.find(separator, mime_type_end_pos + 1);
33  if (file_name_end_pos == base::string16::npos)
34    return false;
35
36  GURL parsed_url = GURL(metadata.substr(file_name_end_pos + 1));
37  if (!parsed_url.is_valid())
38    return false;
39
40  if (mime_type)
41    *mime_type = metadata.substr(0, mime_type_end_pos);
42  if (file_name) {
43    base::string16 file_name_str = metadata.substr(
44        mime_type_end_pos + 1, file_name_end_pos - mime_type_end_pos  - 1);
45#if defined(OS_WIN)
46    *file_name = base::FilePath(file_name_str);
47#else
48    *file_name = base::FilePath(base::UTF16ToUTF8(file_name_str));
49#endif
50  }
51  if (url)
52    *url = parsed_url;
53
54  return true;
55}
56
57base::File CreateFileForDrop(base::FilePath* file_path) {
58  DCHECK(file_path && !file_path->empty());
59
60  const int kMaxSeq = 99;
61  for (int seq = 0; seq <= kMaxSeq; seq++) {
62    base::FilePath new_file_path;
63    if (seq == 0) {
64      new_file_path = *file_path;
65    } else {
66#if defined(OS_WIN)
67      base::string16 suffix =
68          base::ASCIIToUTF16("-") + base::IntToString16(seq);
69#else
70      std::string suffix = std::string("-") + base::IntToString(seq);
71#endif
72      new_file_path = file_path->InsertBeforeExtension(suffix);
73    }
74
75    // http://crbug.com/110709
76    base::ThreadRestrictions::ScopedAllowIO allow_io;
77
78    base::File file(
79        new_file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
80    if (file.IsValid()) {
81      *file_path = new_file_path;
82      return file.Pass();
83    }
84  }
85
86  return base::File();
87}
88
89PromiseFileFinalizer::PromiseFileFinalizer(
90    DragDownloadFile* drag_file_downloader)
91    : drag_file_downloader_(drag_file_downloader) {
92}
93
94void PromiseFileFinalizer::OnDownloadCompleted(
95    const base::FilePath& file_path) {
96  BrowserThread::PostTask(
97      BrowserThread::UI, FROM_HERE,
98      base::Bind(&PromiseFileFinalizer::Cleanup, this));
99}
100
101void PromiseFileFinalizer::OnDownloadAborted() {
102  BrowserThread::PostTask(
103      BrowserThread::UI, FROM_HERE,
104      base::Bind(&PromiseFileFinalizer::Cleanup, this));
105}
106
107PromiseFileFinalizer::~PromiseFileFinalizer() {}
108
109void PromiseFileFinalizer::Cleanup() {
110  if (drag_file_downloader_.get())
111    drag_file_downloader_ = NULL;
112}
113
114}  // namespace content
115