1 // Copyright (c) 2012 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.
5 // This example shows how to use the URLLoader in "stream to file" mode where
6 // the browser writes incoming data to a file, which you can read out via the
9 // This example uses PostMessage between the plugin and the url_loader.html
10 // page in this directory to start the load and to communicate the result.
12 #include "ppapi/c/ppb_file_io.h"
13 #include "ppapi/cpp/file_io.h"
14 #include "ppapi/cpp/file_ref.h"
15 #include "ppapi/cpp/instance.h"
16 #include "ppapi/cpp/module.h"
17 #include "ppapi/cpp/url_loader.h"
18 #include "ppapi/cpp/url_request_info.h"
19 #include "ppapi/cpp/url_response_info.h"
20 #include "ppapi/utility/completion_callback_factory.h"
22 // When compiling natively on Windows, PostMessage can be #define-d to
28 // Buffer size for reading network data.
29 const int kBufSize
= 1024;
31 class MyInstance
: public pp::Instance
{
33 explicit MyInstance(PP_Instance instance
)
34 : pp::Instance(instance
) {
35 factory_
.Initialize(this);
37 virtual ~MyInstance() {
38 // Make sure to explicitly close the loader. If somebody else is holding a
39 // reference to the URLLoader object when this class goes out of scope (so
40 // the URLLoader outlives "this"), and you have an outstanding read
41 // request, the URLLoader will write into invalid memory.
45 // Handler for the page sending us messages.
46 virtual void HandleMessage(const pp::Var
& message_data
);
49 // Called to initiate the request.
50 void StartRequest(const std::string
& url
);
52 // Callback for the URLLoader to tell us it finished opening the connection.
53 void OnOpenComplete(int32_t result
);
55 // Callback for when the file is completely filled with the download
56 void OnStreamComplete(int32_t result
);
58 void OnOpenFileComplete(int32_t result
);
59 void OnReadComplete(int32_t result
);
61 // Forwards the given string to the page.
62 void ReportResponse(const std::string
& data
);
64 // Generates completion callbacks scoped to this class.
65 pp::CompletionCallbackFactory
<MyInstance
> factory_
;
67 pp::URLLoader loader_
;
68 pp::URLResponseInfo response_
;
69 pp::FileRef dest_file_
;
72 // The buffer used for the current read request. This is filled and then
73 // copied into content_ to build up the entire document.
76 // All the content loaded so far.
80 void MyInstance::HandleMessage(const pp::Var
& message_data
) {
81 if (message_data
.is_string() && message_data
.AsString() == "go")
82 StartRequest("./fetched_content.html");
85 void MyInstance::StartRequest(const std::string
& url
) {
88 pp::URLRequestInfo
request(this);
90 request
.SetMethod("GET");
91 request
.SetStreamToFile(true);
93 loader_
= pp::URLLoader(this);
95 factory_
.NewCallback(&MyInstance::OnOpenComplete
));
98 void MyInstance::OnOpenComplete(int32_t result
) {
99 if (result
!= PP_OK
) {
100 ReportResponse("URL could not be requested");
104 loader_
.FinishStreamingToFile(
105 factory_
.NewCallback(&MyInstance::OnStreamComplete
));
106 response_
= loader_
.GetResponseInfo();
107 dest_file_
= response_
.GetBodyAsFileRef();
110 void MyInstance::OnStreamComplete(int32_t result
) {
111 if (result
== PP_OK
) {
112 file_io_
= pp::FileIO(this);
113 file_io_
.Open(dest_file_
, PP_FILEOPENFLAG_READ
,
114 factory_
.NewCallback(&MyInstance::OnOpenFileComplete
));
116 ReportResponse("Could not stream to file");
120 void MyInstance::OnOpenFileComplete(int32_t result
) {
121 if (result
== PP_OK
) {
122 // Note we only read the first 1024 bytes from the file in this example
123 // to keep things simple. Please see a file I/O example for more details
125 file_io_
.Read(0, buf_
, kBufSize
,
126 factory_
.NewCallback(&MyInstance::OnReadComplete
));
128 ReportResponse("Could not open file");
132 void MyInstance::OnReadComplete(int32_t result
) {
134 content_
.append(buf_
, result
);
135 ReportResponse(buf_
);
137 ReportResponse("Could not read file");
140 // Release everything.
141 loader_
= pp::URLLoader();
142 response_
= pp::URLResponseInfo();
143 dest_file_
= pp::FileRef();
144 file_io_
= pp::FileIO();
147 void MyInstance::ReportResponse(const std::string
& data
) {
148 PostMessage(pp::Var(data
));
151 // This object is the global object representing this plugin library as long
153 class MyModule
: public pp::Module
{
155 MyModule() : pp::Module() {}
156 virtual ~MyModule() {}
158 // Override CreateInstance to create your customized Instance object.
159 virtual pp::Instance
* CreateInstance(PP_Instance instance
) {
160 return new MyInstance(instance
);
166 // Factory function for your specialization of the Module object.
167 Module
* CreateModule() {
168 return new MyModule();