diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 20:11:06 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 20:11:06 +0000 |
commit | 844fecb93b985d0d975e4fd1c3ce5b7ad223047b (patch) | |
tree | e585258bbc43ce28efb53fd809ddf624cfb9fe24 /ppapi/examples | |
parent | 5909c79978cd7f940ed04ccbfe68c004636ceea5 (diff) | |
download | chromium_src-844fecb93b985d0d975e4fd1c3ce5b7ad223047b.zip chromium_src-844fecb93b985d0d975e4fd1c3ce5b7ad223047b.tar.gz chromium_src-844fecb93b985d0d975e4fd1c3ce5b7ad223047b.tar.bz2 |
Refactor the URLResponseInfo to use new design
This puts all of the URLResponseInfo attributes in a struct so it can be sent over IPC in one message rather than requiring one sync IPC per attribute access.
This includes a new example of streaming to a file that I used to do some manual tests of this change.
I added and improved some documentation that I noticed when trying to write the example.
Review URL: https://codereview.chromium.org/10993031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168273 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/examples')
-rw-r--r-- | ppapi/examples/url_loader/stream_to_file.cc | 171 | ||||
-rw-r--r-- | ppapi/examples/url_loader/streaming.cc | 4 |
2 files changed, 172 insertions, 3 deletions
diff --git a/ppapi/examples/url_loader/stream_to_file.cc b/ppapi/examples/url_loader/stream_to_file.cc new file mode 100644 index 0000000..887a9d7 --- /dev/null +++ b/ppapi/examples/url_loader/stream_to_file.cc @@ -0,0 +1,171 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This example shows how to use the URLLoader in "stream to file" mode where +// the browser writes incoming data to a file, which you can read out via the +// file I/O APIs. +// +// This example uses PostMessage between the plugin and the url_loader.html +// page in this directory to start the load and to communicate the result. + +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/file_ref.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/url_loader.h" +#include "ppapi/cpp/url_request_info.h" +#include "ppapi/cpp/url_response_info.h" +#include "ppapi/utility/completion_callback_factory.h" + +// When compiling natively on Windows, PostMessage can be #define-d to +// something else. +#ifdef PostMessage +#undef PostMessage +#endif + +// Buffer size for reading network data. +const int kBufSize = 1024; + +class MyInstance : public pp::Instance { + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance) { + factory_.Initialize(this); + } + virtual ~MyInstance() { + // Make sure to explicitly close the loader. If somebody else is holding a + // reference to the URLLoader object when this class goes out of scope (so + // the URLLoader outlives "this"), and you have an outstanding read + // request, the URLLoader will write into invalid memory. + loader_.Close(); + } + + // Handler for the page sending us messages. + virtual void HandleMessage(const pp::Var& message_data); + + private: + // Called to initiate the request. + void StartRequest(const std::string& url); + + // Callback for the URLLoader to tell us it finished opening the connection. + void OnOpenComplete(int32_t result); + + // Callback for when the file is completely filled with the download + void OnStreamComplete(int32_t result); + + void OnOpenFileComplete(int32_t result); + void OnReadComplete(int32_t result); + + // Forwards the given string to the page. + void ReportResponse(const std::string& data); + + // Generates completion callbacks scoped to this class. + pp::CompletionCallbackFactory<MyInstance> factory_; + + pp::URLLoader loader_; + pp::URLResponseInfo response_; + pp::FileRef dest_file_; + pp::FileIO file_io_; + + // The buffer used for the current read request. This is filled and then + // copied into content_ to build up the entire document. + char buf_[kBufSize]; + + // All the content loaded so far. + std::string content_; +}; + +void MyInstance::HandleMessage(const pp::Var& message_data) { + if (message_data.is_string() && message_data.AsString() == "go") + StartRequest("./fetched_content.html"); +} + +void MyInstance::StartRequest(const std::string& url) { + content_.clear(); + + pp::URLRequestInfo request(this); + request.SetURL(url); + request.SetMethod("GET"); + request.SetStreamToFile(true); + + loader_ = pp::URLLoader(this); + loader_.Open(request, + factory_.NewCallback(&MyInstance::OnOpenComplete)); +} + +void MyInstance::OnOpenComplete(int32_t result) { + if (result != PP_OK) { + ReportResponse("URL could not be requested"); + return; + } + + loader_.FinishStreamingToFile( + factory_.NewCallback(&MyInstance::OnStreamComplete)); + response_ = loader_.GetResponseInfo(); + dest_file_ = response_.GetBodyAsFileRef(); +} + +void MyInstance::OnStreamComplete(int32_t result) { + if (result == PP_OK) { + file_io_ = pp::FileIO(this); + file_io_.Open(dest_file_, PP_FILEOPENFLAG_READ, + factory_.NewCallback(&MyInstance::OnOpenFileComplete)); + } else { + ReportResponse("Could not stream to file"); + } +} + +void MyInstance::OnOpenFileComplete(int32_t result) { + if (result == PP_OK) { + // Note we only read the first 1024 bytes from the file in this example + // to keep things simple. Please see a file I/O example for more details + // on reading files. + file_io_.Read(0, buf_, kBufSize, + factory_.NewCallback(&MyInstance::OnReadComplete)); + } else { + ReportResponse("Could not open file"); + } +} + +void MyInstance::OnReadComplete(int32_t result) { + if (result >= 0) { + content_.append(buf_, result); + ReportResponse(buf_); + } else { + ReportResponse("Could not read file"); + } + + // Release everything. + loader_ = pp::URLLoader(); + response_ = pp::URLResponseInfo(); + dest_file_ = pp::FileRef(); + file_io_ = pp::FileIO(); +} + +void MyInstance::ReportResponse(const std::string& data) { + PostMessage(pp::Var(data)); +} + +// This object is the global object representing this plugin library as long +// as it is loaded. +class MyModule : public pp::Module { + public: + MyModule() : pp::Module() {} + virtual ~MyModule() {} + + // Override CreateInstance to create your customized Instance object. + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/examples/url_loader/streaming.cc b/ppapi/examples/url_loader/streaming.cc index 18efe68..762a00b 100644 --- a/ppapi/examples/url_loader/streaming.cc +++ b/ppapi/examples/url_loader/streaming.cc @@ -7,9 +7,7 @@ // the plugin and the url_loader.html page in this directory to start the load // and to communicate the result. // -// The other mode is to stream to a file instead. For that mode, call -// URLLoader.FinishSthreamingToFile once the "Open" callback is complete, and -// then call URLResponseInfo.GetBodyAsFileRef once the file stream is complete. +// The other mode is to stream to a file instead. See stream_to_file.cc #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" |