From d7689073e0c91c342ed551614ddef050cf537d7c Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 24 Oct 2013 11:12:21 +0800 Subject: [PATCH 1/8] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- .../lua/bindings/lua_xml_http_request.cpp | 922 ++++++++++++++++++ .../lua/bindings/lua_xml_http_request.h | 94 ++ 3 files changed, 1017 insertions(+), 1 deletion(-) create mode 100644 cocos/scripting/lua/bindings/lua_xml_http_request.cpp create mode 100644 cocos/scripting/lua/bindings/lua_xml_http_request.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 18265b616b..b62768a5e8 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -1c487d29bdc2d80516e86e2ee93b1664e9f7df2f \ No newline at end of file +fcdf6af61b7c3ac52b92590b16090335bd26b169 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp new file mode 100644 index 0000000000..eaf2202ba0 --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -0,0 +1,922 @@ + +#include "lua_xml_http_request.h" + +extern "C" +{ +#include "tolua_fix.h" +} + +#include + +using namespace std; + +LuaMinXmlHttpRequest::LuaMinXmlHttpRequest():_isNetwork(true) +{ + _httpHeader.clear(); + _requestHeader.clear(); + _withCredentialsValue = true; + _httpRequest = new network::HttpRequest(); +} + +LuaMinXmlHttpRequest::~LuaMinXmlHttpRequest() +{ + _httpHeader.clear(); + _requestHeader.clear(); +} + +/** + * @brief Implementation for header retrieving. + * @param header + */ +void LuaMinXmlHttpRequest::_gotHeader(string header) +{ + // Get Header and Set StatusText + // Split String into Tokens + char * cstr = new char [header.length()+1]; + + // check for colon. + unsigned found_header_field = header.find_first_of(":"); + + if (found_header_field != std::string::npos) + { + // Found a header field. + string http_field; + string http_value; + + http_field = header.substr(0,found_header_field); + http_value = header.substr(found_header_field+1, header.length()); + + // Get rid of all \n + if (!http_value.empty() && http_value[http_value.size() - 1] == '\n') { + http_value.erase(http_value.size() - 1); + } + + _httpHeader[http_field] = http_value; + + } + else + { + // Seems like we have the response Code! Parse it and check for it. + char * pch; + strcpy(cstr, header.c_str()); + + pch = strtok(cstr," "); + while (pch != NULL) + { + + stringstream ss; + string val; + + ss << pch; + val = ss.str(); + unsigned found_http = val.find("HTTP"); + + // Check for HTTP Header to set statusText + if (found_http != std::string::npos) { + + stringstream mystream; + + // Get Response Status + pch = strtok (NULL, " "); + mystream << pch; + + pch = strtok (NULL, " "); + mystream << " " << pch; + + _statusText = mystream.str(); + + } + + pch = strtok (NULL, " "); + } + } + + CC_SAFE_DELETE_ARRAY(cstr); +} + +/** + * @brief Set Request header for next call. + * @param field Name of the Header to be set. + * @param value Value of the Headerfield + */ +void LuaMinXmlHttpRequest::setRequestHeader(const char* field, const char* value) +{ + stringstream header_s; + stringstream value_s; + string header; + + map::iterator iter = _requestHeader.find(field); + + // Concatenate values when header exists. + if (iter != _requestHeader.end()) + { + value_s << iter->second << "," << value; + } + else + { + value_s << value; + } + + _requestHeader[field] = value_s.str(); +} + +/** + * @brief If headers has been set, pass them to curl. + * + */ +void LuaMinXmlHttpRequest::_setHttpRequestHeader() +{ + std::vector header; + + for (auto it = _requestHeader.begin(); it != _requestHeader.end(); ++it) + { + const char* first = it->first.c_str(); + const char* second = it->second.c_str(); + size_t len = sizeof(char) * (strlen(first) + 3 + strlen(second)); + char* test = (char*) malloc(len); + memset(test, 0,len); + + strcpy(test, first); + strcpy(test + strlen(first) , ": "); + strcpy(test + strlen(first) + 2, second); + + header.push_back(test); + + free(test); + + } + + if (!header.empty()) + { + _httpRequest->setHeaders(header); + } + +} + +/** + * @brief Send out request and fire callback when done. + */ +void LuaMinXmlHttpRequest::_sendRequest() +{ + _httpRequest->setResponseCallback(this, httpresponse_selector(LuaMinXmlHttpRequest::handle_requestResponse)); + network::HttpClient::getInstance()->send(_httpRequest); + _httpRequest->release(); +} + + +/** + * @brief Callback for HTTPRequest. Handles the response and invokes Callback. + * @param sender Object which initialized callback + * @param respone Response object + * @js NA + */ +void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, network::HttpResponse *response) +{ + if (0 != strlen(response->getHttpRequest()->getTag())) + { + CCLOG("%s completed", response->getHttpRequest()->getTag()); + } + + int statusCode = response->getResponseCode(); + char statusString[64] = {}; + sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag()); + + if (!response->isSucceed()) + { + CCLOG("response failed"); + CCLOG("error buffer: %s", response->getErrorBuffer()); + return; + } + + // set header + std::vector *headers = response->getResponseHeader(); + + char* concatHeader = (char*) malloc(headers->size() + 1); + std::string header(headers->begin(), headers->end()); + strcpy(concatHeader, header.c_str()); + + std::istringstream stream(concatHeader); + std::string line; + while(std::getline(stream, line)) { + _gotHeader(line); + } + + /** get the response data **/ + std::vector *buffer = response->getResponseData(); + char* concatenated = (char*) malloc(buffer->size() + 1); + std::string s2(buffer->begin(), buffer->end()); + + strcpy(concatenated, s2.c_str()); + + if (statusCode == 200) + { + //Succeeded + _status = 200; + _readyState = DONE; + _data << concatenated; + _dataSize = buffer->size(); + } + else + { + _status = 0; + } + // Free Memory. + free((void*) concatHeader); + free((void*) concatenated); + + // call back lua function --TODO + int handler = 0; +} + +/* function to regType */ +static void lua_reg_xml_http_request(lua_State* L) +{ + tolua_usertype(L, "XMLHttpRequest"); +} + +static int lua_collect_xml_http_request (lua_State* L) +{ + LuaMinXmlHttpRequest* self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); + Mtolua_delete(self); + return 0; +} + +static int lua_cocos2dx_XMLHttpRequest_constructor(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + argc = lua_gettop(L)-1; + if (argc == 0) + { + self = new LuaMinXmlHttpRequest(); + self->autorelease(); + int ID = self? (int)self->_ID : -1; + int* luaID = self? &self->_luaID : NULL; + toluafix_pushusertype_ccobject(L, ID, luaID, (void*)self, "XMLHttpRequest"); + } + + CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "XMLHttpRequest",argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_constructor'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_responseType(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_responseType'\n", nullptr); + return 0; + } +#endif + + tolua_pushnumber(L, (lua_Number)self->getResponseType()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_responseType'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_responseType(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_responseType'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + int responseType = (int)tolua_tonumber(L,2,0); + + self->setResponseType((LuaMinXmlHttpRequest::ResponseType)responseType); + + return 0; + } + + CCLOG("'setResponseType' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_responseType'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_withCredentials(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_withCredentials'\n", nullptr); + return 0; + } +#endif + + tolua_pushboolean(L, self->getWithCredentialsValue()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_withCredentials'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_withCredentials(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_withCredentials'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + self->setWithCredentialsValue((bool)tolua_toboolean(L, 2, 0)); + return 0; + } + + CCLOG("'setWithCredentials' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_withCredentials'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_timeout(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_timeout'\n", nullptr); + return 0; + } +#endif + + tolua_pushnumber(L, (lua_Number)self->getTimeout()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_timeout'.",&tolua_err); + return 0; +#endif +} + +static int lua_set_XMLHttpRequest_timeout(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_set_XMLHttpRequest_timeout'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isnumber(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + self->setTimeout((unsigned)tolua_tonumber(L, 2, 0)); + return 0; + } + + CCLOG("'setTimeout' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_set_XMLHttpRequest_timeout'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_readyState(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_readyState'\n", nullptr); + return 0; + } +#endif + + lua_pushinteger(L, (lua_Integer)self->getReadyState()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_readyState'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_status(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_status'\n", nullptr); + return 0; + } +#endif + + lua_pushinteger(L, (lua_Integer)self->getStatus()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_status'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_statusText(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_statusText'\n", nullptr); + return 0; + } +#endif + + lua_pushstring(L, self->getStatusText().c_str()); + + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_statusText'.",&tolua_err); + return 0; +#endif +} + +static int lua_get_XMLHttpRequest_response(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_response'\n", nullptr); + return 0; + } +#endif + + if (self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::JSON) + { + //TODO + return 0; + } + else if(self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::ARRAY_BUFFER) + { + //TODO + return 0; + } + else + { + lua_pushstring(L, self->getStatusText().c_str()); + return 1; + } + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_response'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_open(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_open'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( argc >= 2) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) || + !tolua_isstring(L, 3, 0, &tolua_err)) + goto tolua_lerror; +#endif + + std::string method = tolua_tostring(L, 2, ""); + std::string url = tolua_tostring(L, 3, ""); + bool async = true; + if (argc > 2) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isboolean(L, 4, 0, &tolua_err) ) + goto tolua_lerror; +#endif + async = tolua_toboolean(L, 4, 0); + } + + self->setUrl(url); + self->setMethod(method); + self->setReadyState(1); + self->setAsync(async); + + if (url.length() > 5 && url.compare(url.length() - 5, 5, ".json") == 0 ) + { + self->setResponseType(LuaMinXmlHttpRequest::ResponseType::JSON); + } + + if (nullptr != self->getHttpRequest()) + { + if (method.compare("post") == 0 || method.compare("POST") == 0) + { + self->getHttpRequest()->setRequestType(network::HttpRequest::Type::POST); + } + else + { + self->getHttpRequest()->setRequestType(network::HttpRequest::Type::GET); + } + + self->getHttpRequest()->setUrl(url.c_str()); + + } + + self->setIsNetWork(true); + self->setReadyState(LuaMinXmlHttpRequest::OPENED); + + return 0; + } + + CCLOG("'open' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_open'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + std::string data = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_send'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 1 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err)) + goto tolua_lerror; +#endif + data = tolua_tostring(L, 2, ""); + } + + if (data.length() > 0 && + (self->getMethod().compare("post") == 0 || self->getMethod().compare("POST") == 0) && + nullptr != self->getHttpRequest()) + { + self->getHttpRequest()->setRequestData(data.c_str(), data.length()); + } + + self->_setHttpRequestHeader(); + self->_sendRequest(); + return 0; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_send'.",&tolua_err); + return 0; +#endif +} + +/** + * @brief abort function Placeholder! + */ +static int lua_cocos2dx_XMLHttpRequest_abort(lua_State* L) +{ + return 0; +} + +static int lua_cocos2dx_XMLHttpRequest_setRequestHeader(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + const char* field = ""; + const char* value = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_setRequestHeader'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 2 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) || + !tolua_isstring(L, 3, 0, &tolua_err) ) + goto tolua_lerror; +#endif + + field = tolua_tostring(L, 2, ""); + value = tolua_tostring(L, 3, ""); + self->setRequestHeader(field, value); + return 0; + } + + CCLOG("'setRequestHeader' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 2); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_setRequestHeader'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + stringstream responseheaders; + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 0 == argc ) + { + map httpHeader = self->getHttpHeader(); + + for (auto it = httpHeader.begin(); it != httpHeader.end(); ++it) + { + responseheaders << it->first << ": "<< it->second << "\n"; + } + + responseheader = responseheaders.str(); + tolua_pushstring(L, responseheader.c_str()); + return 1; + } + + CCLOG("'getAllResponseHeaders' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_getResponseHeader(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if ( 1 == argc ) + { +#if COCOS2D_DEBUG >= 1 + if (!tolua_isstring(L, 2, 0, &tolua_err) ) + goto tolua_lerror; +#endif + responseheader = tolua_tostring(L, 2, ""); + + stringstream streamData; + streamData << responseheader; + + string value = streamData.str(); + + + auto iter = self->getHttpHeader().find(value); + if (iter != self->getHttpHeader().end()) + { + tolua_pushstring(L, (iter->second).c_str()); + return 1; + } + } + + CCLOG("'getResponseHeader' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders'.",&tolua_err); + return 0; +#endif +} + +TOLUA_API int lua_xml_http_request_open(lua_State* L) +{ + tolua_open(L); + lua_reg_xml_http_request(L); + tolua_module(L,NULL,0); + tolua_beginmodule(L,NULL); + tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","",lua_collect_xml_http_request); + tolua_beginmodule(L,"XMLHttpRequest"); + tolua_variable(L, "responseType", lua_get_XMLHttpRequest_responseType, lua_set_XMLHttpRequest_responseType); + tolua_variable(L, "withCredentials", lua_get_XMLHttpRequest_withCredentials, lua_set_XMLHttpRequest_withCredentials); + tolua_variable(L, "timeout", lua_get_XMLHttpRequest_timeout, lua_set_XMLHttpRequest_timeout); + tolua_variable(L, "readyState", lua_get_XMLHttpRequest_readyState, nullptr); + tolua_variable(L, "status",lua_get_XMLHttpRequest_status,nullptr); + tolua_variable(L, "statusText", lua_get_XMLHttpRequest_statusText, nullptr); + tolua_variable(L, "response", lua_get_XMLHttpRequest_response, nullptr); + tolua_function(L, "new", lua_cocos2dx_XMLHttpRequest_constructor); + tolua_function(L, "open", lua_cocos2dx_XMLHttpRequest_open); + tolua_function(L, "send", lua_cocos2dx_XMLHttpRequest_send); + tolua_function(L, "abort", lua_cocos2dx_XMLHttpRequest_abort); + tolua_function(L, "setRequestHeader", lua_cocos2dx_XMLHttpRequest_setRequestHeader); + tolua_function(L, "getAllResponseHeaders", lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders); + tolua_function(L, "getResponseHeader", lua_cocos2dx_XMLHttpRequest_getResponseHeader); + tolua_endmodule(L); + tolua_endmodule(L); + return 1; +} diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.h b/cocos/scripting/lua/bindings/lua_xml_http_request.h new file mode 100644 index 0000000000..2b5a3a2f17 --- /dev/null +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.h @@ -0,0 +1,94 @@ +#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ +#define __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "tolua++.h" +#ifdef __cplusplus +} +#endif + + +#include "network/HttpClient.h" + +class LuaMinXmlHttpRequest : public cocos2d::Object +{ +public: + enum class ResponseType + { + STRING, + ARRAY_BUFFER, + BLOB, + DOCUMENT, + JSON + }; + + // Ready States (http://www.w3.org/TR/XMLHttpRequest/#interface-xmlhttprequest) + static const unsigned short UNSENT = 0; + static const unsigned short OPENED = 1; + static const unsigned short HEADERS_RECEIVED = 2; + static const unsigned short LOADING = 3; + static const unsigned short DONE = 4; + + LuaMinXmlHttpRequest(); + ~LuaMinXmlHttpRequest(); + + void handle_requestResponse(network::HttpClient *sender, network::HttpResponse *response); + + inline void setResponseType(ResponseType type) { _responseType = type; } + inline ResponseType getResponseType() {return _responseType; } + + inline void setWithCredentialsValue(bool value) { _withCredentialsValue = value; } + inline bool getWithCredentialsValue() {return _withCredentialsValue; } + + inline void setTimeout(unsigned timeOut) {_timeout = timeOut; } + inline unsigned getTimeout() { return _timeout;} + + inline void setReadyState(int readyState) { _readyState = readyState; } + inline int getReadyState() { return _readyState ;} + + inline network::HttpRequest* getHttpRequest() { return _httpRequest; } + inline int getStatus() { return _status; } + inline std::string getStatusText() { return _statusText ;} + + inline std::string getUrl(){return _url;} + inline void setUrl(std::string url) { _url = url ;} + + inline std::string getMethod(){return _meth;} + inline void setMethod(std::string meth) { _meth = meth ; } + + inline void setAsync(bool isAsync){ _isAsync = isAsync; } + inline void setIsNetWork(bool isNetWork) {_isNetwork = isNetWork; } + + void _setHttpRequestHeader(); + void _sendRequest(); + void setRequestHeader(const char* field, const char* value); + + std::map getHttpHeader() { return _httpHeader ;} +private: + void _gotHeader(std::string header); + + + + std::string _url; + std::string _meth; + std::string _type; + std::stringstream _data; + size_t _dataSize; + int _readyState; + int _status; + std::string _statusText; + ResponseType _responseType; + unsigned _timeout; + bool _isAsync; + network::HttpRequest* _httpRequest; + bool _isNetwork; + bool _withCredentialsValue; + std::map _httpHeader; + std::map _requestHeader; +}; + +TOLUA_API int lua_xml_http_request_open(lua_State* L); + +#endif //#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ From a4d028e905c31a8884bed780b158683370e4b500 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 11:40:41 +0800 Subject: [PATCH 2/8] issue #3409:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/scripting/lua/bindings/CCLuaStack.cpp | 4 + .../lua/bindings/LuaScriptHandlerMgr.h | 2 + .../lua/bindings/lua_xml_http_request.cpp | 195 ++++++++- .../lua/bindings/lua_xml_http_request.h | 10 +- cocos/scripting/lua/script/json.lua | 376 ++++++++++++++++++ .../XMLHttpRequestTest/XMLHttpRequestTest.lua | 147 +++++++ .../TestLua/Resources/luaScript/mainMenu.lua | 4 +- 8 files changed, 723 insertions(+), 17 deletions(-) create mode 100755 cocos/scripting/lua/script/json.lua create mode 100644 samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 70bb169acc..a937cb6412 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -83265c81797ca614f19372a96adf326aeb21b396 \ No newline at end of file +8a22c92b099f198f28124f0d7c6dd031b07d0154 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/CCLuaStack.cpp b/cocos/scripting/lua/bindings/CCLuaStack.cpp index be2aa86dd9..bad774b677 100644 --- a/cocos/scripting/lua/bindings/CCLuaStack.cpp +++ b/cocos/scripting/lua/bindings/CCLuaStack.cpp @@ -53,6 +53,7 @@ extern "C" { #include "LuaBasicConversions.h" #include "lua_cocos2dx_extension_manual.h" #include "lua_cocos2dx_deprecated.h" +#include "lua_xml_http_request.h" namespace { int lua_print(lua_State * luastate) @@ -148,6 +149,9 @@ bool LuaStack::init(void) #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) tolua_web_socket_open(_state); #endif + + register_xml_http_request(_state); + tolua_script_handler_mgr_open(_state); // add cocos2dx loader diff --git a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h index 44ea6fa103..82bcfee944 100644 --- a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h +++ b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h @@ -95,6 +95,8 @@ public: TABLECELL_SIZE_FOR_INDEX, TABLECELL_AT_INDEX, TABLEVIEW_NUMS_OF_CELLS, + + XMLHTTPREQUEST_READY_STATE_CHANGE, }; typedef int Handler; diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp index eaf2202ba0..f63e55c0b1 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -7,7 +7,13 @@ extern "C" } #include +#include "CCLuaStack.h" +#include "CCLuaValue.h" +#include "CCLuaEngine.h" +#include "LuaScriptHandlerMgr.h" + +using namespace cocos2d; using namespace std; LuaMinXmlHttpRequest::LuaMinXmlHttpRequest():_isNetwork(true) @@ -203,9 +209,12 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n /** get the response data **/ std::vector *buffer = response->getResponseData(); +// for (unsigned int i = 0; i < buffer->size(); i++) +// { +// printf("%c", (*buffer)[i]); +// } char* concatenated = (char*) malloc(buffer->size() + 1); std::string s2(buffer->begin(), buffer->end()); - strcpy(concatenated, s2.c_str()); if (statusCode == 200) @@ -225,7 +234,19 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n free((void*) concatenated); // call back lua function --TODO - int handler = 0; + int handler = cocos2d::ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE ); + + if (0 != handler) + { + cocos2d::CommonScriptData data(handler,""); + cocos2d::ScriptEvent event(cocos2d::ScriptEventType::kCommonEvent,(void*)&data); + cocos2d::ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event); + } +} + +void LuaMinXmlHttpRequest::getByteData(unsigned char* byteData) +{ + _data.read((char*)byteData, _dataSize); } /* function to regType */ @@ -258,6 +279,7 @@ static int lua_cocos2dx_XMLHttpRequest_constructor(lua_State* L) int ID = self? (int)self->_ID : -1; int* luaID = self? &self->_luaID : NULL; toluafix_pushusertype_ccobject(L, ID, luaID, (void*)self, "XMLHttpRequest"); + return 1; } CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "XMLHttpRequest",argc, 0); @@ -567,6 +589,33 @@ tolua_lerror: #endif } +static int lua_get_XMLHttpRequest_responseText(lua_State* L) +{ + LuaMinXmlHttpRequest* self = nullptr; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_get_XMLHttpRequest_responseText'\n", nullptr); + return 0; + } +#endif + lua_pushstring(L, self->getDataStr().c_str()); + return 1; + +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_get_XMLHttpRequest_responseText'.",&tolua_err); + return 0; +#endif +} + static int lua_get_XMLHttpRequest_response(lua_State* L) { LuaMinXmlHttpRequest* self = nullptr; @@ -587,17 +636,46 @@ static int lua_get_XMLHttpRequest_response(lua_State* L) if (self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::JSON) { - //TODO - return 0; + lua_pushstring(L, self->getDataStr().c_str()); + return 1; } else if(self->getResponseType() == LuaMinXmlHttpRequest::ResponseType::ARRAY_BUFFER) { - //TODO - return 0; + LuaStack *pStack = LuaEngine::getInstance()->getLuaStack(); + if (NULL == pStack) { + return 0; + } + + lua_State *tolua_s = pStack->getLuaState(); + if (NULL == tolua_s) { + return 0; + } + + int nRet = 0; + LuaValueArray array; + + uint8_t* tmpData = new uint8_t[self->getDataSize()]; + if (nullptr == tmpData) + { + return 0; + } + + self->getByteData(tmpData); + + for (int i = 0 ; i < self->getDataSize(); i++) + { + LuaValue value = LuaValue::intValue(tmpData[i]); + array.push_back(value); + } + + pStack->pushLuaValueArray(array); + + CC_SAFE_DELETE_ARRAY(tmpData); + return 1; } else { - lua_pushstring(L, self->getStatusText().c_str()); + lua_pushstring(L, self->getDataStr().c_str()); return 1; } @@ -694,7 +772,9 @@ static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) { int argc = 0; LuaMinXmlHttpRequest* self = nullptr; - std::string data = ""; + //std::string data = ""; + const char* data = NULL; + size_t size = 0; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; @@ -718,14 +798,15 @@ static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L) if (!tolua_isstring(L, 2, 0, &tolua_err)) goto tolua_lerror; #endif - data = tolua_tostring(L, 2, ""); + //data = tolua_tostring(L, 2, ""); + data = (const char*) lua_tolstring(L, 2, &size); } - if (data.length() > 0 && + if (size > 0 && (self->getMethod().compare("post") == 0 || self->getMethod().compare("POST") == 0) && nullptr != self->getHttpRequest()) { - self->getHttpRequest()->setRequestData(data.c_str(), data.length()); + self->getHttpRequest()->setRequestData(data,size); } self->_setHttpRequestHeader(); @@ -894,13 +975,98 @@ tolua_lerror: #endif } -TOLUA_API int lua_xml_http_request_open(lua_State* L) +static int lua_cocos2dx_XMLHttpRequest_registerScriptHandler(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_registerScriptHandler'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (1 == argc) + { +#if COCOS2D_DEBUG >= 1 + if (!toluafix_isfunction(L,2,"LUA_FUNCTION",0,&tolua_err)) + goto tolua_lerror; +#endif + + int handler = ( toluafix_ref_function(L,2,0)); + cocos2d::ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE); + return 0; + } + + CCLOG("'registerScriptHandler' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 1); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_registerScriptHandler'.",&tolua_err); + return 0; +#endif +} + +static int lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler(lua_State* L) +{ + int argc = 0; + LuaMinXmlHttpRequest* self = nullptr; + + string responseheader = ""; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; + if (!tolua_isusertype(L,1,"XMLHttpRequest",0,&tolua_err)) goto tolua_lerror; +#endif + + self = (LuaMinXmlHttpRequest*) tolua_tousertype(L,1,0); +#if COCOS2D_DEBUG >= 1 + if (nullptr == self) + { + tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler'\n", nullptr); + return 0; + } +#endif + + argc = lua_gettop(L) - 1; + + if (0 == argc) + { + cocos2d::ScriptHandlerMgr::getInstance()->removeObjectHandler((void*)self, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE); + + return 0; + } + + CCLOG("'unregisterScriptHandler' function of XMLHttpRequest wrong number of arguments: %d, was expecting %d\n", argc, 0); + return 0; +#if COCOS2D_DEBUG >= 1 +tolua_lerror: + tolua_error(L,"#ferror in function 'lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler'.",&tolua_err); + return 0; +#endif + +} + + +TOLUA_API int register_xml_http_request(lua_State* L) { tolua_open(L); lua_reg_xml_http_request(L); tolua_module(L,NULL,0); tolua_beginmodule(L,NULL); - tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","",lua_collect_xml_http_request); + tolua_cclass(L,"XMLHttpRequest","XMLHttpRequest","Object",lua_collect_xml_http_request); tolua_beginmodule(L,"XMLHttpRequest"); tolua_variable(L, "responseType", lua_get_XMLHttpRequest_responseType, lua_set_XMLHttpRequest_responseType); tolua_variable(L, "withCredentials", lua_get_XMLHttpRequest_withCredentials, lua_set_XMLHttpRequest_withCredentials); @@ -908,6 +1074,7 @@ TOLUA_API int lua_xml_http_request_open(lua_State* L) tolua_variable(L, "readyState", lua_get_XMLHttpRequest_readyState, nullptr); tolua_variable(L, "status",lua_get_XMLHttpRequest_status,nullptr); tolua_variable(L, "statusText", lua_get_XMLHttpRequest_statusText, nullptr); + tolua_variable(L, "responseText", lua_get_XMLHttpRequest_responseText, nullptr); tolua_variable(L, "response", lua_get_XMLHttpRequest_response, nullptr); tolua_function(L, "new", lua_cocos2dx_XMLHttpRequest_constructor); tolua_function(L, "open", lua_cocos2dx_XMLHttpRequest_open); @@ -916,6 +1083,8 @@ TOLUA_API int lua_xml_http_request_open(lua_State* L) tolua_function(L, "setRequestHeader", lua_cocos2dx_XMLHttpRequest_setRequestHeader); tolua_function(L, "getAllResponseHeaders", lua_cocos2dx_XMLHttpRequest_getAllResponseHeaders); tolua_function(L, "getResponseHeader", lua_cocos2dx_XMLHttpRequest_getResponseHeader); + tolua_function(L, "registerScriptHandler", lua_cocos2dx_XMLHttpRequest_registerScriptHandler); + tolua_function(L, "unregisterScriptHandler", lua_cocos2dx_XMLHttpRequest_unregisterScriptHandler); tolua_endmodule(L); tolua_endmodule(L); return 1; diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.h b/cocos/scripting/lua/bindings/lua_xml_http_request.h index 2b5a3a2f17..900ec6db35 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.h +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.h @@ -66,11 +66,17 @@ public: void setRequestHeader(const char* field, const char* value); std::map getHttpHeader() { return _httpHeader ;} + + void getByteData(unsigned char* byteData); + + inline std::string getDataStr() { return _data.str(); } + + inline size_t getDataSize() { return _dataSize; } + private: void _gotHeader(std::string header); - std::string _url; std::string _meth; std::string _type; @@ -89,6 +95,6 @@ private: std::map _requestHeader; }; -TOLUA_API int lua_xml_http_request_open(lua_State* L); +TOLUA_API int register_xml_http_request(lua_State* L); #endif //#ifndef __COCOS_SCRIPTING_LUA_BINDINGS_LUA_XML_HTTP_REQUEST_H__ diff --git a/cocos/scripting/lua/script/json.lua b/cocos/scripting/lua/script/json.lua new file mode 100755 index 0000000000..e0b3d17c3e --- /dev/null +++ b/cocos/scripting/lua/script/json.lua @@ -0,0 +1,376 @@ +----------------------------------------------------------------------------- +-- JSON4Lua: JSON encoding / decoding support for the Lua language. +-- json Module. +-- Author: Craig Mason-Jones +-- Homepage: http://json.luaforge.net/ +-- Version: 0.9.40 +-- This module is released under the MIT License (MIT). +-- Please see LICENCE.txt for details. +-- +-- USAGE: +-- This module exposes two functions: +-- encode(o) +-- Returns the table / string / boolean / number / nil / json.null value as a JSON-encoded string. +-- decode(json_string) +-- Returns a Lua object populated with the data encoded in the JSON string json_string. +-- +-- REQUIREMENTS: +-- compat-5.1 if using Lua 5.0 +-- +-- CHANGELOG +-- 0.9.20 Introduction of local Lua functions for private functions (removed _ function prefix). +-- Fixed Lua 5.1 compatibility issues. +-- Introduced json.null to have null values in associative arrays. +-- encode() performance improvement (more than 50%) through table.concat rather than .. +-- Introduced decode ability to ignore /**/ comments in the JSON string. +-- 0.9.10 Fix to array encoding / decoding to correctly manage nil/null values in arrays. +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Imports and dependencies +----------------------------------------------------------------------------- +local math = require('math') +local string = require("string") +local table = require("table") + +local base = _G + +----------------------------------------------------------------------------- +-- Module declaration +----------------------------------------------------------------------------- +module("json") + +-- Public functions + +-- Private functions +local decode_scanArray +local decode_scanComment +local decode_scanConstant +local decode_scanNumber +local decode_scanObject +local decode_scanString +local decode_scanWhitespace +local encodeString +local isArray +local isEncodable + +----------------------------------------------------------------------------- +-- PUBLIC FUNCTIONS +----------------------------------------------------------------------------- +--- Encodes an arbitrary Lua object / variable. +-- @param v The Lua object / variable to be JSON encoded. +-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode) +function encode (v) + -- Handle nil values + if v==nil then + return "null" + end + + local vtype = base.type(v) + + -- Handle strings + if vtype=='string' then + return '"' .. encodeString(v) .. '"' -- Need to handle encoding in string + end + + -- Handle booleans + if vtype=='number' or vtype=='boolean' then + return base.tostring(v) + end + + -- Handle tables + if vtype=='table' then + local rval = {} + -- Consider arrays separately + local bArray, maxCount = isArray(v) + if bArray then + for i = 1,maxCount do + table.insert(rval, encode(v[i])) + end + else -- An object, not an array + for i,j in base.pairs(v) do + if isEncodable(i) and isEncodable(j) then + table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j)) + end + end + end + if bArray then + return '[' .. table.concat(rval,',') ..']' + else + return '{' .. table.concat(rval,',') .. '}' + end + end + + -- Handle null values + if vtype=='function' and v==null then + return 'null' + end + + base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v)) +end + + +--- Decodes a JSON string and returns the decoded value as a Lua data structure / value. +-- @param s The string to scan. +-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1. +-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil, +-- and the position of the first character after +-- the scanned JSON object. +function decode(s, startPos) + startPos = startPos and startPos or 1 + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']') + local curChar = string.sub(s,startPos,startPos) + -- Object + if curChar=='{' then + return decode_scanObject(s,startPos) + end + -- Array + if curChar=='[' then + return decode_scanArray(s,startPos) + end + -- Number + if string.find("+-0123456789.e", curChar, 1, true) then + return decode_scanNumber(s,startPos) + end + -- String + if curChar==[["]] or curChar==[[']] then + return decode_scanString(s,startPos) + end + if string.sub(s,startPos,startPos+1)=='/*' then + return decode(s, decode_scanComment(s,startPos)) + end + -- Otherwise, it must be a constant + return decode_scanConstant(s,startPos) +end + +--- The null function allows one to specify a null value in an associative array (which is otherwise +-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null } +function null() + return null -- so json.null() will also return null ;-) +end +----------------------------------------------------------------------------- +-- Internal, PRIVATE functions. +-- Following a Python-like convention, I have prefixed all these 'PRIVATE' +-- functions with an underscore. +----------------------------------------------------------------------------- + +--- Scans an array from JSON into a Lua object +-- startPos begins at the start of the array. +-- Returns the array and the next starting position +-- @param s The string being scanned. +-- @param startPos The starting position for the scan. +-- @return table, int The scanned array as a table, and the position of the next character to scan. +function decode_scanArray(s,startPos) + local array = {} -- The return value + local stringLen = string.len(s) + base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s ) + startPos = startPos + 1 + -- Infinite loop for array elements + repeat + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.') + local curChar = string.sub(s,startPos,startPos) + if (curChar==']') then + return array, startPos+1 + end + if (curChar==',') then + startPos = decode_scanWhitespace(s,startPos+1) + end + base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.') + object, startPos = decode(s,startPos) + table.insert(array,object) + until false +end + +--- Scans a comment and discards the comment. +-- Returns the position of the next character following the comment. +-- @param string s The JSON string to scan. +-- @param int startPos The starting position of the comment +function decode_scanComment(s, startPos) + base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos) + local endPos = string.find(s,'*/',startPos+2) + base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos) + return endPos+2 +end + +--- Scans for given constants: true, false or null +-- Returns the appropriate Lua type, and the position of the next character to read. +-- @param s The string being scanned. +-- @param startPos The position in the string at which to start scanning. +-- @return object, int The object (true, false or nil) and the position at which the next character should be +-- scanned. +function decode_scanConstant(s, startPos) + local consts = { ["true"] = true, ["false"] = false, ["null"] = nil } + local constNames = {"true","false","null"} + + for i,k in base.pairs(constNames) do + --print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k) + if string.sub(s,startPos, startPos + string.len(k) -1 )==k then + return consts[k], startPos + string.len(k) + end + end + base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos) +end + +--- Scans a number from the JSON encoded string. +-- (in fact, also is able to scan numeric +- eqns, which is not +-- in the JSON spec.) +-- Returns the number, and the position of the next character +-- after the number. +-- @param s The string being scanned. +-- @param startPos The position at which to start scanning. +-- @return number, int The extracted number and the position of the next character to scan. +function decode_scanNumber(s,startPos) + local endPos = startPos+1 + local stringLen = string.len(s) + local acceptableChars = "+-0123456789.e" + while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true) + and endPos<=stringLen + ) do + endPos = endPos + 1 + end + local stringValue = 'return ' .. string.sub(s,startPos, endPos-1) + local stringEval = base.loadstring(stringValue) + base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos) + return stringEval(), endPos +end + +--- Scans a JSON object into a Lua object. +-- startPos begins at the start of the object. +-- Returns the object and the next starting position. +-- @param s The string being scanned. +-- @param startPos The starting position of the scan. +-- @return table, int The scanned object as a table and the position of the next character to scan. +function decode_scanObject(s,startPos) + local object = {} + local stringLen = string.len(s) + local key, value + base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s) + startPos = startPos + 1 + repeat + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.') + local curChar = string.sub(s,startPos,startPos) + if (curChar=='}') then + return object,startPos+1 + end + if (curChar==',') then + startPos = decode_scanWhitespace(s,startPos+1) + end + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.') + -- Scan the key + key, startPos = decode(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + startPos = decode_scanWhitespace(s,startPos) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos) + startPos = decode_scanWhitespace(s,startPos+1) + base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key) + value, startPos = decode(s,startPos) + object[key]=value + until false -- infinite loop while key-value pairs are found +end + +--- Scans a JSON string from the opening inverted comma or single quote to the +-- end of the string. +-- Returns the string extracted as a Lua string, +-- and the position of the next non-string character +-- (after the closing inverted comma or single quote). +-- @param s The string being scanned. +-- @param startPos The starting position of the scan. +-- @return string, int The extracted string as a Lua string, and the next character to parse. +function decode_scanString(s,startPos) + base.assert(startPos, 'decode_scanString(..) called without start position') + local startChar = string.sub(s,startPos,startPos) + base.assert(startChar==[[']] or startChar==[["]],'decode_scanString called for a non-string') + local escaped = false + local endPos = startPos + 1 + local bEnded = false + local stringLen = string.len(s) + repeat + local curChar = string.sub(s,endPos,endPos) + if not escaped then + if curChar==[[\]] then + escaped = true + else + bEnded = curChar==startChar + end + else + -- If we're escaped, we accept the current character come what may + escaped = false + end + endPos = endPos + 1 + base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos) + until bEnded + local stringValue = 'return ' .. string.sub(s, startPos, endPos-1) + local stringEval = base.loadstring(stringValue) + base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos) + return stringEval(), endPos +end + +--- Scans a JSON string skipping all whitespace from the current start position. +-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached. +-- @param s The string being scanned +-- @param startPos The starting position where we should begin removing whitespace. +-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string +-- was reached. +function decode_scanWhitespace(s,startPos) + local whitespace=" \n\r\t" + local stringLen = string.len(s) + while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true) and startPos <= stringLen) do + startPos = startPos + 1 + end + return startPos +end + +--- Encodes a string to be JSON-compatible. +-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-) +-- @param s The string to return as a JSON encoded (i.e. backquoted string) +-- @return The string appropriately escaped. +function encodeString(s) + s = string.gsub(s,'\\','\\\\') + s = string.gsub(s,'"','\\"') + s = string.gsub(s,"'","\\'") + s = string.gsub(s,'\n','\\n') + s = string.gsub(s,'\t','\\t') + return s +end + +-- Determines whether the given Lua type is an array or a table / dictionary. +-- We consider any table an array if it has indexes 1..n for its n items, and no +-- other data in the table. +-- I think this method is currently a little 'flaky', but can't think of a good way around it yet... +-- @param t The table to evaluate as an array +-- @return boolean, number True if the table can be represented as an array, false otherwise. If true, +-- the second returned value is the maximum +-- number of indexed elements in the array. +function isArray(t) + -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable + -- (with the possible exception of 'n') + local maxIndex = 0 + for k,v in base.pairs(t) do + if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then -- k,v is an indexed pair + if (not isEncodable(v)) then return false end -- All array elements must be encodable + maxIndex = math.max(maxIndex,k) + else + if (k=='n') then + if v ~= table.getn(t) then return false end -- False if n does not hold the number of elements + else -- Else of (k=='n') + if isEncodable(v) then return false end + end -- End of (k~='n') + end -- End of k,v not an indexed pair + end -- End of loop across all pairs + return true, maxIndex +end + +--- Determines whether the given Lua object / table / variable can be JSON encoded. The only +-- types that are JSON encodable are: string, boolean, number, nil, table and json.null. +-- In this implementation, all other types are ignored. +-- @param o The object to examine. +-- @return boolean True if the object should be JSON encoded, false if it should be ignored. +function isEncodable(o) + local t = base.type(o) + return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null) +end + diff --git a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua new file mode 100644 index 0000000000..2456d5d092 --- /dev/null +++ b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua @@ -0,0 +1,147 @@ +require("json") + +local function XMLHttpRequestLayer() + local layer = cc.Layer:create() + local winSize = cc.Director:getInstance():getWinSize() + local margin = 40 + local space = 35 + + local function init() + local label = cc.LabelTTF:create("XML Http Request Test", "Arial", 28) + label:setPosition(cc.p(winSize.width / 2, winSize.height - margin)) + layer:addChild(label, 0) + + --Response Code Label + local labelStatusCode = cc.LabelTTF:create("HTTP Status Code", "Marker Felt", 20) + labelStatusCode:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 6 * space)) + layer:addChild(labelStatusCode) + + local menuRequest = cc.Menu:create() + menuRequest:setPosition(cc.p(0,0)) + layer:addChild(menuRequest) + + --Get + local function onMenuGetClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 0 + xhr:open("GET", "http://httpbin.org/get") + + local function onReadyStateChange() + local statusString = "Http Status Code:"..xhr.statusText + labelStatusCode:setString(statusString) + print(xhr.response) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelGet = cc.LabelTTF:create("Test Get", "Arial", 22) + local itemGet = cc.MenuItemLabel:create(labelGet) + itemGet:registerScriptTapHandler(onMenuGetClicked) + itemGet:setPosition(cc.p(winSize.width / 2, winSize.height - margin - space)) + menuRequest:addChild(itemGet) + + --Post + local function onMenuPostClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 0 + xhr:open("POST", "http://httpbin.org/post") + local function onReadyStateChange() + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + print(xhr.response) + end + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPost = cc.LabelTTF:create("Test Post", "Arial", 22) + local itemPost = cc.MenuItemLabel:create(labelPost) + itemPost:registerScriptTapHandler(onMenuPostClicked) + itemPost:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 2 * space)) + menuRequest:addChild(itemPost) + + --Post Binary + local function onMenuPostBinaryClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 1 + xhr:open("POST", "http://httpbin.org/post") + + local function onReadyStateChange() + local response = xhr.response + local size = table.getn(response) + local strInfo = "" + + for i = 1,size do + if 0 == response[i] then + strInfo = strInfo.."\'\\0\'" + else + strInfo = strInfo..string.char(response[i]) + end + end + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + print(strInfo) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPostBinary = cc.LabelTTF:create("Test Post Binary", "Arial", 22) + local itemPostBinary = cc.MenuItemLabel:create(labelPostBinary) + itemPostBinary:registerScriptTapHandler(onMenuPostBinaryClicked) + itemPostBinary:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 3 * space)) + menuRequest:addChild(itemPostBinary) + + --Post Json + + local function onMenuPostJsonClicked() + local xhr = XMLHttpRequest:new() + xhr.responseType = 4 + xhr:open("POST", "http://httpbin.org/post") + + local function onReadyStateChange() + labelStatusCode:setString("Http Status Code:"..xhr.statusText) + local response = xhr.response + local output = json.decode(response,1) + table.foreach(output,function(i, v) print (i, v) end) + print("headers are") + table.foreach(output.headers,print) + end + + xhr:registerScriptHandler(onReadyStateChange) + xhr:send() + + labelStatusCode:setString("waiting...") + end + + local labelPostJson = cc.LabelTTF:create("Test Post Json", "Arial", 22) + local itemPostJson = cc.MenuItemLabel:create(labelPostJson) + itemPostJson:registerScriptTapHandler(onMenuPostJsonClicked) + itemPostJson:setPosition(cc.p(winSize.width / 2, winSize.height - margin - 4 * space)) + menuRequest:addChild(itemPostJson) + end + + local function onNodeEvent(eventName) + if "enter" == eventName then + init() + end + end + + layer:registerScriptHandler(onNodeEvent) + + return layer +end + +function XMLHttpRequestTestMain() + local scene = cc.Scene:create() + scene:addChild(XMLHttpRequestLayer()) + scene:addChild(CreateBackMenuItem()) + return scene +end diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index 73d79855d6..3129caf5cb 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -44,6 +44,7 @@ require "luaScript/TransitionsTest/TransitionsTest" require "luaScript/UserDefaultTest/UserDefaultTest" require "luaScript/ZwoptexTest/ZwoptexTest" require "luaScript/LuaBridgeTest/LuaBridgeTest" +require "luaScript/XMLHttpRequestTest/XMLHttpRequestTest" local LINE_SPACE = 40 @@ -97,7 +98,8 @@ local _allTests = { { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest }, { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain }, { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain }, - { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest } + { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest }, + { isSupported = true, name = "XMLHttpRequestTest" , create_func = XMLHttpRequestTestMain} } local TESTS_COUNT = table.getn(_allTests) From 70082ddc297d69beb33333c130dfbaaa784759c3 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 17:54:35 +0800 Subject: [PATCH 3/8] issue #3409:Add XMLHttpRequest lua binding and corresponding test sample --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/network/HttpRequest.h | 5 +- cocos/scripting/lua/bindings/Android.mk | 1 + cocos/scripting/lua/bindings/Makefile | 3 +- cocos/scripting/lua/bindings/liblua.vcxproj | 2 + .../lua/bindings/liblua.vcxproj.filters | 6 +++ samples/Lua/TestLua/proj.android/.project | 52 ++----------------- .../TestLua/proj.android/project.properties | 2 +- .../TestLua/proj.win32/TestLua.win32.vcxproj | 2 +- 9 files changed, 22 insertions(+), 53 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 17e0cee1da..e5e294b55f 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b695026fc3d856d540590ff09112696f66379c22 \ No newline at end of file +51e880f9a11e50fd1bd14a92c4bcf1004dfbc12b \ No newline at end of file diff --git a/cocos/network/HttpRequest.h b/cocos/network/HttpRequest.h index 81715d7991..141b55df29 100644 --- a/cocos/network/HttpRequest.h +++ b/cocos/network/HttpRequest.h @@ -123,7 +123,10 @@ public: /** Get the request data pointer back */ inline char* getRequestData() { - return &(_requestData.front()); + if(_requestData.size() != 0) + return &(_requestData.front()); + + return nullptr; } /** Get the size of request data back */ inline int getRequestDataSize() diff --git a/cocos/scripting/lua/bindings/Android.mk b/cocos/scripting/lua/bindings/Android.mk index a5293f66a2..b39ee5f6a5 100644 --- a/cocos/scripting/lua/bindings/Android.mk +++ b/cocos/scripting/lua/bindings/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES := CCLuaBridge.cpp \ lua_cocos2dx_manual.cpp \ lua_cocos2dx_extension_manual.cpp \ lua_cocos2dx_deprecated.cpp \ + lua_xml_http_request.cpp \ platform/android/CCLuaJavaBridge.cpp \ platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBridge.cpp \ ../../../../external/lua/tolua/tolua_event.c \ diff --git a/cocos/scripting/lua/bindings/Makefile b/cocos/scripting/lua/bindings/Makefile index 95145d5fbc..c797ce3b9e 100644 --- a/cocos/scripting/lua/bindings/Makefile +++ b/cocos/scripting/lua/bindings/Makefile @@ -60,7 +60,8 @@ SOURCES = ../../../../external/lua/lua/lapi.c \ LuaBasicConversions.cpp \ lua_cocos2dx_manual.cpp \ lua_cocos2dx_extension_manual.cpp \ - lua_cocos2dx_deprecated.cpp + lua_cocos2dx_deprecated.cpp \ + lua_xml_http_request.cpp include ../../../2d/cocos2dx.mk diff --git a/cocos/scripting/lua/bindings/liblua.vcxproj b/cocos/scripting/lua/bindings/liblua.vcxproj index ed1ef534ed..1f6f39d5c8 100644 --- a/cocos/scripting/lua/bindings/liblua.vcxproj +++ b/cocos/scripting/lua/bindings/liblua.vcxproj @@ -144,6 +144,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\lua\luajit\prebuilt\win32\*.*" "$ + @@ -168,6 +169,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\lua\luajit\prebuilt\win32\*.*" "$ + diff --git a/cocos/scripting/lua/bindings/liblua.vcxproj.filters b/cocos/scripting/lua/bindings/liblua.vcxproj.filters index 56f49872c4..d323cdf804 100644 --- a/cocos/scripting/lua/bindings/liblua.vcxproj.filters +++ b/cocos/scripting/lua/bindings/liblua.vcxproj.filters @@ -81,6 +81,9 @@ cocos2dx_support + + cocos2dx_support + @@ -149,6 +152,9 @@ cocos2dx_support + + cocos2dx_support + diff --git a/samples/Lua/TestLua/proj.android/.project b/samples/Lua/TestLua/proj.android/.project index 3c1261c623..8703060095 100644 --- a/samples/Lua/TestLua/proj.android/.project +++ b/samples/Lua/TestLua/proj.android/.project @@ -6,56 +6,12 @@ - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.buildArguments - ${ProjDirPath}/build_native.sh - - - org.eclipse.cdt.make.core.buildCommand - bash - - - org.eclipse.cdt.make.core.buildLocation - ${ProjDirPath} - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - false + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch diff --git a/samples/Lua/TestLua/proj.android/project.properties b/samples/Lua/TestLua/proj.android/project.properties index 0a6dc6664d..94dd07f59d 100644 --- a/samples/Lua/TestLua/proj.android/project.properties +++ b/samples/Lua/TestLua/proj.android/project.properties @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-10 +target=android-15 android.library.reference.1=../../../../cocos/2d/platform/android/java diff --git a/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj b/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj index 0a4ea9edbd..f70904ac2f 100644 --- a/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj +++ b/samples/Lua/TestLua/proj.win32/TestLua.win32.vcxproj @@ -84,7 +84,7 @@ MachineX86 true $(OutDir);%(AdditionalLibraryDirectories) - lua51.lib;websockets.lib;%(AdditionalDependencies) + libcurl_imp.lib;lua51.lib;websockets.lib;%(AdditionalDependencies) 0x0409 From 663b27d1e76afc89a92ef0b04991430f22c40618 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 18:06:02 +0800 Subject: [PATCH 4/8] #3049:Add XMLHttpRequest lua binding and corresponding test sample --- cocos/network/HttpRequest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/network/HttpRequest.h b/cocos/network/HttpRequest.h index 141b55df29..4282193043 100644 --- a/cocos/network/HttpRequest.h +++ b/cocos/network/HttpRequest.h @@ -123,8 +123,8 @@ public: /** Get the request data pointer back */ inline char* getRequestData() { - if(_requestData.size() != 0) - return &(_requestData.front()); + if(_requestData.size() != 0) + return &(_requestData.front()); return nullptr; } From 471bbb8af95e7a2879bcd8dc1f41892927572984 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Tue, 29 Oct 2013 18:21:15 +0800 Subject: [PATCH 5/8] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- cocos/scripting/lua/bindings/lua_xml_http_request.cpp | 4 ---- samples/Lua/TestLua/proj.android/project.properties | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp index f63e55c0b1..945b36a16a 100644 --- a/cocos/scripting/lua/bindings/lua_xml_http_request.cpp +++ b/cocos/scripting/lua/bindings/lua_xml_http_request.cpp @@ -209,10 +209,6 @@ void LuaMinXmlHttpRequest::handle_requestResponse(network::HttpClient *sender, n /** get the response data **/ std::vector *buffer = response->getResponseData(); -// for (unsigned int i = 0; i < buffer->size(); i++) -// { -// printf("%c", (*buffer)[i]); -// } char* concatenated = (char*) malloc(buffer->size() + 1); std::string s2(buffer->begin(), buffer->end()); strcpy(concatenated, s2.c_str()); diff --git a/samples/Lua/TestLua/proj.android/project.properties b/samples/Lua/TestLua/proj.android/project.properties index 94dd07f59d..0a6dc6664d 100644 --- a/samples/Lua/TestLua/proj.android/project.properties +++ b/samples/Lua/TestLua/proj.android/project.properties @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-15 +target=android-10 android.library.reference.1=../../../../cocos/2d/platform/android/java From c08a09a7e088eaec7b5dbca85e2ca0349a0f45a8 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Wed, 30 Oct 2013 10:52:04 +0800 Subject: [PATCH 6/8] #3049:Add LICENSE_JSON4LUA and some constant values. --- .gitignore | 2 ++ .../scripting/lua/script/Cocos2dConstants.lua | 8 +++++++ licenses/LICENSE_JSON4Lua.txt | 21 +++++++++++++++++++ .../XMLHttpRequestTest/XMLHttpRequestTest.lua | 8 +++---- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 licenses/LICENSE_JSON4Lua.txt diff --git a/.gitignore b/.gitignore index d6bae12eb7..91ab9c7356 100644 --- a/.gitignore +++ b/.gitignore @@ -22,10 +22,12 @@ Thumbs.db *.log [Bb]in [Dd]ebug/ +[Dd]ebug.win32/ *.sbr *.sdf obj/ [Rr]elease/ +[Rr]elease.win32/ _ReSharper*/ [Tt]est[Rr]esult* ipch/ diff --git a/cocos/scripting/lua/script/Cocos2dConstants.lua b/cocos/scripting/lua/script/Cocos2dConstants.lua index 5a8ae27e94..cc43ce5ee3 100644 --- a/cocos/scripting/lua/script/Cocos2dConstants.lua +++ b/cocos/scripting/lua/script/Cocos2dConstants.lua @@ -272,3 +272,11 @@ cc.WEBSOCKET_STATE_CONNECTING = 0 cc.WEBSOCKET_STATE_OPEN = 1 cc.WEBSOCKET_STATE_CLOSING = 2 cc.WEBSOCKET_STATE_CLOSED = 3 + + +cc.XMLHTTPREQUEST_RESPONSE_STRING = 0 +cc.XMLHTTPREQUEST_RESPONSE_ARRAY_BUFFER = 1 +cc.XMLHTTPREQUEST_RESPONSE_BLOB = 2 +cc.XMLHTTPREQUEST_RESPONSE_DOCUMENT = 3 +cc.XMLHTTPREQUEST_RESPONSE_JSON = 4 + \ No newline at end of file diff --git a/licenses/LICENSE_JSON4Lua.txt b/licenses/LICENSE_JSON4Lua.txt new file mode 100644 index 0000000000..7e0d778e8c --- /dev/null +++ b/licenses/LICENSE_JSON4Lua.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009 Craig Mason-Jones + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE diff --git a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua index 2456d5d092..1cdffa035a 100644 --- a/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua +++ b/samples/Lua/TestLua/Resources/luaScript/XMLHttpRequestTest/XMLHttpRequestTest.lua @@ -23,7 +23,7 @@ local function XMLHttpRequestLayer() --Get local function onMenuGetClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 0 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING xhr:open("GET", "http://httpbin.org/get") local function onReadyStateChange() @@ -47,7 +47,7 @@ local function XMLHttpRequestLayer() --Post local function onMenuPostClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 0 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() labelStatusCode:setString("Http Status Code:"..xhr.statusText) @@ -68,7 +68,7 @@ local function XMLHttpRequestLayer() --Post Binary local function onMenuPostBinaryClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 1 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_ARRAY_BUFFER xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() @@ -103,7 +103,7 @@ local function XMLHttpRequestLayer() local function onMenuPostJsonClicked() local xhr = XMLHttpRequest:new() - xhr.responseType = 4 + xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_JSON xhr:open("POST", "http://httpbin.org/post") local function onReadyStateChange() From de4aaeda2d232f72f3d02695456898a29e456bcd Mon Sep 17 00:00:00 2001 From: samuelhu Date: Thu, 31 Oct 2013 22:06:34 +0800 Subject: [PATCH 7/8] issue #3049:Add XMLHttpRequest lua binding and corresponding test sample --- build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- samples/Lua/TestLua/Resources/luaScript/mainMenu.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 3a1978b2ff..9bd7c96932 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3cdc74655a14f57ae21036886ccf31e32aaadce4 \ No newline at end of file +99dcbba48124bf51788735fe775650f659d7302c \ No newline at end of file diff --git a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua index c1c5088530..9c4640be8e 100644 --- a/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua +++ b/samples/Lua/TestLua/Resources/luaScript/mainMenu.lua @@ -44,6 +44,7 @@ require "luaScript/TransitionsTest/TransitionsTest" require "luaScript/UserDefaultTest/UserDefaultTest" require "luaScript/ZwoptexTest/ZwoptexTest" require "luaScript/LuaBridgeTest/LuaBridgeTest" +require "luaScript/XMLHttpRequestTest/XMLHttpRequestTest" local LINE_SPACE = 40 @@ -97,6 +98,7 @@ local _allTests = { { isSupported = true, name = "TouchesTest" , create_func = TouchesTest }, { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest }, { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain }, + { isSupported = true, name = "XMLHttpRequestTest" , create_func = XMLHttpRequestTestMain }, { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain } } From 5010779e39242f9b0ff40cbee5b1fcb247ad2e86 Mon Sep 17 00:00:00 2001 From: samuelhu Date: Fri, 1 Nov 2013 11:36:06 +0800 Subject: [PATCH 8/8] issue #3049:Reset .project file in pro.android. --- samples/Lua/TestLua/proj.android/.project | 52 +++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/samples/Lua/TestLua/proj.android/.project b/samples/Lua/TestLua/proj.android/.project index 8703060095..3c1261c623 100644 --- a/samples/Lua/TestLua/proj.android/.project +++ b/samples/Lua/TestLua/proj.android/.project @@ -6,12 +6,56 @@ - org.eclipse.ui.externaltools.ExternalToolBuilder - full,incremental, + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, - LaunchConfigHandle - <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + ${ProjDirPath}/build_native.sh + + + org.eclipse.cdt.make.core.buildCommand + bash + + + org.eclipse.cdt.make.core.buildLocation + ${ProjDirPath} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false