| Index: ppapi/proxy/ppb_url_loader_proxy.cc
|
| diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc
|
| index 91c1bba3020bd3ebb0ed6d22f0db126c453f29d5..3421ef002d674b06e5059eede3ff04cbcce0d8ce 100644
|
| --- a/ppapi/proxy/ppb_url_loader_proxy.cc
|
| +++ b/ppapi/proxy/ppb_url_loader_proxy.cc
|
| @@ -23,6 +23,7 @@
|
| #include "ppapi/proxy/plugin_resource_tracker.h"
|
| #include "ppapi/proxy/ppapi_messages.h"
|
| #include "ppapi/proxy/ppb_file_ref_proxy.h"
|
| +#include "ppapi/shared_impl/array_writer.h"
|
| #include "ppapi/shared_impl/scoped_pp_resource.h"
|
| #include "ppapi/shared_impl/tracked_callback.h"
|
| #include "ppapi/thunk/enter.h"
|
| @@ -78,6 +79,12 @@ InterfaceProxy* CreateURLLoaderProxy(Dispatcher* dispatcher) {
|
| return new PPB_URLLoader_Proxy(dispatcher);
|
| }
|
|
|
| +// An adapter to let ReadResponseBody() share the same implementation with
|
| +// ReadResponseBodyToArray().
|
| +void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) {
|
| + return user_data;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // URLLoader -------------------------------------------------------------------
|
| @@ -108,6 +115,10 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
|
| void* buffer,
|
| int32_t bytes_to_read,
|
| scoped_refptr<TrackedCallback> callback) OVERRIDE;
|
| + virtual int32_t ReadResponseBodyToArray(
|
| + int32_t max_read_length,
|
| + PP_ArrayOutput* array_output,
|
| + scoped_refptr<TrackedCallback> callback) OVERRIDE;
|
| virtual int32_t FinishStreamingToFile(
|
| scoped_refptr<TrackedCallback> callback) OVERRIDE;
|
| virtual void Close() OVERRIDE;
|
| @@ -116,6 +127,10 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
|
| PP_URLLoaderTrusted_StatusCallback cb) OVERRIDE;
|
| virtual bool GetResponseInfoData(URLResponseInfoData* data) OVERRIDE;
|
|
|
| + int32_t ReadResponseBodyInternal(const PP_ArrayOutput& output,
|
| + int32_t max_read_length,
|
| + scoped_refptr<TrackedCallback> callback);
|
| +
|
| // Called when the browser has new up/download progress to report.
|
| void UpdateProgress(const PPBURLLoader_UpdateProgress_Params& params);
|
|
|
| @@ -130,7 +145,7 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
|
| // buffer, and removes the bytes from the buffer.
|
| //
|
| // The size must be not more than the current size of the buffer.
|
| - void PopBuffer(void* output_buffer, int32_t output_size);
|
| + void PopBuffer(const PP_ArrayOutput& output_buffer, int32_t output_size);
|
|
|
| PluginDispatcher* GetDispatcher() const {
|
| return PluginDispatcher::GetForResource(this);
|
| @@ -149,8 +164,8 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
|
|
|
| // When an asynchronous read is pending, this will contain the buffer to put
|
| // the data. The current_callback_ will identify the read callback.
|
| - void* current_read_buffer_;
|
| - int32_t current_read_buffer_size_;
|
| + PP_ArrayOutput current_array_output_;
|
| + int32_t current_max_read_length_;
|
|
|
| // A buffer of all the data that's been sent to us from the host that we
|
| // have yet to send out to the plugin.
|
| @@ -170,8 +185,7 @@ URLLoader::URLLoader(const HostResource& resource)
|
| total_bytes_to_be_sent_(-1),
|
| bytes_received_(-1),
|
| total_bytes_to_be_received_(-1),
|
| - current_read_buffer_(NULL),
|
| - current_read_buffer_size_(0),
|
| + current_max_read_length_(0),
|
| response_info_(0) {
|
| }
|
|
|
| @@ -278,27 +292,19 @@ PP_Resource URLLoader::GetResponseInfo() {
|
| int32_t URLLoader::ReadResponseBody(void* buffer,
|
| int32_t bytes_to_read,
|
| scoped_refptr<TrackedCallback> callback) {
|
| - if (!buffer || bytes_to_read <= 0)
|
| - return PP_ERROR_BADARGUMENT; // Must specify an output buffer.
|
| - if (TrackedCallback::IsPending(current_callback_))
|
| - return PP_ERROR_INPROGRESS; // Can only have one request pending.
|
| -
|
| - if (buffer_.size()) {
|
| - // Special case: we've already buffered some data that we can synchronously
|
| - // return to the caller. Do so without making IPCs.
|
| - int32_t bytes_to_return =
|
| - std::min(bytes_to_read, static_cast<int32_t>(buffer_.size()));
|
| - PopBuffer(buffer, bytes_to_return);
|
| - return bytes_to_return;
|
| - }
|
| -
|
| - current_callback_ = callback;
|
| - current_read_buffer_ = buffer;
|
| - current_read_buffer_size_ = bytes_to_read;
|
| + if (!buffer)
|
| + return PP_ERROR_BADARGUMENT;
|
| + PP_ArrayOutput output_adapter = { &DummyGetDataBuffer, buffer };
|
| + return ReadResponseBodyInternal(output_adapter, bytes_to_read, callback);
|
| +}
|
|
|
| - GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
|
| - API_ID_PPB_URL_LOADER, host_resource(), bytes_to_read));
|
| - return PP_OK_COMPLETIONPENDING;
|
| +int32_t URLLoader::ReadResponseBodyToArray(
|
| + int32_t max_read_length,
|
| + PP_ArrayOutput* array_output,
|
| + scoped_refptr<TrackedCallback> callback) {
|
| + if (!array_output)
|
| + return PP_ERROR_BADARGUMENT;
|
| + return ReadResponseBodyInternal(*array_output, max_read_length, callback);
|
| }
|
|
|
| int32_t URLLoader::FinishStreamingToFile(
|
| @@ -345,7 +351,7 @@ void URLLoader::UpdateProgress(
|
| }
|
|
|
| void URLLoader::ReadResponseBodyAck(int32 result, const char* data) {
|
| - if (!TrackedCallback::IsPending(current_callback_) || !current_read_buffer_) {
|
| + if (!TrackedCallback::IsPending(current_callback_)) {
|
| NOTREACHED();
|
| return;
|
| }
|
| @@ -353,10 +359,11 @@ void URLLoader::ReadResponseBodyAck(int32 result, const char* data) {
|
| if (result >= 0) {
|
| DCHECK_EQ(0U, buffer_.size());
|
|
|
| - int32_t bytes_to_return = std::min(current_read_buffer_size_, result);
|
| - std::copy(data,
|
| - data + bytes_to_return,
|
| - static_cast<char*>(current_read_buffer_));
|
| + int32_t bytes_to_return = std::min(current_max_read_length_, result);
|
| + ArrayWriter output;
|
| + output.set_pp_array_output(current_array_output_);
|
| + if (output.is_valid())
|
| + output.StoreArray(data, bytes_to_return);
|
|
|
| if (result > bytes_to_return) {
|
| // Save what remains to be copied when ReadResponseBody is called again.
|
| @@ -375,13 +382,16 @@ void URLLoader::CallbackComplete(int32_t result) {
|
| current_callback_->Run(result);
|
| }
|
|
|
| -void URLLoader::PopBuffer(void* output_buffer, int32_t output_size) {
|
| +void URLLoader::PopBuffer(const PP_ArrayOutput& output_buffer,
|
| + int32_t output_size) {
|
| CHECK(output_size <= static_cast<int32_t>(buffer_.size()));
|
| - std::copy(buffer_.begin(),
|
| - buffer_.begin() + output_size,
|
| - static_cast<char*>(output_buffer));
|
| - buffer_.erase(buffer_.begin(),
|
| - buffer_.begin() + output_size);
|
| +
|
| + ArrayWriter output;
|
| + output.set_pp_array_output(output_buffer);
|
| + if (output.is_valid() && !buffer_.empty()) {
|
| + output.StoreArray(&buffer_[0], output_size);
|
| + buffer_.erase(buffer_.begin(), buffer_.begin() + output_size);
|
| + }
|
| }
|
|
|
| // PPB_URLLoader_Proxy ---------------------------------------------------------
|
| @@ -645,5 +655,32 @@ void PPB_URLLoader_Proxy::OnCallback(int32_t result,
|
| }
|
| #endif // !defined(OS_NACL)
|
|
|
| +int32_t URLLoader::ReadResponseBodyInternal(
|
| + const PP_ArrayOutput& output,
|
| + int32_t max_read_length,
|
| + scoped_refptr<TrackedCallback> callback) {
|
| + if (max_read_length <= 0)
|
| + return PP_ERROR_BADARGUMENT; // Must specify an output buffer.
|
| + if (TrackedCallback::IsPending(current_callback_))
|
| + return PP_ERROR_INPROGRESS; // Can only have one request pending.
|
| +
|
| + if (buffer_.size()) {
|
| + // Special case: we've already buffered some data that we can synchronously
|
| + // return to the caller. Do so without making IPCs.
|
| + int32_t bytes_to_return =
|
| + std::min(max_read_length, static_cast<int32_t>(buffer_.size()));
|
| + PopBuffer(output, bytes_to_return);
|
| + return bytes_to_return;
|
| + }
|
| +
|
| + current_callback_ = callback;
|
| + current_array_output_ = output;
|
| + current_max_read_length_ = max_read_length;
|
| +
|
| + GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
|
| + API_ID_PPB_URL_LOADER, host_resource(), max_read_length));
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| } // namespace proxy
|
| } // namespace ppapi
|
|
|