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/c/pp_file_info.h"
6#include "ppapi/c/ppb_file_ref.h"
7#include "ppapi/c/pp_completion_callback.h"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/c/private/ppb_file_ref_private.h"
10#include "ppapi/shared_impl/file_ref_create_info.h"
11#include "ppapi/shared_impl/proxy_lock.h"
12#include "ppapi/shared_impl/tracked_callback.h"
13#include "ppapi/thunk/enter.h"
14#include "ppapi/thunk/thunk.h"
15#include "ppapi/thunk/ppb_file_ref_api.h"
16#include "ppapi/thunk/ppb_file_system_api.h"
17#include "ppapi/thunk/resource_creation_api.h"
18
19namespace ppapi {
20namespace thunk {
21
22namespace {
23
24typedef EnterResource<PPB_FileRef_API> EnterFileRef;
25
26PP_Resource Create(PP_Resource file_system, const char* path) {
27  VLOG(4) << "PPB_FileRef::Create()";
28  ppapi::ProxyAutoLock lock;
29  EnterResourceNoLock<PPB_FileSystem_API> enter_file_system(file_system, true);
30  if (enter_file_system.failed())
31    return 0;
32  PP_Instance instance = enter_file_system.resource()->pp_instance();
33  EnterResourceCreationNoLock enter(instance);
34  if (enter.failed())
35    return 0;
36  FileRefCreateInfo info;
37  info.file_system_type = enter_file_system.object()->GetType();
38  info.internal_path = std::string(path);
39  info.browser_pending_host_resource_id = 0;
40  info.renderer_pending_host_resource_id = 0;
41  info.file_system_plugin_resource = file_system;
42  return enter.functions()->CreateFileRef(instance, info);
43}
44
45PP_Bool IsFileRef(PP_Resource resource) {
46  VLOG(4) << "PPB_FileRef::IsFileRef()";
47  EnterFileRef enter(resource, false);
48  return PP_FromBool(enter.succeeded());
49}
50
51PP_FileSystemType GetFileSystemType(PP_Resource file_ref) {
52  VLOG(4) << "PPB_FileRef::GetFileSystemType()";
53  EnterFileRef enter(file_ref, true);
54  if (enter.failed())
55    return PP_FILESYSTEMTYPE_INVALID;
56  return enter.object()->GetFileSystemType();
57}
58
59PP_Var GetName(PP_Resource file_ref) {
60  VLOG(4) << "PPB_FileRef::GetName()";
61  EnterFileRef enter(file_ref, true);
62  if (enter.failed())
63    return PP_MakeUndefined();
64  return enter.object()->GetName();
65}
66
67PP_Var GetPath(PP_Resource file_ref) {
68  VLOG(4) << "PPB_FileRef::GetPath()";
69  EnterFileRef enter(file_ref, true);
70  if (enter.failed())
71    return PP_MakeUndefined();
72  return enter.object()->GetPath();
73}
74
75PP_Resource GetParent(PP_Resource file_ref) {
76  VLOG(4) << "PPB_FileRef::GetParent()";
77  EnterFileRef enter(file_ref, true);
78  if (enter.failed())
79    return 0;
80  return enter.object()->GetParent();
81}
82
83int32_t MakeDirectory(PP_Resource directory_ref,
84                      PP_Bool make_ancestors,
85                      PP_CompletionCallback callback) {
86  VLOG(4) << "PPB_FileRef::MakeDirectory()";
87  EnterFileRef enter(directory_ref, callback, true);
88  if (enter.failed())
89    return enter.retval();
90  int32_t flag = make_ancestors ? PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS
91                                : PP_MAKEDIRECTORYFLAG_NONE;
92  return enter.SetResult(enter.object()->MakeDirectory(
93      flag, enter.callback()));
94}
95
96int32_t MakeDirectory_1_2(PP_Resource directory_ref,
97                          int32_t make_directory_flags,
98                          PP_CompletionCallback callback) {
99  VLOG(4) << "PPB_FileRef::MakeDirectory()";
100  EnterFileRef enter(directory_ref, callback, true);
101  if (enter.failed())
102    return enter.retval();
103  return enter.SetResult(enter.object()->MakeDirectory(
104      make_directory_flags, enter.callback()));
105}
106
107int32_t Touch(PP_Resource file_ref,
108              PP_Time last_access_time,
109              PP_Time last_modified_time,
110              PP_CompletionCallback callback) {
111  VLOG(4) << "PPB_FileRef::Touch()";
112  EnterFileRef enter(file_ref, callback, true);
113  if (enter.failed())
114    return enter.retval();
115  return enter.SetResult(enter.object()->Touch(
116      last_access_time, last_modified_time, enter.callback()));
117}
118
119int32_t Delete(PP_Resource file_ref,
120               PP_CompletionCallback callback) {
121  VLOG(4) << "PPB_FileRef::Delete()";
122  EnterFileRef enter(file_ref, callback, true);
123  if (enter.failed())
124    return enter.retval();
125  return enter.SetResult(enter.object()->Delete(enter.callback()));
126}
127
128int32_t Rename(PP_Resource file_ref,
129               PP_Resource new_file_ref,
130               PP_CompletionCallback callback) {
131  VLOG(4) << "PPB_FileRef::Rename()";
132  EnterFileRef enter(file_ref, callback, true);
133  if (enter.failed())
134    return enter.retval();
135  return enter.SetResult(enter.object()->Rename(new_file_ref,
136                                                enter.callback()));
137}
138
139int32_t Query(PP_Resource file_ref,
140              PP_FileInfo* info,
141              PP_CompletionCallback callback) {
142  VLOG(4) << "PPB_FileRef::Query()";
143  EnterFileRef enter(file_ref, callback, true);
144  if (enter.failed())
145    return enter.retval();
146  return enter.SetResult(enter.object()->Query(info,
147                                               enter.callback()));
148}
149
150int32_t ReadDirectoryEntries(PP_Resource file_ref,
151                             PP_ArrayOutput output,
152                             PP_CompletionCallback callback) {
153  EnterFileRef enter(file_ref, callback, true);
154  if (enter.failed())
155    return enter.retval();
156  return enter.SetResult(enter.object()->ReadDirectoryEntries(
157      output, enter.callback()));
158}
159
160PP_Var GetAbsolutePath(PP_Resource file_ref) {
161  VLOG(4) << "PPB_FileRef::GetAbsolutePath";
162  EnterFileRef enter(file_ref, true);
163  if (enter.failed())
164    return PP_MakeUndefined();
165  return enter.object()->GetAbsolutePath();
166}
167
168const PPB_FileRef_1_0 g_ppb_file_ref_thunk_1_0 = {
169  &Create,
170  &IsFileRef,
171  &GetFileSystemType,
172  &GetName,
173  &GetPath,
174  &GetParent,
175  &MakeDirectory,
176  &Touch,
177  &Delete,
178  &Rename
179};
180
181const PPB_FileRef_1_1 g_ppb_file_ref_thunk_1_1 = {
182  &Create,
183  &IsFileRef,
184  &GetFileSystemType,
185  &GetName,
186  &GetPath,
187  &GetParent,
188  &MakeDirectory,
189  &Touch,
190  &Delete,
191  &Rename,
192  &Query,
193  &ReadDirectoryEntries
194};
195
196const PPB_FileRef_1_2 g_ppb_file_ref_thunk_1_2 = {
197  &Create,
198  &IsFileRef,
199  &GetFileSystemType,
200  &GetName,
201  &GetPath,
202  &GetParent,
203  &MakeDirectory_1_2,
204  &Touch,
205  &Delete,
206  &Rename,
207  &Query,
208  &ReadDirectoryEntries
209};
210
211const PPB_FileRefPrivate g_ppb_file_ref_private_thunk = {
212  &GetAbsolutePath
213};
214
215}  // namespace
216
217const PPB_FileRef_1_0* GetPPB_FileRef_1_0_Thunk() {
218  return &g_ppb_file_ref_thunk_1_0;
219}
220
221const PPB_FileRef_1_1* GetPPB_FileRef_1_1_Thunk() {
222  return &g_ppb_file_ref_thunk_1_1;
223}
224
225const PPB_FileRef_1_2* GetPPB_FileRef_1_2_Thunk() {
226  return &g_ppb_file_ref_thunk_1_2;
227}
228
229const PPB_FileRefPrivate_0_1* GetPPB_FileRefPrivate_0_1_Thunk() {
230  return &g_ppb_file_ref_private_thunk;
231}
232
233}  // namespace thunk
234}  // namespace ppapi
235