This source file includes following definitions.
- Create
- cc_factory_
- Start
- OnOpen
- AppendDataBytes
- OnRead
- ReadBody
- ReportResultAndDie
- ReportResult
#include <stdio.h>
#include <stdlib.h>
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "url_loader_handler.h"
#ifdef WIN32
#undef min
#undef max
#undef PostMessage
#pragma warning(disable : 4355)
#endif
URLLoaderHandler* URLLoaderHandler::Create(pp::Instance* instance,
const std::string& url) {
return new URLLoaderHandler(instance, url);
}
URLLoaderHandler::URLLoaderHandler(pp::Instance* instance,
const std::string& url)
: instance_(instance),
url_(url),
url_request_(instance),
url_loader_(instance),
buffer_(new char[READ_BUFFER_SIZE]),
cc_factory_(this) {
url_request_.SetURL(url);
url_request_.SetMethod("GET");
url_request_.SetRecordDownloadProgress(true);
}
URLLoaderHandler::~URLLoaderHandler() {
delete[] buffer_;
buffer_ = NULL;
}
void URLLoaderHandler::Start() {
pp::CompletionCallback cc =
cc_factory_.NewCallback(&URLLoaderHandler::OnOpen);
url_loader_.Open(url_request_, cc);
}
void URLLoaderHandler::OnOpen(int32_t result) {
if (result != PP_OK) {
ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false);
return;
}
int64_t bytes_received = 0;
int64_t total_bytes_to_be_received = 0;
if (url_loader_.GetDownloadProgress(&bytes_received,
&total_bytes_to_be_received)) {
if (total_bytes_to_be_received > 0) {
url_response_body_.reserve(total_bytes_to_be_received);
}
}
url_request_.SetRecordDownloadProgress(false);
ReadBody();
}
void URLLoaderHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
if (num_bytes <= 0)
return;
num_bytes = std::min(READ_BUFFER_SIZE, num_bytes);
url_response_body_.insert(
url_response_body_.end(), buffer, buffer + num_bytes);
}
void URLLoaderHandler::OnRead(int32_t result) {
if (result == PP_OK) {
delete[] buffer_;
buffer_ = NULL;
ReportResultAndDie(url_, url_response_body_, true);
} else if (result > 0) {
AppendDataBytes(buffer_, result);
ReadBody();
} else {
ReportResultAndDie(
url_, "pp::URLLoader::ReadResponseBody() result<0", false);
}
}
void URLLoaderHandler::ReadBody() {
pp::CompletionCallback cc =
cc_factory_.NewOptionalCallback(&URLLoaderHandler::OnRead);
int32_t result = PP_OK;
do {
result = url_loader_.ReadResponseBody(buffer_, READ_BUFFER_SIZE, cc);
if (result > 0) {
AppendDataBytes(buffer_, result);
}
} while (result > 0);
if (result != PP_OK_COMPLETIONPENDING) {
cc.Run(result);
}
}
void URLLoaderHandler::ReportResultAndDie(const std::string& fname,
const std::string& text,
bool success) {
ReportResult(fname, text, success);
delete this;
}
void URLLoaderHandler::ReportResult(const std::string& fname,
const std::string& text,
bool success) {
if (success)
printf("URLLoaderHandler::ReportResult(Ok).\n");
else
printf("URLLoaderHandler::ReportResult(Err). %s\n", text.c_str());
fflush(stdout);
if (instance_) {
pp::Var var_result(fname + "\n" + text);
instance_->PostMessage(var_result);
}
}