drag_download_util.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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 "chrome/browser/download/drag_download_util.h"
6
7#include "base/string_util.h"
8#include "base/file_path.h"
9#include "base/file_util.h"
10#include "base/scoped_ptr.h"
11#include "base/task.h"
12#include "base/utf_string_conversions.h"
13#include "chrome/browser/chrome_thread.h"
14#include "googleurl/src/gurl.h"
15#include "net/base/file_stream.h"
16#include "net/base/net_errors.h"
17
18using net::FileStream;
19
20namespace drag_download_util {
21
22bool ParseDownloadMetadata(const string16& metadata,
23                           string16* mime_type,
24                           FilePath* file_name,
25                           GURL* url) {
26  const char16 separator = L':';
27
28  size_t mime_type_end_pos = metadata.find(separator);
29  if (mime_type_end_pos == 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 == 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    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 = FilePath(file_name_str);
47#else
48    *file_name = FilePath(UTF16ToUTF8(file_name_str));
49#endif
50  }
51  if (url)
52    *url = parsed_url;
53
54  return true;
55}
56
57FileStream* CreateFileStreamForDrop(FilePath* file_path) {
58  DCHECK(file_path && !file_path->empty());
59
60  scoped_ptr<FileStream> file_stream(new FileStream);
61  const int kMaxSeq = 99;
62  for (int seq = 0; seq <= kMaxSeq; seq++) {
63    FilePath new_file_path;
64    if (seq == 0) {
65      new_file_path = *file_path;
66    } else {
67 #if defined(OS_WIN)
68      std::wstring suffix = std::wstring(L"-") + IntToWString(seq);
69 #else
70      std::string suffix = std::string("-") + IntToString(seq);
71 #endif
72      new_file_path = file_path->InsertBeforeExtension(suffix);
73    }
74
75    // Explicitly (and redundantly check) for file -- despite the fact that our
76    // open won't overwrite -- just to avoid log spew.
77    if (!file_util::PathExists(new_file_path) &&
78        file_stream->Open(new_file_path, base::PLATFORM_FILE_CREATE |
79                              base::PLATFORM_FILE_WRITE) == net::OK) {
80      *file_path = new_file_path;
81      return file_stream.release();
82    }
83  }
84
85  return NULL;
86}
87
88void PromiseFileFinalizer::Cleanup() {
89  if (drag_file_downloader_.get())
90    drag_file_downloader_ = NULL;
91}
92
93void PromiseFileFinalizer::OnDownloadCompleted(const FilePath& file_path) {
94  ChromeThread::PostTask(
95      ChromeThread::UI, FROM_HERE,
96      NewRunnableMethod(this, &PromiseFileFinalizer::Cleanup));
97}
98
99void PromiseFileFinalizer::OnDownloadAborted() {
100  ChromeThread::PostTask(
101      ChromeThread::UI, FROM_HERE,
102      NewRunnableMethod(this, &PromiseFileFinalizer::Cleanup));
103}
104
105}  // namespace drag_download_util
106