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

Side by Side Diff: native_client_sdk/src/examples/geturl/geturl_handler.cc

Issue 8922018: Merged in NaCl SDK r1388 from old repo (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years 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 | « native_client_sdk/src/examples/geturl/geturl_handler.h ('k') | no next file » | 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) 2011 The Native Client Authors. All rights reserved. 1 // Copyright (c) 2011 The Native Client 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 #include "examples/geturl/geturl_handler.h" 5 #include "examples/geturl/geturl_handler.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include "ppapi/c/pp_errors.h" 9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/ppb_instance.h" 10 #include "ppapi/c/ppb_instance.h"
(...skipping 10 matching lines...) Expand all
21 const std::string& url) { 21 const std::string& url) {
22 return new GetURLHandler(instance, url); 22 return new GetURLHandler(instance, url);
23 } 23 }
24 24
25 GetURLHandler::GetURLHandler(pp::Instance* instance, 25 GetURLHandler::GetURLHandler(pp::Instance* instance,
26 const std::string& url) 26 const std::string& url)
27 : instance_(instance), 27 : instance_(instance),
28 url_(url), 28 url_(url),
29 url_request_(instance), 29 url_request_(instance),
30 url_loader_(instance), 30 url_loader_(instance),
31 buffer_(new char[READ_BUFFER_SIZE]),
31 cc_factory_(this) { 32 cc_factory_(this) {
32 url_request_.SetURL(url); 33 url_request_.SetURL(url);
33 url_request_.SetMethod("GET"); 34 url_request_.SetMethod("GET");
35 url_request_.SetRecordDownloadProgress(true);
34 } 36 }
35 37
36 GetURLHandler::~GetURLHandler() { 38 GetURLHandler::~GetURLHandler() {
39 delete [] buffer_;
40 buffer_ = NULL;
37 } 41 }
38 42
39 void GetURLHandler::Start() { 43 void GetURLHandler::Start() {
40 pp::CompletionCallback cc = 44 pp::CompletionCallback cc =
41 cc_factory_.NewRequiredCallback(&GetURLHandler::OnOpen); 45 cc_factory_.NewRequiredCallback(&GetURLHandler::OnOpen);
42 url_loader_.Open(url_request_, cc); 46 url_loader_.Open(url_request_, cc);
43 } 47 }
44 48
45 void GetURLHandler::OnOpen(int32_t result) { 49 void GetURLHandler::OnOpen(int32_t result) {
46 if (result != PP_OK) { 50 if (result != PP_OK) {
47 ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false); 51 ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false);
48 return; 52 return;
49 } 53 }
50 // Here you would process the headers. A real program would want to at least 54 // Here you would process the headers. A real program would want to at least
51 // check the HTTP code and potentially cancel the request. 55 // check the HTTP code and potentially cancel the request.
52 // pp::URLResponseInfo response = loader_.GetResponseInfo(); 56 // pp::URLResponseInfo response = loader_.GetResponseInfo();
53 57
58 // Try to figure out how many bytes of data are going to be downloaded in
59 // order to allocate memory for the response body in advance (this will
60 // reduce heap traffic and also the amount of memory allocated).
61 // It is not a problem if this fails, it just means that the
62 // url_response_body_.insert() call in GetURLHandler::AppendDataBytes()
63 // will allocate the memory later on.
64 int64_t bytes_received = 0;
65 int64_t total_bytes_to_be_received = 0;
66 if (url_loader_.GetDownloadProgress(&bytes_received,
67 &total_bytes_to_be_received)) {
68 if (total_bytes_to_be_received > 0) {
69 url_response_body_.reserve(total_bytes_to_be_received);
70 }
71 }
72 // We will not use the download progress anymore, so just disable it.
73 url_request_.SetRecordDownloadProgress(false);
74
54 // Start streaming. 75 // Start streaming.
55 ReadBody(); 76 ReadBody();
56 } 77 }
57 78
58 void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) { 79 void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
59 if (num_bytes <= 0) 80 if (num_bytes <= 0)
60 return; 81 return;
61 // Make sure we don't get a buffer overrun. 82 // Make sure we don't get a buffer overrun.
62 num_bytes = std::min(READ_BUFFER_SIZE, num_bytes); 83 num_bytes = std::min(READ_BUFFER_SIZE, num_bytes);
63 url_response_body_.reserve(url_response_body_.size() + num_bytes); 84 // Note that we do *not* try to minimally increase the amount of allocated
85 // memory here by calling url_response_body_.reserve(). Doing so causes a
86 // lot of string reallocations that kills performance for large files.
64 url_response_body_.insert(url_response_body_.end(), 87 url_response_body_.insert(url_response_body_.end(),
65 buffer, 88 buffer,
66 buffer + num_bytes); 89 buffer + num_bytes);
67 } 90 }
68 91
69 void GetURLHandler::OnRead(int32_t result) { 92 void GetURLHandler::OnRead(int32_t result) {
70 if (result == PP_OK) { 93 if (result == PP_OK) {
71 // Streaming the file is complete. 94 // Streaming the file is complete, delete the read buffer since it is
95 // no longer needed.
96 delete [] buffer_;
97 buffer_ = NULL;
72 ReportResultAndDie(url_, url_response_body_, true); 98 ReportResultAndDie(url_, url_response_body_, true);
73 } else if (result > 0) { 99 } else if (result > 0) {
74 // The URLLoader just filled "result" number of bytes into our buffer. 100 // The URLLoader just filled "result" number of bytes into our buffer.
75 // Save them and perform another read. 101 // Save them and perform another read.
76 AppendDataBytes(buffer_, result); 102 AppendDataBytes(buffer_, result);
77 ReadBody(); 103 ReadBody();
78 } else { 104 } else {
79 // A read error occurred. 105 // A read error occurred.
80 ReportResultAndDie(url_, 106 ReportResultAndDie(url_,
81 "pp::URLLoader::ReadResponseBody() result<0", 107 "pp::URLLoader::ReadResponseBody() result<0",
82 false); 108 false);
83 } 109 }
84 } 110 }
85 111
86 void GetURLHandler::ReadBody() { 112 void GetURLHandler::ReadBody() {
87 // Note that you specifically want an "optional" callback here. This will 113 // Note that you specifically want an "optional" callback here. This will
88 // allow ReadBody() to return synchronously, ignoring your completion 114 // allow ReadBody() to return synchronously, ignoring your completion
89 // callback, if data is available. For fast connections and large files, 115 // callback, if data is available. For fast connections and large files,
90 // reading as fast as we can will make a large performance difference 116 // reading as fast as we can will make a large performance difference
91 // However, in the case of a synchronous return, we need to be sure to run 117 // However, in the case of a synchronous return, we need to be sure to run
92 // the callback we created since the loader won't do anything with it. 118 // the callback we created since the loader won't do anything with it.
93 pp::CompletionCallback cc = 119 pp::CompletionCallback cc =
94 cc_factory_.NewOptionalCallback(&GetURLHandler::OnRead); 120 cc_factory_.NewOptionalCallback(&GetURLHandler::OnRead);
95 int32_t result = PP_OK; 121 int32_t result = PP_OK;
96 do { 122 do {
97 result = url_loader_.ReadResponseBody(buffer_, sizeof(buffer_), cc); 123 result = url_loader_.ReadResponseBody(buffer_, READ_BUFFER_SIZE, cc);
98 // Handle streaming data directly. Note that we *don't* want to call 124 // Handle streaming data directly. Note that we *don't* want to call
99 // OnRead here, since in the case of result > 0 it will schedule 125 // OnRead here, since in the case of result > 0 it will schedule
100 // another call to this function. If the network is very fast, we could 126 // another call to this function. If the network is very fast, we could
101 // end up with a deeply recursive stack. 127 // end up with a deeply recursive stack.
102 if (result > 0) { 128 if (result > 0) {
103 AppendDataBytes(buffer_, result); 129 AppendDataBytes(buffer_, result);
104 } 130 }
105 } while (result > 0); 131 } while (result > 0);
106 132
107 if (result != PP_OK_COMPLETIONPENDING) { 133 if (result != PP_OK_COMPLETIONPENDING) {
(...skipping 20 matching lines...) Expand all
128 printf("GetURLHandler::ReportResult(Ok).\n"); 154 printf("GetURLHandler::ReportResult(Ok).\n");
129 else 155 else
130 printf("GetURLHandler::ReportResult(Err). %s\n", text.c_str()); 156 printf("GetURLHandler::ReportResult(Err). %s\n", text.c_str());
131 fflush(stdout); 157 fflush(stdout);
132 if (instance_) { 158 if (instance_) {
133 pp::Var var_result(fname + "\n" + text); 159 pp::Var var_result(fname + "\n" + text);
134 instance_->PostMessage(var_result); 160 instance_->PostMessage(var_result);
135 } 161 }
136 } 162 }
137 163
OLDNEW
« no previous file with comments | « native_client_sdk/src/examples/geturl/geturl_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698