1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file.
4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include <sstream>
6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/c/ppb_file_io.h"
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/cpp/file_io.h"
9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/cpp/file_ref.h"
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/cpp/instance.h"
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/cpp/module.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/cpp/private/isolated_file_system_private.h"
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h"
14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// When compiling natively on Windows, PostMessage can be #define-d to
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// something else.
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#ifdef PostMessage
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#undef PostMessage
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Buffer size for reading file.
22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const size_t kBufSize = 1024;
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class MyInstance : public pp::Instance {
25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  explicit MyInstance(PP_Instance instance)
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      : pp::Instance(instance),
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        handle_(instance) {
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    factory_.Initialize(this);
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual ~MyInstance() {
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Handler for the page sending us messages.
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void HandleMessage(const pp::Var& message_data);
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private:
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void OpenCrxFsAndReadFile(const std::string& filename);
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void CrxFileSystemCallback(int32_t pp_error, pp::FileSystem file_system);
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void FileIOOpenCallback(int32_t pp_error);
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void FileIOReadCallback(int32_t pp_error);
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Forwards the given string to the page.
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void ReportResponse(const char* name, int32_t pp_error);
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Generates completion callbacks scoped to this class.
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  pp::CompletionCallbackFactory<MyInstance> factory_;
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  pp::InstanceHandle handle_;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pp::IsolatedFileSystemPrivate crxfs_;
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  pp::FileRef file_ref_;
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  pp::FileIO file_io_;
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string filename_;
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  char read_buf_[kBufSize];
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::HandleMessage(const pp::Var& message_data) {
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!message_data.is_string()) {
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("HandleMessage: not a string", 0);
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string filename = message_data.AsString();
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  OpenCrxFsAndReadFile(filename);
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::OpenCrxFsAndReadFile(const std::string& filename) {
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  filename_ = filename;
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  pp::CompletionCallbackWithOutput<pp::FileSystem> callback =
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      factory_.NewCallbackWithOutput(&MyInstance::CrxFileSystemCallback);
72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  crxfs_ = pp::IsolatedFileSystemPrivate(
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this, PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX);
75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int32_t rv = crxfs_.Open(callback);
76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (rv != PP_OK_COMPLETIONPENDING)
77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("ExtCrxFileSystemPrivate::Open", rv);
78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::CrxFileSystemCallback(int32_t pp_error,
81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                       pp::FileSystem file_system) {
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (pp_error != PP_OK) {
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("CrxFileSystemCallback", pp_error);
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  file_io_ = pp::FileIO(handle_);
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  file_ref_ = pp::FileRef(file_system, filename_.c_str());
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int32_t rv = file_io_.Open(
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      file_ref_, PP_FILEOPENFLAG_READ,
91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      factory_.NewCallback(&MyInstance::FileIOOpenCallback));
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (rv != PP_OK_COMPLETIONPENDING)
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("FileIO::Open", rv);
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::FileIOOpenCallback(int32_t pp_error) {
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (pp_error != PP_OK) {
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("FileIOOpenCallback", pp_error);
99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int32_t rv = file_io_.Read(0, read_buf_, sizeof(read_buf_),
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      factory_.NewCallback(&MyInstance::FileIOReadCallback));
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (rv != PP_OK_COMPLETIONPENDING) {
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("FileIO::Read", rv);
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::FileIOReadCallback(int32_t pp_error) {
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (pp_error < 0) {
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ReportResponse("FileIOReadCallback", pp_error);
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return;
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string content;
117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  content.append(read_buf_, pp_error);
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  PostMessage(pp::Var(content));
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void MyInstance::ReportResponse(const char* name, int32_t rv) {
122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::ostringstream out;
123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  out << name << " failed, pp_error: " << rv;
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  PostMessage(pp::Var(out.str()));
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// This object is the global object representing this plugin library as long
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// as it is loaded.
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class MyModule : public pp::Module {
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  MyModule() : pp::Module() {}
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual ~MyModule() {}
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Override CreateInstance to create your customized Instance object.
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual pp::Instance* CreateInstance(PP_Instance instance) {
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return new MyInstance(instance);
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace pp {
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Factory function for your specialization of the Module object.
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)Module* CreateModule() {
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return new MyModule();
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace pp
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
149