OSDN Git Service

jQueryのアップデートに伴う変更。
[nacltest/xmplayer.git] / geturl_handler.cc
1 // Copyright 2010 The Native Client SDK Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can
3 // be found in the LICENSE file.
4
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <ppapi/c/pp_errors.h>
9 #include <ppapi/c/ppb_instance.h>
10 #include <ppapi/cpp/module.h>
11 #include <ppapi/cpp/var.h>
12 #include <ppapi/cpp/url_response_info.h>
13 #include <boost/format.hpp>
14 #include <string>
15 #include <vector>
16 #include <boost/xpressive/xpressive.hpp>
17 #include <boost/lexical_cast.hpp>
18 #include <boost/format.hpp>
19
20 #include "geturl_handler.h"
21
22 namespace  x = boost::xpressive;
23
24 extern void LogMsg (void* instance,const char* format,...);
25
26 namespace {
27 bool IsError(int32_t result) {
28   return ((PP_OK != result) && (PP_OK_COMPLETIONPENDING  != result));
29 }
30 }  // namespace
31
32 std::string GetURLHandler::js_empty_;
33
34 GetURLHandler* GetURLHandler::Create(pp::Instance* instance,
35                                      const std::string& url,std::vector<char>& result_data,complete_func_type func ) {
36   return new GetURLHandler(instance, url,result_data,func);
37 }
38
39 GetURLHandler::GetURLHandler(pp::Instance* instance,
40                              const std::string& url,std::vector<char>& result_data,complete_func_type func)
41     : instance_(instance),
42       url_(url),
43       url_request_(instance),
44       url_loader_(instance),
45       url_response_body_(result_data),
46       cc_factory_(this),load_success_(false) ,received_bytes_(0),total_bytes_(0),func_(func),status_(init){
47     url_response_body_.clear();
48     url_request_.SetURL(url);
49     url_request_.SetMethod("GET");
50   // 
51 }
52
53 GetURLHandler::~GetURLHandler() {
54 }
55
56 bool GetURLHandler::Start() {
57   LogMsg(instance_,"GetURLHandler::Start () Enter" );
58   pp::CompletionCallback cc = cc_factory_.NewCallback(&GetURLHandler::OnOpen);
59   int32_t res = url_loader_.Open(url_request_, cc);
60   LogMsg(instance_,"GetURLHandler::Start::result = %d",res);
61   if ((PP_OK_COMPLETIONPENDING) != res )
62     cc.Run(res);
63   
64   return !IsError(res);
65 }
66
67 void GetURLHandler::OnOpen(int32_t result) {
68   LogMsg(instance_,"GetURLHandler::OnOpen::result = %d",result);
69   pp::URLResponseInfo info(url_loader_.GetResponseInfo());
70   LogMsg(instance_,"GetURLHandler::OnOpen::result = %d,Status Code = %d",result,info.GetStatusCode());
71   LogMsg(instance_,"Headers: %s",info.GetProperty(PP_URLRESPONSEPROPERTY_HEADERS).AsString().c_str());
72   if (result < 0 || info.GetStatusCode() >= 400){
73     std::string result_str((boost::format("pp::URLLoader::Open() failed: %d %s") % result % info.GetStatusLine().AsString()).str());
74     LogMsg(instance_, result_str.c_str());
75     func_(open,false,*this);
76     CallbackEventJS(open,false,result_str);
77     status_ = end;
78     //    ReportResultAndDie(url_, "pp::URLLoader::Open() failed", false);
79   } else {
80     x::sregex  reg =  "Content-Length: "  >> ( x::s1 = +x::_d ) ;
81     //x::sregex reg = x::sregex::compile("Content\\-Length\\:\\s([0-9]+)\\s");
82     x::smatch m;
83     if(x::regex_search(info.GetProperty(PP_URLRESPONSEPROPERTY_HEADERS).AsString(),m,reg))
84     {
85       total_bytes_ = boost::lexical_cast<int32_t>(m[1].str());
86       LogMsg(instance_, "regex:match() success");
87     };
88     LogMsg(instance_, "pp::URLLoader::Open() Success.");
89     CallbackEventJS(open,true,pp::Var((int32_t)total_bytes_));
90     status_ = open;
91     func_(open,true,*this);
92     ReadBody();
93   }
94 }
95
96   void GetURLHandler::CallbackEventJS(status_id id,bool status,const pp::Var& reason)
97   {
98     LogMsg(instance_, "CallbackEventJS");
99     if(reason.is_string()){
100       instance_->PostMessage(pp::Var((boost::format("GetURLHandler:%d:%d:%s") % id % status % reason.AsString()).str()));
101     } else {
102       instance_->PostMessage(pp::Var((boost::format("GetURLHandler:%d:%d:%d") % id % status % reason.AsInt()).str()));
103     }
104   }
105
106
107 void GetURLHandler::OnRead(int32_t result) {
108   result_ = result;
109   static int count = 0;
110   pp::URLResponseInfo info(url_loader_.GetResponseInfo());
111
112   if (result < 0 && info.GetStatusCode() >= 400) {
113     // \83G\83\89\81[\8f\88\97\9d
114     result_string_ =  (boost::format("pp::URLLoader::OnRead() file: %s result: %d status code:%d") % url_.c_str() % result %  info.GetStatusCode()).str();
115     LogMsg(instance_, result_string_.c_str());
116     load_success_ = false;
117     CallbackEventJS(loading,load_success_,result_string_);
118     func_(loading,load_success_,*this);
119     status_ = end;
120   } else if (result != 0 ) {
121     /*\83X\83e\81[\83^\83X\83R\81[\83h\83`\83F\83b\83N*/
122       
123     int32_t num_bytes = result < kBufferSize ? result : sizeof(buffer_);
124     url_response_body_.reserve(url_response_body_.size() + num_bytes);
125     url_response_body_.insert(url_response_body_.end(),
126                                 buffer_,
127                                 buffer_ + num_bytes);
128
129     //pp::FileRef_Dev d(info.
130       //url_loader_.GetDownloadProgress(&received_bytes_,&total_bytes_);
131       received_bytes_ += num_bytes;
132       count = (++count) & 0x3;
133       if(count == 0){
134         CallbackEventJS(loading,true,(int32_t)(received_bytes_));
135         LogMsg(instance_,"pp::URLLoader::OnRead() File: %s Success: %d bytes Status: %d" ,url_.c_str(),num_bytes,info.GetStatusCode());
136       }
137
138       ReadBody();
139   } else {  // result == 0, end of stream
140     load_success_ = true;
141     LogMsg(instance_,"Load Success. File Size is %d bytes.\n",url_response_body_.size());
142     CallbackEventJS(complete,load_success_,(int32_t)(url_response_body_.size()));
143     func_(complete,load_success_,*this);
144     status_ = end;
145   }
146 }
147 /* TODO: \90i\92»\8fó\91Ô\82Ì\93Ç\82Ý\8eæ\82è\82ð\8dì\82é */
148
149 void GetURLHandler::ReadBody() {
150   // Reads the response body (asynchronous) into this->buffer_.
151   // OnRead() will be called when bytes are received or when an error occurs.
152   // Look at <ppapi/c/dev/ppb_url_loader> for more details.
153   pp::CompletionCallback cc = cc_factory_.NewCallback(&GetURLHandler::OnRead);
154   int32_t res = url_loader_.ReadResponseBody(buffer_,
155                                              sizeof(buffer_),
156                                              cc);
157   if (PP_OK_COMPLETIONPENDING  != res)
158     cc.Run(res);
159 }
160 //
161 //void GetURLHandler::ReportResultAndDie(const std::string& fname,
162 //                                       const std::string& text,
163 //                                       bool success) {
164 //  ReportResult(fname, text, success);
165 //  delete this;
166 //}
167 //
168 //void GetURLHandler::ReportResult(const std::string& fname,
169 //                                 const std::string& text,
170 //                                 bool success) {
171 //  if (success)
172 //    printf("GetURLHandler::ReportResult(Ok).\n");
173 //  else
174 //    printf("GetURLHandler::ReportResult(Err). %s\n", text.c_str());
175 //  fflush(stdout);
176 //  pp::Module* module = pp::Module::Get();
177 //  if (NULL == module)
178 //    return;
179 //
180 //  pp::Instance* instance = module->InstanceForPPInstance(instance_id_);
181 //  if (NULL == instance)
182 //    return;
183 //
184 //  pp::Var window = instance->GetWindowObject();
185 //  // calls JavaScript function reportResult(url, result, success)
186 //  // defined in geturl.html.
187 //  pp::Var exception;
188 //  window.Call("reportResult", fname, text, success, &exception);
189 //}
190