1// Copyright (c) 2013 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#ifndef STORAGE_COMMON_BLOB_SCOPED_FILE_H_
6#define STORAGE_COMMON_BLOB_SCOPED_FILE_H_
7
8#include <map>
9
10#include "base/callback_forward.h"
11#include "base/files/file_path.h"
12#include "base/memory/ref_counted.h"
13#include "base/move.h"
14#include "storage/common/storage_common_export.h"
15
16namespace base {
17class TaskRunner;
18}
19
20namespace storage {
21
22// A scoped reference for a FilePath that can optionally schedule the file
23// to be deleted and/or to notify a consumer when it is going to be scoped out.
24// This class supports move semantics, i.e. consumers can call Pass() to
25// pass the ownership of ScopedFile.
26//
27// TODO(kinuko): Probably this can be moved under base or somewhere more
28// common place.
29class STORAGE_COMMON_EXPORT ScopedFile {
30  // To support destructive assignment from an l-value assignment.
31  // This provides Pass() method which creates an r-value for the current
32  // instance. (See base/move.h for details)
33  MOVE_ONLY_TYPE_FOR_CPP_03(ScopedFile, RValue)
34
35 public:
36  typedef base::Callback<void(const base::FilePath&)> ScopeOutCallback;
37  typedef std::pair<ScopeOutCallback, scoped_refptr<base::TaskRunner> >
38      ScopeOutCallbackPair;
39  typedef std::vector<ScopeOutCallbackPair> ScopeOutCallbackList;
40
41  enum ScopeOutPolicy {
42    DELETE_ON_SCOPE_OUT,
43    DONT_DELETE_ON_SCOPE_OUT,
44  };
45
46  ScopedFile();
47
48  // |file_task_runner| is used to schedule a file deletion if |policy|
49  // is DELETE_ON_SCOPE_OUT.
50  ScopedFile(const base::FilePath& path,
51             ScopeOutPolicy policy,
52             const scoped_refptr<base::TaskRunner>& file_task_runner);
53
54  // Move constructor and operator. The data of r-value will be transfered
55  // in a destructive way. (See base/move.h)
56  ScopedFile(RValue other);
57  ScopedFile& operator=(RValue rhs) {
58    MoveFrom(*rhs.object);
59    return *this;
60  }
61
62  ~ScopedFile();
63
64  // The |callback| is fired on |callback_runner| when the final reference
65  // of this instance is released.
66  // If release policy is DELETE_ON_SCOPE_OUT the
67  // callback task(s) is/are posted before the deletion is scheduled.
68  void AddScopeOutCallback(const ScopeOutCallback& callback,
69                           base::TaskRunner* callback_runner);
70
71  // The full file path.
72  const base::FilePath& path() const { return path_; }
73
74  // Releases the file. After calling this, this instance will hold
75  // an empty file path and scoping out won't make any file deletion
76  // or callback dispatch. (If an owned pointer is attached to any of
77  // callbacks the pointer will be deleted.)
78  base::FilePath Release();
79
80  void Reset();
81
82 private:
83  // Performs destructive move from |other| to this.
84  void MoveFrom(ScopedFile& other);
85
86  base::FilePath path_;
87  ScopeOutPolicy scope_out_policy_;
88  scoped_refptr<base::TaskRunner> file_task_runner_;
89  ScopeOutCallbackList scope_out_callbacks_;
90};
91
92}  // namespace storage
93
94#endif  // STORAGE_COMMON_BLOB_SCOPED_FILE_H_
95