1 // Copyright 2014 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.
7 #include "ppapi/c/ppb_file_io.h"
8 #include "ppapi/cpp/file_io.h"
9 #include "ppapi/cpp/file_ref.h"
10 #include "ppapi/cpp/file_system.h"
11 #include "ppapi/cpp/instance.h"
12 #include "ppapi/cpp/module.h"
13 #include "ppapi/cpp/var.h"
14 #include "ppapi/cpp/var_dictionary.h"
15 #include "ppapi/tests/test_utils.h"
17 /// The Instance class. Receives the file through HandleMessage(), and returns
18 /// data to the plugin with PostMessage().
19 class FilePassingInstance
: public pp::Instance
{
21 /// The constructor creates the plugin-side instance.
22 /// @param[in] instance the handle to the browser-side plugin instance.
23 explicit FilePassingInstance(PP_Instance instance
);
24 virtual ~FilePassingInstance();
26 virtual bool Init(uint32_t argc
, const char* argn
[], const char* argv
[]);
29 /// Handler for messages coming in from the browser via postMessage().
30 /// @param[in] var_message The message posted by the browser.
31 virtual void HandleMessage(const pp::Var
& var_message
);
33 /// Takes a fileEntry-dictionary message received from JavaScript and converts
34 /// it into a pp::FileRef. On failure, returns a null FileRef.
35 pp::FileRef
ParseMessage(const pp::Var
& var_message
, std::string
* test_type
);
37 void TestRead(pp::FileRef file_ref
);
38 void TestWrite(pp::FileRef file_ref
);
41 FilePassingInstance::FilePassingInstance(PP_Instance instance
)
42 : pp::Instance(instance
) {}
44 FilePassingInstance::~FilePassingInstance() {}
46 bool FilePassingInstance::Init(uint32_t argc
,
53 pp::FileRef
FilePassingInstance::ParseMessage(const pp::Var
& var_message
,
54 std::string
* test_type
) {
55 if (!var_message
.is_dictionary()) {
56 PostMessage("Message was not a dictionary.");
59 pp::VarDictionary
var_dictionary_message(var_message
);
60 pp::Var var_filesystem
= var_dictionary_message
.Get("filesystem");
61 pp::Var var_fullpath
= var_dictionary_message
.Get("fullPath");
62 pp::Var var_testtype
= var_dictionary_message
.Get("testType");
64 if (!var_filesystem
.is_resource()) {
65 PostMessage("Filesystem was missing or not a resource.");
68 pp::Resource resource_filesystem
= var_filesystem
.AsResource();
69 if (!var_fullpath
.is_string()) {
70 PostMessage("FullPath was missing or not a string.");
73 std::string fullpath
= var_fullpath
.AsString();
74 if (!var_testtype
.is_string()) {
75 PostMessage("TestType was missing or not a string.");
78 std::string name_of_test
= var_testtype
.AsString();
80 if (!pp::FileSystem::IsFileSystem(resource_filesystem
)) {
81 PostMessage("Filesystem was not a file system.");
85 *test_type
= name_of_test
;
86 pp::FileSystem
filesystem(resource_filesystem
);
87 // Note: The filesystem is already open (there is no need to call Open again).
89 return pp::FileRef(filesystem
, fullpath
.c_str());
92 void FilePassingInstance::HandleMessage(const pp::Var
& var_message
) {
93 // Extract the filesystem and fullPath from the message.
94 std::string test_type
;
95 pp::FileRef file_ref
= ParseMessage(var_message
, &test_type
);
96 if (file_ref
.is_null())
99 if (test_type
== "read_test") {
101 } else if (test_type
== "write_test") {
104 PostMessage("Unknown test type");
108 void FilePassingInstance::TestRead(pp::FileRef file_ref
) {
109 pp::FileIO
file_io(pp::InstanceHandle(this));
112 TestCompletionCallback
callback(pp_instance(), PP_REQUIRED
);
113 callback
.WaitForResult(
114 file_io
.Open(file_ref
, PP_FILEOPENFLAG_READ
, callback
.GetCallback()));
115 if (callback
.result() != PP_OK
) {
116 PostMessage("Could not open file");
121 TestCompletionCallbackWithOutput
<std::vector
<char> > callback(pp_instance(),
123 callback
.WaitForResult(
124 file_io
.Read(0, 1024, callback
.GetCallback()));
125 if (callback
.result() < 0) {
126 PostMessage("Could not read file");
130 if (callback
.output().size() != 306) {
131 PostMessage("Read the wrong number of bytes");
135 PostMessage("read_success");
138 void FilePassingInstance::TestWrite(pp::FileRef file_ref
) {
139 pp::FileIO
file_io(pp::InstanceHandle(this));
140 TestCompletionCallback
callback(pp_instance(), PP_REQUIRED
);
141 callback
.WaitForResult(
142 file_io
.Open(file_ref
, PP_FILEOPENFLAG_WRITE
, callback
.GetCallback()));
143 if (callback
.result() != PP_ERROR_NOACCESS
) {
144 PostMessage("Opening for write should have failed");
147 PostMessage("write_success");
150 class FilePassingModule
: public pp::Module
{
152 FilePassingModule() : pp::Module() {}
153 virtual ~FilePassingModule() {}
155 virtual pp::Instance
* CreateInstance(PP_Instance instance
) {
156 return new FilePassingInstance(instance
);
162 Module
* CreateModule() {
163 return new FilePassingModule();