Home | History | Annotate | Download | only in crxfs
      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/isolated_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.
     22 const size_t kBufSize = 1024;
     23 
     24 class 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::IsolatedFileSystemPrivate crxfs_;
     52   pp::FileRef file_ref_;
     53   pp::FileIO file_io_;
     54   std::string filename_;
     55   char read_buf_[kBufSize];
     56 };
     57 
     58 void 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 
     67 void 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::IsolatedFileSystemPrivate(
     74       this, PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX);
     75   int32_t rv = crxfs_.Open(callback);
     76   if (rv != PP_OK_COMPLETIONPENDING)
     77     ReportResponse("ExtCrxFileSystemPrivate::Open", rv);
     78 }
     79 
     80 void MyInstance::CrxFileSystemCallback(int32_t pp_error,
     81                                        pp::FileSystem file_system) {
     82   if (pp_error != PP_OK) {
     83     ReportResponse("CrxFileSystemCallback", pp_error);
     84     return;
     85   }
     86 
     87   file_io_ = pp::FileIO(handle_);
     88   file_ref_ = pp::FileRef(file_system, filename_.c_str());
     89   int32_t rv = file_io_.Open(
     90       file_ref_, PP_FILEOPENFLAG_READ,
     91       factory_.NewCallback(&MyInstance::FileIOOpenCallback));
     92   if (rv != PP_OK_COMPLETIONPENDING)
     93     ReportResponse("FileIO::Open", rv);
     94 }
     95 
     96 void MyInstance::FileIOOpenCallback(int32_t pp_error) {
     97   if (pp_error != PP_OK) {
     98     ReportResponse("FileIOOpenCallback", pp_error);
     99     return;
    100   }
    101 
    102   int32_t rv = file_io_.Read(0, read_buf_, sizeof(read_buf_),
    103       factory_.NewCallback(&MyInstance::FileIOReadCallback));
    104   if (rv != PP_OK_COMPLETIONPENDING) {
    105     ReportResponse("FileIO::Read", rv);
    106     return;
    107   }
    108 }
    109 
    110 void MyInstance::FileIOReadCallback(int32_t pp_error) {
    111   if (pp_error < 0) {
    112     ReportResponse("FileIOReadCallback", pp_error);
    113     return;
    114   }
    115 
    116   std::string content;
    117   content.append(read_buf_, pp_error);
    118   PostMessage(pp::Var(content));
    119 }
    120 
    121 void MyInstance::ReportResponse(const char* name, int32_t rv) {
    122   std::ostringstream out;
    123   out << name << " failed, pp_error: " << rv;
    124   PostMessage(pp::Var(out.str()));
    125 }
    126 
    127 // This object is the global object representing this plugin library as long
    128 // as it is loaded.
    129 class MyModule : public pp::Module {
    130  public:
    131   MyModule() : pp::Module() {}
    132   virtual ~MyModule() {}
    133 
    134   // Override CreateInstance to create your customized Instance object.
    135   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    136     return new MyInstance(instance);
    137   }
    138 };
    139 
    140 namespace pp {
    141 
    142 // Factory function for your specialization of the Module object.
    143 Module* CreateModule() {
    144   return new MyModule();
    145 }
    146 
    147 }  // namespace pp
    148 
    149