| Index: native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_file_ref_interface.cc
 | 
| diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_file_ref_interface.cc b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_file_ref_interface.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..f103678fdef18f3d97b6318d2d013b0f179f9ce2
 | 
| --- /dev/null
 | 
| +++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_file_ref_interface.cc
 | 
| @@ -0,0 +1,220 @@
 | 
| +// Copyright 2016 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.
 | 
| +
 | 
| +#include "fake_ppapi/fake_file_ref_interface.h"
 | 
| +
 | 
| +#include <string.h>
 | 
| +
 | 
| +#include <algorithm>
 | 
| +#include <vector>
 | 
| +
 | 
| +#include <ppapi/c/pp_completion_callback.h>
 | 
| +#include <ppapi/c/pp_directory_entry.h>
 | 
| +#include <ppapi/c/pp_errors.h>
 | 
| +
 | 
| +#include "gtest/gtest.h"
 | 
| +
 | 
| +#include "fake_ppapi/fake_core_interface.h"
 | 
| +#include "fake_ppapi/fake_filesystem.h"
 | 
| +#include "fake_ppapi/fake_node.h"
 | 
| +#include "fake_ppapi/fake_util.h"
 | 
| +#include "fake_ppapi/fake_var_interface.h"
 | 
| +
 | 
| +FakeFileRefInterface::FakeFileRefInterface(FakeCoreInterface* core_interface,
 | 
| +                                           FakeVarInterface* var_interface)
 | 
| +    : core_interface_(core_interface), var_interface_(var_interface) {}
 | 
| +
 | 
| +PP_Resource FakeFileRefInterface::Create(PP_Resource file_system,
 | 
| +                                         const char* path) {
 | 
| +  FakeFileSystemResource* file_system_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileSystemResource>(
 | 
| +          file_system);
 | 
| +  if (file_system_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  if (!file_system_resource->opened)
 | 
| +    return PP_ERROR_FAILED;
 | 
| +
 | 
| +  if (path == NULL)
 | 
| +    return PP_ERROR_FAILED;
 | 
| +
 | 
| +  size_t path_len = strlen(path);
 | 
| +  if (path_len == 0)
 | 
| +    return PP_ERROR_FAILED;
 | 
| +
 | 
| +  FakeFileRefResource* file_ref_resource = new FakeFileRefResource;
 | 
| +  file_ref_resource->filesystem = file_system_resource->filesystem;
 | 
| +  file_ref_resource->path = path;
 | 
| +
 | 
| +  // Remove a trailing slash from the path, unless it is the root path.
 | 
| +  if (path_len > 1 && file_ref_resource->path[path_len - 1] == '/')
 | 
| +    file_ref_resource->path.erase(path_len - 1);
 | 
| +
 | 
| +  return CREATE_RESOURCE(core_interface_->resource_manager(),
 | 
| +                         FakeFileRefResource, file_ref_resource);
 | 
| +}
 | 
| +
 | 
| +PP_Var FakeFileRefInterface::GetName(PP_Resource file_ref) {
 | 
| +  FakeFileRefResource* file_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(file_ref);
 | 
| +  if (file_ref_resource == NULL)
 | 
| +    return PP_MakeUndefined();
 | 
| +
 | 
| +  return var_interface_->VarFromUtf8(file_ref_resource->path.c_str(),
 | 
| +                                     file_ref_resource->path.size());
 | 
| +}
 | 
| +
 | 
| +int32_t FakeFileRefInterface::MakeDirectory(PP_Resource directory_ref,
 | 
| +                                            PP_Bool make_parents,
 | 
| +                                            PP_CompletionCallback callback) {
 | 
| +  FakeFileRefResource* directory_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(
 | 
| +          directory_ref);
 | 
| +  if (directory_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  // TODO(binji): We don't currently use make_parents in nacl_io, so
 | 
| +  // I won't bother handling it yet.
 | 
| +  if (make_parents == PP_TRUE)
 | 
| +    return PP_ERROR_FAILED;
 | 
| +
 | 
| +  FakeFilesystem* filesystem = directory_ref_resource->filesystem;
 | 
| +  FakeFilesystem::Path path = directory_ref_resource->path;
 | 
| +
 | 
| +  // Pepper returns PP_ERROR_NOACCESS when trying to create the root directory,
 | 
| +  // not PP_ERROR_FILEEXISTS, as you might expect.
 | 
| +  if (path == "/")
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_NOACCESS);
 | 
| +
 | 
| +  FakeNode* node = filesystem->GetNode(path);
 | 
| +  if (node != NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILEEXISTS);
 | 
| +
 | 
| +  FakeFilesystem::Path parent_path = filesystem->GetParentPath(path);
 | 
| +  FakeNode* parent_node = filesystem->GetNode(parent_path);
 | 
| +  if (parent_node == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILENOTFOUND);
 | 
| +
 | 
| +  if (!parent_node->IsDirectory())
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FAILED);
 | 
| +
 | 
| +  bool result = filesystem->AddDirectory(directory_ref_resource->path, NULL);
 | 
| +  EXPECT_EQ(true, result);
 | 
| +  return RunCompletionCallback(&callback, PP_OK);
 | 
| +}
 | 
| +
 | 
