Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: ppapi/examples/url_loader/stream_to_file.cc

Issue 10993031: Refactor the URLResponseInfo to use new design (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/cpp/file_io.h ('k') | ppapi/examples/url_loader/streaming.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This example shows how to use the URLLoader in streaming mode (reading to 5 // This example shows how to use the URLLoader in "stream to file" mode where
6 // memory as data comes over the network). This example uses PostMessage between 6 // the browser writes incoming data to a file, which you can read out via the
7 // the plugin and the url_loader.html page in this directory to start the load 7 // file I/O APIs.
8 // and to communicate the result.
9 // 8 //
10 // The other mode is to stream to a file instead. For that mode, call 9 // This example uses PostMessage between the plugin and the url_loader.html
11 // URLLoader.FinishSthreamingToFile once the "Open" callback is complete, and 10 // page in this directory to start the load and to communicate the result.
12 // then call URLResponseInfo.GetBodyAsFileRef once the file stream is complete.
13 11
12 #include "ppapi/c/ppb_file_io.h"
13 #include "ppapi/cpp/file_io.h"
14 #include "ppapi/cpp/file_ref.h"
14 #include "ppapi/cpp/instance.h" 15 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/module.h" 16 #include "ppapi/cpp/module.h"
16 #include "ppapi/cpp/url_loader.h" 17 #include "ppapi/cpp/url_loader.h"
17 #include "ppapi/cpp/url_request_info.h" 18 #include "ppapi/cpp/url_request_info.h"
18 #include "ppapi/cpp/url_response_info.h" 19 #include "ppapi/cpp/url_response_info.h"
19 #include "ppapi/utility/completion_callback_factory.h" 20 #include "ppapi/utility/completion_callback_factory.h"
20 21
21 // When compiling natively on Windows, PostMessage can be #define-d to 22 // When compiling natively on Windows, PostMessage can be #define-d to
22 // something else. 23 // something else.
23 #ifdef PostMessage 24 #ifdef PostMessage
(...skipping 20 matching lines...) Expand all
44 // Handler for the page sending us messages. 45 // Handler for the page sending us messages.
45 virtual void HandleMessage(const pp::Var& message_data); 46 virtual void HandleMessage(const pp::Var& message_data);
46 47
47 private: 48 private:
48 // Called to initiate the request. 49 // Called to initiate the request.
49 void StartRequest(const std::string& url); 50 void StartRequest(const std::string& url);
50 51
51 // Callback for the URLLoader to tell us it finished opening the connection. 52 // Callback for the URLLoader to tell us it finished opening the connection.
52 void OnOpenComplete(int32_t result); 53 void OnOpenComplete(int32_t result);
53 54
54 // Starts streaming data. 55 // Callback for when the file is completely filled with the download
55 void ReadMore(); 56 void OnStreamComplete(int32_t result);
56 57
57 // Callback for the URLLoader to tell us when it finished a read. 58 void OnOpenFileComplete(int32_t result);
58 void OnReadComplete(int32_t result); 59 void OnReadComplete(int32_t result);
59 60
60 // Forwards the given string to the page. 61 // Forwards the given string to the page.
61 void ReportResponse(const std::string& data); 62 void ReportResponse(const std::string& data);
62 63
63 // Generates completion callbacks scoped to this class. 64 // Generates completion callbacks scoped to this class.
64 pp::CompletionCallbackFactory<MyInstance> factory_; 65 pp::CompletionCallbackFactory<MyInstance> factory_;
65 66
66 pp::URLLoader loader_; 67 pp::URLLoader loader_;
67 pp::URLResponseInfo response_; 68 pp::URLResponseInfo response_;
69 pp::FileRef dest_file_;
70 pp::FileIO file_io_;
68 71
69 // The buffer used for the current read request. This is filled and then 72 // The buffer used for the current read request. This is filled and then
70 // copied into content_ to build up the entire document. 73 // copied into content_ to build up the entire document.
71 char buf_[kBufSize]; 74 char buf_[kBufSize];
72 75
73 // All the content loaded so far. 76 // All the content loaded so far.
74 std::string content_; 77 std::string content_;
75 }; 78 };
76 79
77 void MyInstance::HandleMessage(const pp::Var& message_data) { 80 void MyInstance::HandleMessage(const pp::Var& message_data) {
78 if (message_data.is_string() && message_data.AsString() == "go") 81 if (message_data.is_string() && message_data.AsString() == "go")
79 StartRequest("./fetched_content.html"); 82 StartRequest("./fetched_content.html");
80 } 83 }
81 84
82 void MyInstance::StartRequest(const std::string& url) { 85 void MyInstance::StartRequest(const std::string& url) {
83 content_.clear(); 86 content_.clear();
84 87
85 pp::URLRequestInfo request(this); 88 pp::URLRequestInfo request(this);
86 request.SetURL(url); 89 request.SetURL(url);
87 request.SetMethod("GET"); 90 request.SetMethod("GET");
91 request.SetStreamToFile(true);
88 92
89 loader_ = pp::URLLoader(this); 93 loader_ = pp::URLLoader(this);
90 loader_.Open(request, 94 loader_.Open(request,
91 factory_.NewCallback(&MyInstance::OnOpenComplete)); 95 factory_.NewCallback(&MyInstance::OnOpenComplete));
92 } 96 }
93 97
94 void MyInstance::OnOpenComplete(int32_t result) { 98 void MyInstance::OnOpenComplete(int32_t result) {
95 if (result != PP_OK) { 99 if (result != PP_OK) {
96 ReportResponse("URL could not be requested"); 100 ReportResponse("URL could not be requested");
97 return; 101 return;
98 } 102 }
99 103
104 loader_.FinishStreamingToFile(
105 factory_.NewCallback(&MyInstance::OnStreamComplete));
100 response_ = loader_.GetResponseInfo(); 106 response_ = loader_.GetResponseInfo();
101 107 dest_file_ = response_.GetBodyAsFileRef();
102 // Here you would process the headers. A real program would want to at least
103 // check the HTTP code and potentially cancel the request.
104
105 // Start streaming.
106 ReadMore();
107 } 108 }
108 109
109 void MyInstance::ReadMore() { 110 void MyInstance::OnStreamComplete(int32_t result) {
110 // Note that you specifically want an "optional" callback here. This will 111 if (result == PP_OK) {
111 // allow Read() to return synchronously, ignoring your completion callback, 112 file_io_ = pp::FileIO(this);
112 // if data is available. For fast connections and large files, reading as 113 file_io_.Open(dest_file_, PP_FILEOPENFLAG_READ,
113 // fast as we can will make a large performance difference. However, in the 114 factory_.NewCallback(&MyInstance::OnOpenFileComplete));
114 // case of a synchronous return, we need to be sure to run the callback we 115 } else {
115 // created since the loader won't do anything with it. 116 ReportResponse("Could not stream to file");
116 pp::CompletionCallback cc = 117 }
117 factory_.NewOptionalCallback(&MyInstance::OnReadComplete); 118 }
118 int32_t result = PP_OK;
119 do {
120 result = loader_.ReadResponseBody(buf_, kBufSize, cc);
121 // Handle streaming data directly. Note that we *don't* want to call
122 // OnReadComplete here, since in the case of result > 0 it will schedule
123 // another call to this function. If the network is very fast, we could
124 // end up with a deeply recursive stack.
125 if (result > 0)
126 content_.append(buf_, result);
127 } while (result > 0);
128 119
129 if (result != PP_OK_COMPLETIONPENDING) { 120 void MyInstance::OnOpenFileComplete(int32_t result) {
130 // Either we reached the end of the stream (result == PP_OK) or there was 121 if (result == PP_OK) {
131 // an error. We want OnReadComplete to get called no matter what to handle 122 // Note we only read the first 1024 bytes from the file in this example
132 // that case, whether the error is synchronous or asynchronous. If the 123 // to keep things simple. Please see a file I/O example for more details
133 // result code *is* COMPLETIONPENDING, our callback will be called 124 // on reading files.
134 // asynchronously. 125 file_io_.Read(0, buf_, kBufSize,
135 cc.Run(result); 126 factory_.NewCallback(&MyInstance::OnReadComplete));
127 } else {
128 ReportResponse("Could not open file");
136 } 129 }
137 } 130 }
138 131
139 void MyInstance::OnReadComplete(int32_t result) { 132 void MyInstance::OnReadComplete(int32_t result) {
140 if (result == PP_OK) { 133 if (result >= 0) {
141 // Streaming the file is complete.
142 ReportResponse(content_);
143 } else if (result > 0) {
144 // The URLLoader just filled "result" number of bytes into our buffer.
145 // Save them and perform another read.
146 content_.append(buf_, result); 134 content_.append(buf_, result);
147 ReadMore(); 135 ReportResponse(buf_);
148 } else { 136 } else {
149 // A read error occurred. 137 ReportResponse("Could not read file");
150 ReportResponse("A read error occurred");
151 } 138 }
139
140 // Release everything.
141 loader_ = pp::URLLoader();
142 response_ = pp::URLResponseInfo();
143 dest_file_ = pp::FileRef();
144 file_io_ = pp::FileIO();
152 } 145 }
153 146
154 void MyInstance::ReportResponse(const std::string& data) { 147 void MyInstance::ReportResponse(const std::string& data) {
155 PostMessage(pp::Var(data)); 148 PostMessage(pp::Var(data));
156 } 149 }
157 150
158 // This object is the global object representing this plugin library as long 151 // This object is the global object representing this plugin library as long
159 // as it is loaded. 152 // as it is loaded.
160 class MyModule : public pp::Module { 153 class MyModule : public pp::Module {
161 public: 154 public:
162 MyModule() : pp::Module() {} 155 MyModule() : pp::Module() {}
163 virtual ~MyModule() {} 156 virtual ~MyModule() {}
164 157
165 // Override CreateInstance to create your customized Instance object. 158 // Override CreateInstance to create your customized Instance object.
166 virtual pp::Instance* CreateInstance(PP_Instance instance) { 159 virtual pp::Instance* CreateInstance(PP_Instance instance) {
167 return new MyInstance(instance); 160 return new MyInstance(instance);
168 } 161 }
169 }; 162 };
170 163
171 namespace pp { 164 namespace pp {
172 165
173 // Factory function for your specialization of the Module object. 166 // Factory function for your specialization of the Module object.
174 Module* CreateModule() { 167 Module* CreateModule() {
175 return new MyModule(); 168 return new MyModule();
176 } 169 }
177 170
178 } // namespace pp 171 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/cpp/file_io.h ('k') | ppapi/examples/url_loader/streaming.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698