#include <boost/format.hpp>
#include <string>
#include <vector>
+#include <boost/xpressive/xpressive.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace x = boost::xpressive;
extern void LogMsg (void* instance,const char* format,...);
std::string GetURLHandler::js_empty_;
GetURLHandler* GetURLHandler::Create(pp::Instance* instance,
- const std::string& url,std::vector<char>& result_data,const std::string& jsFuncName ) {
- return new GetURLHandler(instance, url,result_data,jsFuncName);
+ const std::string& url,std::vector<char>& result_data,const std::string& jsFuncName,complete_func_type func ) {
+ return new GetURLHandler(instance, url,result_data,jsFuncName,func);
}
GetURLHandler::GetURLHandler(pp::Instance* instance,
- const std::string& url,std::vector<char>& result_data,const std::string& jsFuncName)
+ const std::string& url,std::vector<char>& result_data,const std::string& jsFuncName,complete_func_type func)
: instance_(instance),
url_(url),
url_request_(instance),
url_loader_(instance),
url_response_body_(result_data),
- cc_factory_(this) {
+ cc_factory_(this),load_success_(false) ,received_bytes_(0),total_bytes_(0),func_(func),status_(init){
if(jsFuncName == "")
{
js_func_name_ = js_empty_;
}
bool GetURLHandler::Start() {
+ LogMsg(instance_,"GetURLHandler::Start () Enter" );
pp::CompletionCallback cc = cc_factory_.NewCallback(&GetURLHandler::OnOpen);
int32_t res = url_loader_.Open(url_request_, cc);
- pp::URLResponseInfo info(url_loader_.GetResponseInfo());
LogMsg(instance_,"GetURLHandler::Start::result = %d",res);
if ((PP_ERROR_WOULDBLOCK) != res )
cc.Run(res);
}
void GetURLHandler::OnOpen(int32_t result) {
- result_ = result;
+ LogMsg(instance_,"GetURLHandler::OnOpen::result = %d",result);
pp::URLResponseInfo info(url_loader_.GetResponseInfo());
LogMsg(instance_,"GetURLHandler::OnOpen::result = %d,Status Code = %d",result,info.GetStatusCode());
-
+ LogMsg(instance_,"Headers: %s",info.GetProperty(PP_URLRESPONSEPROPERTY_HEADERS).AsString().c_str());
if (result < 0 || info.GetStatusCode() >= 400){
std::string result_str((boost::format("pp::URLLoader::Open() failed: %d %s") % result % info.GetStatusLine().AsString()).str());
LogMsg(instance_, result_str.c_str());
+ func_(open,false,*this);
CallbackEventJS(open,false,result_str);
- delete this;
-// ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false);
+ status_ = end;
+ // ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false);
} else {
+ x::sregex reg = "Content-Length: " >> ( x::s1 = +x::_d ) ;
+ //x::sregex reg = x::sregex::compile("Content\\-Length\\:\\s([0-9]+)\\s");
+ x::smatch m;
+ if(x::regex_search(info.GetProperty(PP_URLRESPONSEPROPERTY_HEADERS).AsString(),m,reg))
+ {
+ LogMsg(instance_, "regex:match() success");
+ total_bytes_ = boost::lexical_cast<int32_t>(m[1].str());
+ };
LogMsg(instance_, "pp::URLLoader::Open() Success.");
- CallbackEventJS(open,true);
+ CallbackEventJS(open,true,pp::Var((int32_t)total_bytes_));
+ status_ = open;
+ func_(open,true,*this);
ReadBody();
}
}
void GetURLHandler::OnRead(int32_t result) {
result_ = result;
- if (result < 0) {
- std::string result_str((boost::format("pp::URLLoader::OnRead() file: %s result: %d") % url_.c_str() % result).str());
- LogMsg(instance_, result_str.c_str());
- CallbackEventJS(loading,false,result_str);
- delete this;
- } else if (result != 0) {
+ pp::URLResponseInfo info(url_loader_.GetResponseInfo());
+
+ if (result < 0 && info.GetStatusCode() >= 400) {
+ // \83G\83\89\81[\8f\88\97\9d
+ result_string_ = (boost::format("pp::URLLoader::OnRead() file: %s result: %d status code:%d") % url_.c_str() % result % info.GetStatusCode()).str();
+ LogMsg(instance_, result_string_.c_str());
+ load_success_ = false;
+ CallbackEventJS(loading,load_success_,result_string_);
+ func_(loading,load_success_,*this);
+ status_ = end;
+ } else if (result != 0 ) {
/*\83X\83e\81[\83^\83X\83R\81[\83h\83`\83F\83b\83N*/
- pp::URLResponseInfo info(url_loader_.GetResponseInfo());
- int32_t num_bytes = result < kBufferSize ? result : sizeof(buffer_);
- url_response_body_.reserve(url_response_body_.size() + num_bytes);
- url_response_body_.insert(url_response_body_.end(),
+
+ int32_t num_bytes = result < kBufferSize ? result : sizeof(buffer_);
+ url_response_body_.reserve(url_response_body_.size() + num_bytes);
+ url_response_body_.insert(url_response_body_.end(),
buffer_,
buffer_ + num_bytes);
+
+ //pp::FileRef_Dev d(info.
+ //url_loader_.GetDownloadProgress(&received_bytes_,&total_bytes_);
+ received_bytes_ += num_bytes;
LogMsg(instance_,"pp::URLLoader::OnRead() File: %s Success: %d bytes Status: %d" ,url_.c_str(),num_bytes,info.GetStatusCode());
ReadBody();
} else { // result == 0, end of stream
- isLoadSuccess = true;
+ load_success_ = true;
LogMsg(instance_,"Load Success. File Size is %d bytes.\n",url_response_body_.size());
- CallbackEventJS(complete,true,(int32_t)(url_response_body_.size()));
- delete this;
+ CallbackEventJS(complete,load_success_,(int32_t)(url_response_body_.size()));
+ func_(complete,load_success_,*this);
+ status_ = end;
}
}
/* TODO: \90i\92»\8fó\91Ô\82Ì\93Ç\82Ý\8eæ\82è\82ð\8dì\82é */
#include <ppapi/cpp/url_loader.h>
#include <ppapi/cpp/url_request_info.h>
#include <ppapi/cpp/instance.h>
+#include <boost/function.hpp>
// GetURLHandler is used to download data from |url|. When download is
// finished or when an error occurs, it calls JavaScript function
//
class GetURLHandler {
public:
- enum event_id {
+
+ enum status_id {
open,
loading,
- complete
+ complete,
+ end,
+ init
};
+
+ typedef boost::function<void (status_id,bool,GetURLHandler&) > complete_func_type;
+ static void null_func(status_id,bool,GetURLHandler&) { } ;
+
// Creates instance of GetURLHandler on the heap.
// GetURLHandler objects shall be created only on the heap (they
// self-destroy when all data is in).
static GetURLHandler* Create(pp::Instance* instance_,
- const std::string& url,std::vector<char>& result,const std::string& jsFuncName = js_empty_);
+ const std::string& url,std::vector<char>& result,const std::string& jsFuncName = js_empty_,complete_func_type func = complete_func_type(&null_func));
// Initiates page (URL) download.
// Returns false in case of internal error, and self-destroys.
bool Start();
- private:
- static const int kBufferSize = 4096;
+ int32_t GetReceivedBytes() const
+ {
+ return (int32_t)received_bytes_;
+ }
+
+ int32_t GetTotalBytes() const
+ {
+ return (int32_t)total_bytes_;
+ }
- GetURLHandler(pp::Instance* instance_, const std::string& url,std::vector<char>& result,const std::string& jsFuncName = js_empty_);
~GetURLHandler();
+ status_id GetStatus() const { return status_;};
+private:
+ static const int kBufferSize = 4096;
+
+ GetURLHandler(pp::Instance* instance_, const std::string& url,std::vector<char>& result,const std::string& jsFuncName = js_empty_,complete_func_type func = complete_func_type(&null_func));
// Callback fo the pp::URLLoader::Open().
// Called by pp::URLLoader when response headers are received or when an
// OnRead() will be called when bytes are received or when an error occurs.
void ReadBody();
- void CallbackEventJS(event_id id,bool status,const pp::Var& reason = std::string(""))
+ void CallbackEventJS(status_id id,bool status,const pp::Var& reason = std::string(""))
{
if(!js_func_name_.empty())
{
// const std::string& text,
// bool success);
- pp::Instance* instance_;
+ pp::Instance* instance_;
std::string url_; // URL to be downloaded.
pp::URLRequestInfo url_request_;
pp::URLLoader url_loader_; // URLLoader provides an API to download URLs.
pp::CompletionCallbackFactory<GetURLHandler> cc_factory_;
std::string js_func_name_;
uint32_t result_;
- bool isLoadSuccess;
+ std::string result_string_;
+ bool load_success_;
GetURLHandler(const GetURLHandler&);
void operator=(const GetURLHandler&);
static std::string js_empty_;
+ int64_t received_bytes_,total_bytes_;
+ complete_func_type func_;
+ status_id status_;
};
#endif // EXAMPLES_GETURL_GETURL_HANDLER_H_
const char* const kStopSoundId = "stopSound";
// メインスレッド以外のログを取得する
const char* const kGetLogId = "getLog";
- //
+ //
const char* const kCheckLogId = "checkLog";
+ const char * const kRecievedBytesId = "receivedBytes";
+ const char * const kTotalBytesId = "totalBytes";
+
// システムにリクエストするサンプルカウント数
const uint32_t kSampleFrameCount = 4096u;
// 現在サポートしているのはステレオオーディオのみである。
: pp::Instance(instance), scriptable_object_(NULL),
sample_frame_count_(kSampleFrameCount) , mod_( MOD__Create(this))
{
- pthread_mutex_init(&mutex_, NULL);
+ pthread_mutexattr_init(&mutex_attr_);
+ pthread_mutexattr_settype(&mutex_attr_,PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mutex_, NULL );
}
virtual ~XmPlayerInstance()
{
+ pthread_mutex_destroy(&mutex_);
+ pthread_mutexattr_destroy(&mutex_attr_);
MOD__Destruct(mod_);
}
}
std::string ret(log_.front());
{
- ScopedMutexLock lock(&mutex_);
+ ScopedMutexLock lock(&mutex_);
log_.pop_front();
}
return ret;
pp::Var exception;
window.Call("reportLog",log, &exception);
}
+
+ bool LoadXmFile(const std::string& url,const std::string& jsFuncName)
+ {
+ SendLog("XmPlayerInstance::LoadXmFile()::CreateGetURLHandler");
+ //MODファイルのロード
+ { //GetURLHandler *handler_ = 0;
+ if(!handler_ || handler_->GetStatus() == GetURLHandler::end){
+ handler_.reset(GetURLHandler::Create(this,url,GetLoadData(),jsFuncName));
+ // handler_= GetURLHandler::Create(this,url,GetLoadData(),jsFuncName);
+ if(!handler_)
+ {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ SendLog("XmPlayerInstance::LoadXmFile()::handler_->Start()");
+ if(!handler_->Start()){
+ return false;
+ };
+ SendLog("XmPlayerInstance::LoadXmFile() Exit");
+ return true;
+ }
+ }
+
+ int32_t GetReceivedBytes()
+ {
+ if(!handler_) return 0;
+ return handler_->GetReceivedBytes();
+ }
+
+ int32_t GetTotalBytes()
+ {
+ if(!handler_) return 0;
+ return handler_->GetTotalBytes();
+ }
+
private:
static void XmPlayerCallback(void* samples, size_t buffer_size, void* data) {
XmPlayerInstance* xm_player_instance =
std::vector<char> load_data_;
std::list<std::string> log_;
pthread_mutex_t mutex_;
+ pthread_mutexattr_t mutex_attr_;
+ boost::shared_ptr<GetURLHandler> handler_;
};
// The Module class. The browser calls the CreateInstance() method to create
bool XmPlayerScriptableObject::HasProperty(const pp::Var& property,
pp::Var* exception) {
- return false;
- // if (!property.is_string()) {
- // return false;
- //}
- //const std::string property_name = property.AsString();
- //const bool has_property = (property_name == kFrequencyId);
- //return has_property;
+ if (!property.is_string()) {
+ return false;
+ }
+ const std::string property_name = property.AsString();
+ const bool has_property = (property_name == kRecievedBytesId) || (property_name == kTotalBytesId);
+ return has_property;
}
void XmPlayerScriptableObject::SetProperty(const pp::Var& property,
return pp::Var();
}
std::string property_name = property.AsString();
- //if (property_name == kFrequencyId) {
- // return pp::Var(frequency());
- //}
+ if (property_name == kRecievedBytesId) {
+ return pp::Var(player_.GetReceivedBytes());
+ } else if(property_name == kTotalBytesId)
+ {
+ return pp::Var(player_.GetTotalBytes());
+ }
*exception = std::string("No property named ") + property_name;
return pp::Var();
}
bool XmPlayerScriptableObject::LoadXmFile(const std::string& url,const std::string& jsFuncName)
{
- //MODファイルのロード
- GetURLHandler* handler_(GetURLHandler::Create(&player_,url,player_.GetLoadData(),jsFuncName));
- if(handler_)
- {
- if(!handler_->Start()){
- return false;
- };
- } else {
- return false;
+ return player_.LoadXmFile(url,jsFuncName);
}
- return true;
- }
} // namespace xm_player
void LogMsg (void* instance,const char* format,...)
va_end(ap);
//pp::Instance * inst = pp::Module::Get()->InstanceForPPInstance(instance);
- xm_player::XmPlayerInstance * inst = reinterpret_cast<xm_player::XmPlayerInstance*>(instance);
+ xm_player::XmPlayerInstance * inst = static_cast<xm_player::XmPlayerInstance*>(instance);
+ //inst->SendLog(buf);
inst->WriteLog(buf);
// pp::Var window(inst->GetWindowObject());
//window.is_int();
<script type="text/javascript" src="http://nacl-gallery.appspot.com/check_browser.js"></script>
<!-- <script type="text/javascript" src="jquery-1.5.1.min.js"></script> -->
<script type="text/javascript">
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-15457703-9']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
- <script type="text/javascript">
+// var _gaq = _gaq || [];
+// _gaq.push(['_setAccount', 'UA-15457703-9']);
+// _gaq.push(['_trackPageview']);
+
+// (function() {
+// var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+// ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+// var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+// })();
+
var xmPlayer = null; // Global application object.
var timerId = null;
+ var progress_id = null;
var reportResult;
var status_open = 0;
var status_loading = 1;
var status_complete = 2;
+ var total_bytes = 0;
function reportLog(log) {
// $("#GeneralOutput").append(log + "<br/>");
var logElt = document.getElementById('GeneralOutput');
function moduleLoad() {
xmPlayer = document.getElementById("xmPlayer");
+ timerId = setInterval(function () {
+ if (xmPlayer.checkLog()) {
+ var c = $("#GeneralOutput");
+ while (xmPlayer.checkLog()) {
+ c.append(xmPlayer.getLog() + "<br/>");
+ }
+ }
+ }, 300);
+
$("#load-file").attr("disabled", "").click(
function () {
try {
+ var logElt = document.getElementById('GeneralOutput');
+
reportResult = function (status, success, result) {
var logElt = document.getElementById('GeneralOutput');
logElt.innerHTML += 'File URL:' + $("#xmfile-url").val() + '<br/>';
logElt.innerHTML += 'RESULT:\n' + result + '<br/>';
+
+ // ファイルオープンが成功したら
+ if (status == status_open && success) {
+ // トータルバイト数を取得する
+ total_bytes = parseInt(result);
+ logElt.innerHTML += "TotalBytes:" + total_bytes + '<br/>';
+ $("#status-dialog")
+ .html("<p>ファイルを読み込んでいます。</p><div id='progress'></div>")
+ .attr("title", "ファイルロード")
+ .dialog();
+
+ $("#progress").progressbar({ value: 0 });
+ // 100ms 毎に進捗を表示
+ progress_id = setInterval(function () {
+ $("GeneralOutput").append(xmPlayer.receivedBytes + "<br/>");
+ $("#progress").progressbar("value", parseInt(xmPlayer.receivedBytes * 100 / total_bytes));
+ }, 100);
+ }
+
if (status == status_complete && success) {
+ if (progress_id != null)
+ clearInterval(progress_id);
$("#Play").click(function () {
xmPlayer.playSound();
}).attr("disabled", "");
$("#Stop").click(function () {
xmPlayer.stopSound();
}).attr("disabled", "");
- $("#status-dialog").html("ファイルの読み込みが完了しました。")
- .attr("title", "ファイルロード")
+
+ $("#status-dialog")
+ .html("ファイルの読み込みが完了しました。")
.dialog({ buttons: [
{
- text: "Ok",
- click: function () { $(this).dialog("close"); }
- }
- ]
+ text: "Ok", click: function () { $(this).dialog("close"); }
+ }]
});
} else if (!success) {
+ if (progress_id != null)
+ clearInterval(progress_id);
logElt.innerHTML += "Load Failure:" + result + "<br/>";
$("#status-dialog").html("ファイルの読み込みが失敗しました。" + result)
.attr("title", "ファイルロード")
- .dialog({ buttons: [
+ .dialog("options", "buttons", [
{
- text: "Ok",
- click: function () { $(this).dialog("close"); }
- }
- ]
- });
+ text: "Ok", click: function () { $(this).dialog("close"); }
+ }]
+ );
}
};
}
);
- timerId = setInterval(function () {
- if (xmPlayer.checkLog()) {
- var c = $("#GeneralOutput");
- while (xmPlayer.checkLog()) {
- c.append(xmPlayer.getLog() + "<br/>");
- }
- }
- }, 300);
+
}
</script>
<option value="SHADOW.XM">SHADOW.XM</option>
<option value="DEADLOCK.XM">DEADLOCK.XM</option>
<option value="sweetdre.xm">sweetdre.xm</option>
+ <option value="aws_aq16.xm">aws_aq16.xm</option>
</select></div>
<!-- <input id="xmfile-url" type="text" maxlength="2048" /></div> -->
<div>
type="application/x-nacl"
onload="moduleLoad();"
/>
- <div id="status-dialog" title=""></div>
+ <div id="status-dialog" title=""><p>これはこれは</p></div>
</body>
</html>