| +int32_t FakeFileRefInterface::Delete(PP_Resource file_ref,
 | 
| +                                     PP_CompletionCallback callback) {
 | 
| +  FakeFileRefResource* file_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(file_ref);
 | 
| +  if (file_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  FakeFilesystem* filesystem = file_ref_resource->filesystem;
 | 
| +  FakeFilesystem::Path path = file_ref_resource->path;
 | 
| +  FakeNode* node = filesystem->GetNode(path);
 | 
| +  if (node == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILENOTFOUND);
 | 
| +
 | 
| +  filesystem->RemoveNode(path);
 | 
| +  return RunCompletionCallback(&callback, PP_OK);
 | 
| +}
 | 
| +
 | 
| +int32_t FakeFileRefInterface::Query(PP_Resource file_ref,
 | 
| +                                    PP_FileInfo* info,
 | 
| +                                    PP_CompletionCallback callback) {
 | 
| +  FakeFileRefResource* file_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(file_ref);
 | 
| +  if (file_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  FakeFilesystem* filesystem = file_ref_resource->filesystem;
 | 
| +  FakeFilesystem::Path path = file_ref_resource->path;
 | 
| +  FakeNode* node = filesystem->GetNode(path);
 | 
| +  if (node == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILENOTFOUND);
 | 
| +
 | 
| +  node->GetInfo(info);
 | 
| +  return RunCompletionCallback(&callback, PP_OK);
 | 
| +}
 | 
| +
 | 
| +int32_t FakeFileRefInterface::ReadDirectoryEntries(
 | 
| +    PP_Resource directory_ref,
 | 
| +    const PP_ArrayOutput& output,
 | 
| +    PP_CompletionCallback callback) {
 | 
| +  FakeFileRefResource* directory_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(
 | 
| +          directory_ref);
 | 
| +  if (directory_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  FakeFilesystem* filesystem = directory_ref_resource->filesystem;
 | 
| +  FakeFilesystem::Path path = directory_ref_resource->path;
 | 
| +  FakeNode* node = filesystem->GetNode(path);
 | 
| +  if (node == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILENOTFOUND);
 | 
| +
 | 
| +  if (!node->IsDirectory())
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FAILED);
 | 
| +
 | 
| +  FakeFilesystem::DirectoryEntries fake_dir_entries;
 | 
| +  filesystem->GetDirectoryEntries(path, &fake_dir_entries);
 | 
| +
 | 
| +  uint32_t element_count = fake_dir_entries.size();
 | 
| +  uint32_t element_size = sizeof(fake_dir_entries[0]);
 | 
| +  void* data_buffer =
 | 
| +      (*output.GetDataBuffer)(output.user_data, element_count, element_size);
 | 
| +
 | 
| +  if (data_buffer == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FAILED);
 | 
| +
 | 
| +  PP_DirectoryEntry* dir_entries = static_cast<PP_DirectoryEntry*>(data_buffer);
 | 
| +  for (uint32_t i = 0; i < element_count; ++i) {
 | 
| +    const FakeFilesystem::DirectoryEntry& fake_dir_entry = fake_dir_entries[i];
 | 
| +
 | 
| +    FakeFileRefResource* file_ref_resource = new FakeFileRefResource;
 | 
| +    file_ref_resource->filesystem = directory_ref_resource->filesystem;
 | 
| +    file_ref_resource->path = fake_dir_entry.path;
 | 
| +    PP_Resource file_ref =
 | 
| +        CREATE_RESOURCE(core_interface_->resource_manager(),
 | 
| +                        FakeFileRefResource, file_ref_resource);
 | 
| +
 | 
| +    dir_entries[i].file_ref = file_ref;
 | 
| +    dir_entries[i].file_type = fake_dir_entry.node->file_type();
 | 
| +  }
 | 
| +
 | 
| +  return RunCompletionCallback(&callback, PP_OK);
 | 
| +}
 | 
| +
 | 
| +int32_t FakeFileRefInterface::Rename(PP_Resource file_ref,
 | 
| +                                     PP_Resource new_file_ref,
 | 
| +                                     PP_CompletionCallback callback) {
 | 
| +  FakeFileRefResource* file_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(file_ref);
 | 
| +  if (file_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  FakeFileRefResource* new_file_ref_resource =
 | 
| +      core_interface_->resource_manager()->Get<FakeFileRefResource>(
 | 
| +          new_file_ref);
 | 
| +  if (new_file_ref_resource == NULL)
 | 
| +    return PP_ERROR_BADRESOURCE;
 | 
| +
 | 
| +  FakeFilesystem* filesystem = file_ref_resource->filesystem;
 | 
| +  FakeFilesystem::Path path = file_ref_resource->path;
 | 
| +  FakeFilesystem::Path newpath = new_file_ref_resource->path;
 | 
| +  FakeNode* node = filesystem->GetNode(path);
 | 
| +  if (node == NULL)
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_FILENOTFOUND);
 | 
| +  // FakeFileRefResource does not support directory rename.
 | 
| +  if (!node->IsRegular())
 | 
| +    return RunCompletionCallback(&callback, PP_ERROR_NOTAFILE);
 | 
| +
 | 
| +  // Remove the destination if it exists.
 | 
| +  filesystem->RemoveNode(newpath);
 | 
| +  const std::vector<uint8_t> contents = node->contents();
 | 
| +  EXPECT_TRUE(filesystem->AddFile(newpath, contents, NULL));
 | 
| +  EXPECT_TRUE(filesystem->RemoveNode(path));
 | 
| +  return RunCompletionCallback(&callback, PP_OK);
 | 
| +}
 | 
| 
 |