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 "ppapi/cpp/file_ref.h"
6
7#include "ppapi/c/pp_bool.h"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/cpp/completion_callback.h"
10#include "ppapi/cpp/directory_entry.h"
11#include "ppapi/cpp/file_system.h"
12#include "ppapi/cpp/module_impl.h"
13
14namespace pp {
15
16namespace {
17
18template <> const char* interface_name<PPB_FileRef_1_0>() {
19  return PPB_FILEREF_INTERFACE_1_0;
20}
21
22template <> const char* interface_name<PPB_FileRef_1_1>() {
23  return PPB_FILEREF_INTERFACE_1_1;
24}
25
26template <> const char* interface_name<PPB_FileRef_1_2>() {
27  return PPB_FILEREF_INTERFACE_1_2;
28}
29
30}  // namespace
31
32FileRef::FileRef(PP_Resource resource) : Resource(resource) {
33}
34
35FileRef::FileRef(PassRef, PP_Resource resource) : Resource(PASS_REF, resource) {
36}
37
38FileRef::FileRef(const FileSystem& file_system,
39                 const char* path) {
40  if (has_interface<PPB_FileRef_1_2>()) {
41    PassRefFromConstructor(get_interface<PPB_FileRef_1_2>()->Create(
42        file_system.pp_resource(), path));
43  } else if (has_interface<PPB_FileRef_1_1>()) {
44    PassRefFromConstructor(get_interface<PPB_FileRef_1_1>()->Create(
45        file_system.pp_resource(), path));
46  } else if (has_interface<PPB_FileRef_1_0>()) {
47    PassRefFromConstructor(get_interface<PPB_FileRef_1_0>()->Create(
48        file_system.pp_resource(), path));
49  }
50}
51
52FileRef::FileRef(const FileRef& other)
53    : Resource(other) {
54}
55
56PP_FileSystemType FileRef::GetFileSystemType() const {
57  if (has_interface<PPB_FileRef_1_2>())
58    return get_interface<PPB_FileRef_1_2>()->GetFileSystemType(pp_resource());
59  if (has_interface<PPB_FileRef_1_1>())
60    return get_interface<PPB_FileRef_1_1>()->GetFileSystemType(pp_resource());
61  if (has_interface<PPB_FileRef_1_0>())
62    return get_interface<PPB_FileRef_1_0>()->GetFileSystemType(pp_resource());
63  return PP_FILESYSTEMTYPE_EXTERNAL;
64}
65
66Var FileRef::GetName() const {
67  if (has_interface<PPB_FileRef_1_2>()) {
68    return Var(PASS_REF,
69               get_interface<PPB_FileRef_1_2>()->GetName(pp_resource()));
70  }
71  if (has_interface<PPB_FileRef_1_1>()) {
72    return Var(PASS_REF,
73               get_interface<PPB_FileRef_1_1>()->GetName(pp_resource()));
74  }
75  if (has_interface<PPB_FileRef_1_0>()) {
76    return Var(PASS_REF,
77               get_interface<PPB_FileRef_1_0>()->GetName(pp_resource()));
78  }
79  return Var();
80}
81
82Var FileRef::GetPath() const {
83  if (has_interface<PPB_FileRef_1_2>()) {
84    return Var(PASS_REF,
85               get_interface<PPB_FileRef_1_2>()->GetPath(pp_resource()));
86  }
87  if (has_interface<PPB_FileRef_1_1>()) {
88    return Var(PASS_REF,
89               get_interface<PPB_FileRef_1_1>()->GetPath(pp_resource()));
90  }
91  if (has_interface<PPB_FileRef_1_0>()) {
92    return Var(PASS_REF,
93               get_interface<PPB_FileRef_1_0>()->GetPath(pp_resource()));
94  }
95  return Var();
96}
97
98FileRef FileRef::GetParent() const {
99  if (has_interface<PPB_FileRef_1_2>()) {
100    return FileRef(PASS_REF,
101                   get_interface<PPB_FileRef_1_2>()->GetParent(pp_resource()));
102  }
103  if (has_interface<PPB_FileRef_1_1>()) {
104    return FileRef(PASS_REF,
105                   get_interface<PPB_FileRef_1_1>()->GetParent(pp_resource()));
106  }
107  if (has_interface<PPB_FileRef_1_0>()) {
108    return FileRef(PASS_REF,
109                   get_interface<PPB_FileRef_1_0>()->GetParent(pp_resource()));
110  }
111  return FileRef();
112}
113
114int32_t FileRef::MakeDirectory(int32_t make_directory_flags,
115                               const CompletionCallback& cc) {
116  if (has_interface<PPB_FileRef_1_2>()) {
117    return get_interface<PPB_FileRef_1_2>()->MakeDirectory(
118        pp_resource(),
119        make_directory_flags,
120        cc.pp_completion_callback());
121  }
122  if (has_interface<PPB_FileRef_1_1>()) {
123    if (make_directory_flags & ~PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS)
124      return cc.MayForce(PP_ERROR_NOTSUPPORTED);
125    return get_interface<PPB_FileRef_1_1>()->MakeDirectory(
126        pp_resource(),
127        PP_FromBool(make_directory_flags & PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS),
128        cc.pp_completion_callback());
129  }
130  if (has_interface<PPB_FileRef_1_0>()) {
131    if (make_directory_flags & ~PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS)
132      return cc.MayForce(PP_ERROR_NOTSUPPORTED);
133    return get_interface<PPB_FileRef_1_0>()->MakeDirectory(
134        pp_resource(),
135        PP_FromBool(make_directory_flags & PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS),
136        cc.pp_completion_callback());
137  }
138  return cc.MayForce(PP_ERROR_NOINTERFACE);
139}
140
141int32_t FileRef::Touch(PP_Time last_access_time,
142                       PP_Time last_modified_time,
143                       const CompletionCallback& cc) {
144  if (has_interface<PPB_FileRef_1_2>()) {
145    return get_interface<PPB_FileRef_1_2>()->Touch(
146        pp_resource(), last_access_time, last_modified_time,
147        cc.pp_completion_callback());
148  }
149  if (has_interface<PPB_FileRef_1_1>()) {
150    return get_interface<PPB_FileRef_1_1>()->Touch(
151        pp_resource(), last_access_time, last_modified_time,
152        cc.pp_completion_callback());
153  }
154  if (has_interface<PPB_FileRef_1_0>()) {
155    return get_interface<PPB_FileRef_1_0>()->Touch(
156        pp_resource(), last_access_time, last_modified_time,
157        cc.pp_completion_callback());
158  }
159  return cc.MayForce(PP_ERROR_NOINTERFACE);
160}
161
162int32_t FileRef::Delete(const CompletionCallback& cc) {
163  if (has_interface<PPB_FileRef_1_2>()) {
164    return get_interface<PPB_FileRef_1_2>()->Delete(
165        pp_resource(), cc.pp_completion_callback());
166  }
167  if (has_interface<PPB_FileRef_1_1>()) {
168    return get_interface<PPB_FileRef_1_1>()->Delete(
169        pp_resource(), cc.pp_completion_callback());
170  }
171  if (has_interface<PPB_FileRef_1_0>()) {
172    return get_interface<PPB_FileRef_1_0>()->Delete(
173        pp_resource(), cc.pp_completion_callback());
174  }
175  return cc.MayForce(PP_ERROR_NOINTERFACE);
176}
177
178int32_t FileRef::Rename(const FileRef& new_file_ref,
179                        const CompletionCallback& cc) {
180  if (has_interface<PPB_FileRef_1_2>()) {
181    return get_interface<PPB_FileRef_1_2>()->Rename(
182        pp_resource(), new_file_ref.pp_resource(), cc.pp_completion_callback());
183  }
184  if (has_interface<PPB_FileRef_1_1>()) {
185    return get_interface<PPB_FileRef_1_1>()->Rename(
186        pp_resource(), new_file_ref.pp_resource(), cc.pp_completion_callback());
187  }
188  if (has_interface<PPB_FileRef_1_0>()) {
189    return get_interface<PPB_FileRef_1_0>()->Rename(
190        pp_resource(), new_file_ref.pp_resource(), cc.pp_completion_callback());
191  }
192  return cc.MayForce(PP_ERROR_NOINTERFACE);
193}
194
195int32_t FileRef::Query(const CompletionCallbackWithOutput<PP_FileInfo>& cc) {
196  if (has_interface<PPB_FileRef_1_2>()) {
197    return get_interface<PPB_FileRef_1_2>()->Query(
198        pp_resource(), cc.output(), cc.pp_completion_callback());
199  }
200  if (has_interface<PPB_FileRef_1_1>()) {
201    return get_interface<PPB_FileRef_1_1>()->Query(
202        pp_resource(), cc.output(), cc.pp_completion_callback());
203  }
204  return cc.MayForce(PP_ERROR_NOINTERFACE);
205}
206
207int32_t FileRef::ReadDirectoryEntries(
208    const CompletionCallbackWithOutput<std::vector<DirectoryEntry> >&
209        callback) {
210  if (has_interface<PPB_FileRef_1_2>()) {
211    return get_interface<PPB_FileRef_1_2>()->ReadDirectoryEntries(
212        pp_resource(), callback.output(), callback.pp_completion_callback());
213  }
214  if (has_interface<PPB_FileRef_1_1>()) {
215    return get_interface<PPB_FileRef_1_1>()->ReadDirectoryEntries(
216        pp_resource(), callback.output(), callback.pp_completion_callback());
217  }
218  return callback.MayForce(PP_ERROR_NOINTERFACE);
219}
220
221}  // namespace pp
222