summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_fetcher_response_writer.h
blob: d34080600d488ab4536822879f5464fcdfc21f4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_
#define NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/platform_file.h"
#include "net/base/completion_callback.h"

namespace base {
class FilePath;
class TaskRunner;
}  // namespace base

namespace net {

class DrainableIOBuffer;
class IOBuffer;

// This class encapsulates all state involved in writing URLFetcher response
// bytes to the destination.
class URLFetcherResponseWriter {
 public:
  virtual ~URLFetcherResponseWriter() {}

  // Initializes this instance. If ERR_IO_PENDING is returned, |callback| will
  // be run later with the result.
  virtual int Initialize(const CompletionCallback& callback) = 0;

  // Writes |num_bytes| bytes in |buffer|, and returns the number of bytes
  // written or an error code. If ERR_IO_PENDING is returned, |callback| will be
  // run later with the result.
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) = 0;

  // Finishes writing. If ERR_IO_PENDING is returned, |callback| will be run
  // later with the result.
  virtual int Finish(const CompletionCallback& callback) = 0;
};

// URLFetcherResponseWriter implementation for std::string.
class URLFetcherStringWriter : public URLFetcherResponseWriter {
 public:
  URLFetcherStringWriter(std::string* string);
  virtual ~URLFetcherStringWriter();

  // URLFetcherResponseWriter overrides:
  virtual int Initialize(const CompletionCallback& callback) OVERRIDE;
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) OVERRIDE;
  virtual int Finish(const CompletionCallback& callback) OVERRIDE;

 private:
  std::string* const string_;

  DISALLOW_COPY_AND_ASSIGN(URLFetcherStringWriter);
};

// URLFetcherResponseWriter implementation for files.
class URLFetcherFileWriter : public URLFetcherResponseWriter {
 public:
  URLFetcherFileWriter(scoped_refptr<base::TaskRunner> file_task_runner);
  virtual ~URLFetcherFileWriter();

  // Sets destination file path.
  // Call this method before Initialize() to set the destination path,
  // if this method is not called before Initialize(), Initialize() will create
  // a temporary file.
  void set_destination_file_path(const base::FilePath& file_path) {
    file_path_ = file_path;
  }

  // URLFetcherResponseWriter overrides:
  virtual int Initialize(const CompletionCallback& callback) OVERRIDE;
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) OVERRIDE;
  virtual int Finish(const CompletionCallback& callback) OVERRIDE;

  // Called when a write has been done.  Continues writing if there are more
  // bytes to write.  Otherwise, runs |callback|.
  void ContinueWrite(scoped_refptr<DrainableIOBuffer> buffer,
                     const CompletionCallback& callback,
                     base::PlatformFileError error_code,
                     int bytes_written);

  // Drops ownership of the file at |file_path_|.
  // This class will not delete it or write to it again.
  void DisownFile();

  // Closes the file if it is open.
  // |callback| is run with the result upon completion.
  void CloseFile(const CompletionCallback& callback);

  // Closes the file if it is open and then delete it.
  void CloseAndDeleteFile();

  const base::FilePath& file_path() const { return file_path_; }
  int64 total_bytes_written() { return total_bytes_written_; }
  int error_code() const { return error_code_; }

 private:
  // Callback which gets the result of a permanent file creation.
  void DidCreateFile(const CompletionCallback& callback,
                     const base::FilePath& file_path,
                     base::PlatformFileError error_code,
                     base::PassPlatformFile file_handle,
                     bool created);

  // Callback which gets the result of a temporary file creation.
  void DidCreateTempFile(const CompletionCallback& callback,
                         base::PlatformFileError error_code,
                         base::PassPlatformFile file_handle,
                         const base::FilePath& file_path);

  // This method is used to implement DidCreateFile and DidCreateTempFile.
  // |callback| is run with the result.
  void DidCreateFileInternal(const CompletionCallback& callback,
                             const base::FilePath& file_path,
                             base::PlatformFileError error_code,
                             base::PassPlatformFile file_handle);

  // Callback which gets the result of closing the file.
  // |callback| is run with the result.
  void DidCloseFile(const CompletionCallback& callback,
                    base::PlatformFileError error);

  // Callback which gets the result of closing the file. Deletes the file if
  // it has been created.
  void DeleteFile(base::PlatformFileError error_code);

  // The last error encountered on a file operation.  OK if no error occurred.
  int error_code_;

  // Callbacks are created for use with base::FileUtilProxy.
  base::WeakPtrFactory<URLFetcherFileWriter> weak_factory_;

  // Task runner on which file operations should happen.
  scoped_refptr<base::TaskRunner> file_task_runner_;

  // Destination file path.
  // Initialize() creates a temporary file if this variable is empty.
  base::FilePath file_path_;

  // True when this instance is responsible to delete the file at |file_path_|.
  bool owns_file_;

  // Handle to the file.
  base::PlatformFile file_handle_;

  // We always append to the file.  Track the total number of bytes
  // written, so that writes know the offset to give.
  int64 total_bytes_written_;

  DISALLOW_COPY_AND_ASSIGN(URLFetcherFileWriter);
};

}  // namespace net

#endif  // NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_