Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/filesystem/Directory.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/dom/Directory.h"
8
9
#include "GetDirectoryListingTask.h"
10
#include "GetFilesTask.h"
11
12
#include "nsCharSeparatedTokenizer.h"
13
#include "nsString.h"
14
#include "mozilla/dom/DirectoryBinding.h"
15
#include "mozilla/dom/FileSystemBase.h"
16
#include "mozilla/dom/FileSystemUtils.h"
17
#include "mozilla/dom/OSFileSystem.h"
18
#include "mozilla/dom/WorkerPrivate.h"
19
20
namespace mozilla {
21
namespace dom {
22
23
NS_IMPL_CYCLE_COLLECTION_CLASS(Directory)
24
25
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Directory)
26
0
  if (tmp->mFileSystem) {
27
0
    tmp->mFileSystem->Unlink();
28
0
    tmp->mFileSystem = nullptr;
29
0
  }
30
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
31
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
32
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
33
34
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Directory)
35
0
  if (tmp->mFileSystem) {
36
0
    tmp->mFileSystem->Traverse(cb);
37
0
  }
38
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
39
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
40
41
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Directory)
42
43
NS_IMPL_CYCLE_COLLECTING_ADDREF(Directory)
44
NS_IMPL_CYCLE_COLLECTING_RELEASE(Directory)
45
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Directory)
46
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
47
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
48
0
NS_INTERFACE_MAP_END
49
50
/* static */ already_AddRefed<Directory>
51
Directory::Constructor(const GlobalObject& aGlobal,
52
                       const nsAString& aRealPath,
53
                       ErrorResult& aRv)
54
0
{
55
0
  nsCOMPtr<nsIFile> path;
56
0
  aRv = NS_NewLocalFile(aRealPath, true, getter_AddRefs(path));
57
0
  if (NS_WARN_IF(aRv.Failed())) {
58
0
    return nullptr;
59
0
  }
60
0
61
0
  return Create(aGlobal.GetAsSupports(), path);
62
0
}
63
64
/* static */ already_AddRefed<Directory>
65
Directory::Create(nsISupports* aParent, nsIFile* aFile,
66
                  FileSystemBase* aFileSystem)
67
0
{
68
0
  MOZ_ASSERT(aParent);
69
0
  MOZ_ASSERT(aFile);
70
0
71
0
  RefPtr<Directory> directory = new Directory(aParent, aFile, aFileSystem);
72
0
  return directory.forget();
73
0
}
74
75
Directory::Directory(nsISupports* aParent,
76
                     nsIFile* aFile,
77
                     FileSystemBase* aFileSystem)
78
  : mParent(aParent)
79
  , mFile(aFile)
80
0
{
81
0
  MOZ_ASSERT(aFile);
82
0
83
0
  // aFileSystem can be null. In this case we create a OSFileSystem when needed.
84
0
  if (aFileSystem) {
85
0
    // More likely, this is a OSFileSystem. This object keeps a reference of
86
0
    // mParent but it's not cycle collectable and to avoid manual
87
0
    // addref/release, it's better to have 1 object per directory. For this
88
0
    // reason we clone it here.
89
0
    mFileSystem = aFileSystem->Clone();
90
0
  }
91
0
}
92
93
Directory::~Directory()
94
0
{
95
0
}
96
97
nsISupports*
98
Directory::GetParentObject() const
99
0
{
100
0
  return mParent;
101
0
}
102
103
JSObject*
104
Directory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
105
0
{
106
0
  return Directory_Binding::Wrap(aCx, this, aGivenProto);
107
0
}
108
109
void
110
Directory::GetName(nsAString& aRetval, ErrorResult& aRv)
111
0
{
112
0
  aRetval.Truncate();
113
0
114
0
  RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
115
0
  if (NS_WARN_IF(aRv.Failed())) {
116
0
    return;
117
0
  }
118
0
119
0
  fs->GetDirectoryName(mFile, aRetval, aRv);
120
0
}
121
122
void
123
Directory::GetPath(nsAString& aRetval, ErrorResult& aRv)
124
0
{
125
0
  // This operation is expensive. Better to cache the result.
126
0
  if (mPath.IsEmpty()) {
127
0
    RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
128
0
    if (NS_WARN_IF(aRv.Failed())) {
129
0
      return;
130
0
    }
131
0
132
0
    fs->GetDOMPath(mFile, mPath, aRv);
133
0
    if (NS_WARN_IF(aRv.Failed())) {
134
0
      return;
135
0
    }
136
0
  }
137
0
138
0
  aRetval = mPath;
139
0
}
140
141
nsresult
142
Directory::GetFullRealPath(nsAString& aPath)
143
0
{
144
0
  nsresult rv = mFile->GetPath(aPath);
145
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
146
0
    return rv;
147
0
  }
148
0
149
0
  return NS_OK;
150
0
}
151
152
already_AddRefed<Promise>
153
Directory::GetFilesAndDirectories(ErrorResult& aRv)
154
0
{
155
0
  RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
156
0
  if (NS_WARN_IF(aRv.Failed())) {
157
0
    return nullptr;
158
0
  }
159
0
160
0
  RefPtr<GetDirectoryListingTaskChild> task =
161
0
    GetDirectoryListingTaskChild::Create(fs, this, mFile, mFilters, aRv);
162
0
  if (NS_WARN_IF(aRv.Failed())) {
163
0
    return nullptr;
164
0
  }
165
0
166
0
  task->Start();
167
0
168
0
  return task->GetPromise();
169
0
}
170
171
already_AddRefed<Promise>
172
Directory::GetFiles(bool aRecursiveFlag, ErrorResult& aRv)
173
0
{
174
0
  ErrorResult rv;
175
0
  RefPtr<FileSystemBase> fs = GetFileSystem(rv);
176
0
  if (NS_WARN_IF(rv.Failed())) {
177
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
178
0
    return nullptr;
179
0
  }
180
0
181
0
  RefPtr<GetFilesTaskChild> task =
182
0
    GetFilesTaskChild::Create(fs, this, mFile, aRecursiveFlag, rv);
183
0
  if (NS_WARN_IF(rv.Failed())) {
184
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
185
0
    return nullptr;
186
0
  }
187
0
188
0
  task->Start();
189
0
190
0
  return task->GetPromise();
191
0
}
192
193
void
194
Directory::SetContentFilters(const nsAString& aFilters)
195
0
{
196
0
  mFilters = aFilters;
197
0
}
198
199
FileSystemBase*
200
Directory::GetFileSystem(ErrorResult& aRv)
201
0
{
202
0
  if (!mFileSystem) {
203
0
    nsAutoString path;
204
0
    aRv = mFile->GetPath(path);
205
0
    if (NS_WARN_IF(aRv.Failed())) {
206
0
      return nullptr;
207
0
    }
208
0
209
0
    RefPtr<OSFileSystem> fs = new OSFileSystem(path);
210
0
    fs->Init(mParent);
211
0
212
0
    mFileSystem = fs;
213
0
  }
214
0
215
0
  return mFileSystem;
216
0
}
217
218
} // namespace dom
219
} // namespace mozilla