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