hostile-takeover/game/iphone/iphonehttprequest.mm

153 lines
4.6 KiB
Plaintext

#include "game/iphone/iphonehttprequest.h"
#include "game/iphone/input.h"
#include "game/iphone/iphone.h"
#include "base/thread.h"
// Requests come in from the game thread; NS* api calls occur on main
// thread.
// C++ implementation of HttpRequest interface for iPhone
namespace wi {
IPhoneHttpRequest::IPhoneHttpRequest(HttpResponseHandler *handler) : handler_(handler) {
}
IPhoneHttpRequest::~IPhoneHttpRequest() {
}
void IPhoneHttpRequest::Dispose() {
// Called on game thread
thread_.Clear(this);
MessageHandler::Dispose();
}
NSURLRequest *IPhoneHttpRequest::CreateNSURLRequest() {
// Called on main thread
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
// Set the url
NSString *s = [NSString stringWithCString:url_.c_str()
encoding:[NSString defaultCStringEncoding]];
[req setURL:[NSURL URLWithString:s]];
// Set the method
s = [NSString stringWithCString:method_.c_str()
encoding:[NSString defaultCStringEncoding]];
[req setHTTPMethod:s];
// Set the body
if (pbb_ != NULL) {
int cb;
void *pv = pbb_->Strip(&cb);
NSData *data = [NSData dataWithBytesNoCopy:(void *)pv length:cb];
[req setHTTPBody:data];
}
// Set timeout
[req setTimeoutInterval:timeout_];
// Set cache policy
[req setCachePolicy:NSURLRequestReloadIgnoringCacheData];
// Set headers
Enum enm;
char szKey[128];
while (headers_.EnumKeys(&enm, szKey, sizeof(szKey))) {
char szValue[256];
if (headers_.GetValue(szKey, szValue, sizeof(szValue))) {
NSString *key = [NSString stringWithCString:szKey
encoding:[NSString defaultCStringEncoding]];
NSString *value = [NSString stringWithCString:szValue
encoding:[NSString defaultCStringEncoding]];
[req setValue:value forHTTPHeaderField:key];
}
}
// Done
[pool release];
return req;
}
void IPhoneHttpRequest::OnMessage(base::Message *pmsg) {
switch (pmsg->id) {
case kidmReceivedResponse:
{
ReceivedResponseParams *pparams =
(ReceivedResponseParams *)pmsg->data;
handler_->OnReceivedResponse(this, pparams->code,
&pparams->headers);
delete pparams;
}
break;
case kidmReceivedData:
{
ReceivedDataParams *pparams =
(ReceivedDataParams *)pmsg->data;
handler_->OnReceivedData(this, &pparams->bb);
delete pparams;
}
break;
case kidmFinishedLoading:
handler_->OnFinishedLoading(this);
break;
case kidmError:
{
ErrorParams *pparams = (ErrorParams *)pmsg->data;
handler_->OnError(this, pparams->szError);
delete pparams;
}
break;
}
}
void IPhoneHttpRequest::OnReceivedResponse(NSHTTPURLResponse *resp) {
// Called on main thread. Populate ReceivedResponseParams
ReceivedResponseParams *pparams = new ReceivedResponseParams;
NSDictionary *dict = [resp allHeaderFields];
for (NSString *k in dict) {
NSString *v = [dict objectForKey:k];
pparams->headers.SetValue(
[k cStringUsingEncoding:[NSString defaultCStringEncoding]],
[v cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
pparams->code = (int)[resp statusCode];
// Post this to the game thread
thread_.Post(kidmReceivedResponse, this, pparams);
}
void IPhoneHttpRequest::OnReceivedData(NSData *data) {
// Called on main thread. Populate ReceivedDataParams
ReceivedDataParams *pparams = new ReceivedDataParams;
pparams->bb.WriteBytes((const byte *)[data bytes], (int)[data length]);
// Post this to the game thread
thread_.Post(kidmReceivedData, this, pparams);
}
void IPhoneHttpRequest::OnFinishedLoading() {
// Called on main thread. Post this to game thread.
thread_.Post(kidmFinishedLoading, this);
}
void IPhoneHttpRequest::OnError(NSError *error) {
// Called on main thread. Populate ErrorParams. Use
// localizedDescription. Note there is also localizedFailureReason;
// not sure which is better at the moment
const char *psz = [[error localizedDescription] cStringUsingEncoding:
[NSString defaultCStringEncoding]];
ErrorParams *pparams = new ErrorParams;
strncpyz(pparams->szError, psz, sizeof(pparams->szError));
// Called on main thread. Post this to game thread.
thread_.Post(kidmError, this, pparams);
}
} // namespace wi