int _wrap_setCallback(lua_State *L) { luaL_argcheck(L, lua_isfunction(L, 1), 1, "Expected function"); instance->setCallback(L); return 0; }
static Quaternion* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "Quaternion"); luaL_argcheck(state, userdata != NULL, 1, "'Quaternion' expected."); return (Quaternion*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance; }
static Gamepad* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "Gamepad"); luaL_argcheck(state, userdata != NULL, 1, "'Gamepad' expected."); return (Gamepad*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance; }
// Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) static int mqtt_socket_connect( lua_State* L ) { NODE_DBG("enter mqtt_socket_connect.\n"); lmqtt_userdata *mud = NULL; unsigned port = 1883; size_t il; ip_addr_t ipaddr; const char *domain; int stack = 1; unsigned secure = 0, auto_reconnect = 0; int top = lua_gettop(L); mud = (lmqtt_userdata *)luaL_checkudata(L, stack, "mqtt.socket"); luaL_argcheck(L, mud, stack, "mqtt.socket expected"); stack++; if(mud == NULL) return 0; if(mud->connected){ return luaL_error(L, "already connected"); } if(mud->pesp_conn){ //TODO: should I free tcp struct directly or ask user to call close()??? mud->pesp_conn->reverse = NULL; if(mud->pesp_conn->proto.tcp) c_free(mud->pesp_conn->proto.tcp); mud->pesp_conn->proto.tcp = NULL; c_free(mud->pesp_conn); mud->pesp_conn = NULL; } struct espconn *pesp_conn = NULL; pesp_conn = mud->pesp_conn = (struct espconn *)c_zalloc(sizeof(struct espconn)); if(!pesp_conn) return luaL_error(L, "not enough memory"); pesp_conn->proto.udp = NULL; pesp_conn->proto.tcp = (esp_tcp *)c_zalloc(sizeof(esp_tcp)); if(!pesp_conn->proto.tcp){ c_free(pesp_conn); pesp_conn = mud->pesp_conn = NULL; return luaL_error(L, "not enough memory"); } // reverse is for the callback function pesp_conn->reverse = mud; pesp_conn->type = ESPCONN_TCP; pesp_conn->state = ESPCONN_NONE; mud->connected = false; if( (stack<=top) && lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } if ( (stack<=top) && lua_isnumber(L, stack) ) { port = lua_tointeger(L, stack); stack++; NODE_DBG("TCP port is set: %d.\n", port); } pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); mud->mqtt_state.port = port; if ( (stack<=top) && lua_isnumber(L, stack) ) { secure = lua_tointeger(L, stack); stack++; if ( secure != 0 && secure != 1 ){ secure = 0; // default to 0 } } else { secure = 0; // default to 0 } mud->secure = secure; // save if ( (stack<=top) && lua_isnumber(L, stack) ) { auto_reconnect = lua_tointeger(L, stack); stack++; if ( auto_reconnect != 0 && auto_reconnect != 1 ){ auto_reconnect = 0; // default to 0 } } else { auto_reconnect = 0; // default to 0 } mud->mqtt_state.auto_reconnect = auto_reconnect; // call back function when a connection is obtained, tcp only if ((stack<=top) && (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(mud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_connect_ref); mud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); stack++; } lua_pushvalue(L, 1); // copy userdata to the top of stack if(mud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->self_ref); mud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); espconn_regist_connectcb(pesp_conn, mqtt_socket_connected); espconn_regist_reconcb(pesp_conn, mqtt_socket_reconnected); os_timer_disarm(&mud->mqttTimer); os_timer_setfn(&mud->mqttTimer, (os_timer_func_t *)mqtt_socket_timer, mud); // timer started in socket_connect() if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } NODE_DBG("leave mqtt_socket_connect.\n"); return 0; }
static int luaB_costatus (lua_State *L) { lua_State *co = lua_tothread(L, 1); luaL_argcheck(L, co, 1, "coroutine expected"); lua_pushstring(L, statnames[costatus(L, co)]); return 1; }
// Lua: bool = mqtt:subscribe(topic, qos, function()) static int mqtt_socket_subscribe( lua_State* L ) { NODE_DBG("enter mqtt_socket_subscribe.\n"); uint8_t stack = 1, qos = 0; uint16_t msg_id = 0; const char *topic; size_t il; lmqtt_userdata *mud; mud = (lmqtt_userdata *) luaL_checkudata( L, stack, "mqtt.socket" ); luaL_argcheck( L, mud, stack, "mqtt.socket expected" ); stack++; if(mud==NULL){ NODE_DBG("userdata is nil.\n"); lua_pushboolean(L, 0); return 1; } if(mud->pesp_conn == NULL){ NODE_DBG("mud->pesp_conn is NULL.\n"); lua_pushboolean(L, 0); return 1; } if(!mud->connected){ luaL_error( L, "not connected" ); lua_pushboolean(L, 0); return 1; } uint8_t temp_buffer[MQTT_BUF_SIZE]; mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); mqtt_message_t *temp_msg = NULL; if( lua_istable( L, stack ) ) { NODE_DBG("subscribe table\n"); lua_pushnil( L ); /* first key */ uint8_t temp_buf[MQTT_BUF_SIZE]; uint32_t temp_pos = 0; while( lua_next( L, stack ) != 0 ) { topic = luaL_checkstring( L, -2 ); qos = luaL_checkinteger( L, -1 ); temp_msg = mqtt_msg_subscribe( &mud->mqtt_state.mqtt_connection, topic, qos, &msg_id ); NODE_DBG("topic: %s - qos: %d, length: %d\n", topic, qos, temp_msg->length); if (temp_pos + temp_msg->length > MQTT_BUF_SIZE){ lua_pop(L, 1); break; // too long message for the outbuffer. } c_memcpy( temp_buf + temp_pos, temp_msg->data, temp_msg->length ); temp_pos += temp_msg->length; lua_pop( L, 1 ); } if (temp_pos == 0){ luaL_error( L, "invalid data" ); lua_pushboolean(L, 0); return 1; } c_memcpy( temp_buffer, temp_buf, temp_pos ); temp_msg->data = temp_buffer; temp_msg->length = temp_pos; stack++; } else { NODE_DBG("subscribe string\n"); topic = luaL_checklstring( L, stack, &il ); stack++; if( topic == NULL ){ luaL_error( L, "need topic name" ); lua_pushboolean(L, 0); return 1; } qos = luaL_checkinteger( L, stack ); temp_msg = mqtt_msg_subscribe( &mud->mqtt_state.mqtt_connection, topic, qos, &msg_id ); stack++; } if( lua_type( L, stack ) == LUA_TFUNCTION || lua_type( L, stack ) == LUA_TLIGHTFUNCTION ) { // TODO: this will overwrite the previous one. lua_pushvalue( L, stack ); // copy argument (func) to the top of stack if( mud->cb_suback_ref != LUA_NOREF ) luaL_unref( L, LUA_REGISTRYINDEX, mud->cb_suback_ref ); mud->cb_suback_ref = luaL_ref( L, LUA_REGISTRYINDEX ); } msg_queue_t *node = msg_enqueue( &(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_SUBSCRIBE, (int)mqtt_get_qos(temp_msg->data) ); NODE_DBG("topic: %s - id: %d - qos: %d, length: %d\n", topic, node->msg_id, node->publish_qos, node->msg.length); if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){ mud->event_timeout = MQTT_SEND_TIMEOUT; NODE_DBG("Sent: %d\n", node->msg.length); if( mud->secure ) espconn_secure_sent( mud->pesp_conn, node->msg.data, node->msg.length ); else espconn_sent( mud->pesp_conn, node->msg.data, node->msg.length ); mud->keep_alive_tick = 0; } if(!node){ lua_pushboolean(L, 0); } else { lua_pushboolean(L, 1); // enqueued succeed. } NODE_DBG("subscribe, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_subscribe.\n"); return 1; }
// Lua: mqtt:lwt( topic, message, qos, retain, function(client) ) static int mqtt_socket_lwt( lua_State* L ) { NODE_DBG("enter mqtt_socket_lwt.\n"); uint8_t stack = 1; size_t topicSize, msgSize; NODE_DBG("mqtt_socket_lwt.\n"); lmqtt_userdata *mud = NULL; const char *lwtTopic, *lwtMsg; uint8_t lwtQoS, lwtRetain; mud = (lmqtt_userdata *)luaL_checkudata( L, stack, "mqtt.socket" ); luaL_argcheck( L, mud, stack, "mqtt.socket expected" ); if(mud == NULL) return 0; stack++; lwtTopic = luaL_checklstring( L, stack, &topicSize ); if (lwtTopic == NULL) { return luaL_error( L, "need lwt topic"); } stack++; lwtMsg = luaL_checklstring( L, stack, &msgSize ); if (lwtMsg == NULL) { return luaL_error( L, "need lwt message"); } if(mud->connect_info.will_topic){ // free the previous one if there is any c_free(mud->connect_info.will_topic); mud->connect_info.will_topic = NULL; } if(mud->connect_info.will_message){ c_free(mud->connect_info.will_message); mud->connect_info.will_message = NULL; } mud->connect_info.will_topic = (uint8_t*) c_zalloc( topicSize + 1 ); mud->connect_info.will_message = (uint8_t*) c_zalloc( msgSize + 1 ); if(!mud->connect_info.will_topic || !mud->connect_info.will_message){ if(mud->connect_info.will_topic){ c_free(mud->connect_info.will_topic); mud->connect_info.will_topic = NULL; } if(mud->connect_info.will_message){ c_free(mud->connect_info.will_message); mud->connect_info.will_message = NULL; } return luaL_error( L, "not enough memory"); } c_memcpy(mud->connect_info.will_topic, lwtTopic, topicSize); mud->connect_info.will_topic[topicSize] = 0; c_memcpy(mud->connect_info.will_message, lwtMsg, msgSize); mud->connect_info.will_message[msgSize] = 0; if ( lua_isnumber(L, stack) ) { mud->connect_info.will_qos = lua_tointeger(L, stack); stack++; } if ( lua_isnumber(L, stack) ) { mud->connect_info.will_retain = lua_tointeger(L, stack); stack++; } NODE_DBG("mqtt_socket_lwt: topic: %s, message: %s, qos: %d, retain: %d\n", mud->connect_info.will_topic, mud->connect_info.will_message, mud->connect_info.will_qos, mud->connect_info.will_retain); NODE_DBG("leave mqtt_socket_lwt.\n"); return 0; }
static uv_tcp_t* luv_check_tcp(lua_State* L, int index) { uv_tcp_t* handle = luaL_checkudata(L, index, "uv_tcp"); luaL_argcheck(L, handle->type == UV_TCP && handle->data, index, "Expected uv_tcp_t"); return handle; }
static int str_format (lua_State *L) { int top = lua_gettop(L); int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format ('%...') */ char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ int nb = 0; /* number of bytes in added item */ if (++arg > top) luaL_argerror(L, arg, "no value"); strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { lua_Integer n = luaL_checkinteger(L, arg); addlenmod(form, LUA_INTEGER_FRMLEN); nb = l_sprintf(buff, MAX_ITEM, form, n); break; } case 'a': case 'A': addlenmod(form, LUA_NUMBER_FRMLEN); nb = lua_number2strx(L, buff, MAX_ITEM, form, luaL_checknumber(L, arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': { addlenmod(form, LUA_NUMBER_FRMLEN); nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg)); break; } case 'q': { addliteral(L, &b, arg); break; } case 's': { size_t l; const char *s = luaL_tolstring(L, arg, &l); if (form[2] == '\0') /* no modifiers? */ luaL_addvalue(&b); /* keep entire string */ else { luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted */ luaL_addvalue(&b); /* keep entire string */ } else { /* format the string into 'buff' */ nb = l_sprintf(buff, MAX_ITEM, form, s); lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } } break; } default: { /* also treat cases 'pnLlh' */ return luaL_error(L, "invalid option '%%%c' to 'format'", *(strfrmt - 1)); } } lua_assert(nb < MAX_ITEM); luaL_addsize(&b, nb); } } luaL_pushresult(&b); return 1; }
void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const String& error) const { luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); }
static Technique* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "Technique"); luaL_argcheck(state, userdata != NULL, 1, "'Technique' expected."); return (Technique*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance; }
void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) const { luaL_argcheck(m_state, condition, argNum, error); }
static NumArray *checkarray(lua_State *L) { void *ud = luaL_checkudata(L, 1, "LuaBook.array"); luaL_argcheck(L, ud != NULL, 1, "'array' expected"); return (NumArray *)ud; }
/* Lua only functions */ int luaT_lua_newmetatable(lua_State *L) { const char* tname = luaL_checkstring(L, 1); const void *id; lua_settop(L, 5); luaL_argcheck(L, lua_isnoneornil(L, 2) || lua_isstring(L, 2), 2, "parent class name or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "constructor function or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isfunction(L, 4), 4, "destructor function or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 5) || lua_isfunction(L, 5), 5, "factory function or nil expected"); if(luaT_classmodulename(tname)) lua_getfield(L, LUA_GLOBALSINDEX, luaT_classmodulename(tname)); else lua_pushvalue(L, LUA_GLOBALSINDEX); if(!lua_istable(L, 6)) luaL_error(L, "while creating metatable %s: bad argument #1 (%s is an invalid module name)", tname, luaT_classmodulename(tname)); /* we first create the new metaclass if we have to */ if(!luaT_typename2id(L, tname)) { /* create the metaclass */ lua_newtable(L); id = lua_topointer(L, -1); /* id = pointer on metaclass */ /* __index points on itself */ lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); /* new points to constructor */ lua_pushvalue(L, 3); lua_setfield(L, -2, "new"); /* __typename contains the typename */ lua_pushstring(L, tname); lua_setfield(L, -2, "__typename"); /* by default, __version equals 1 */ lua_pushnumber(L, 1); lua_setfield(L, -2, "__version"); /* register in "*torch.id2tname*" registry table (id -> typename) */ lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); } lua_pushlightuserdata(L, (void*)id); lua_pushstring(L, tname); lua_settable(L, -3); lua_pop(L, 1); /* register in "*torch.tname2id*" registry table (typename -> id) */ lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); } lua_pushstring(L, tname); lua_pushlightuserdata(L, (void*)id); lua_settable(L, -3); lua_pop(L, 1); } /* we retrieve the existing metaclass */ else { id = luaT_typename2id(L, tname); luaT_pushmetaclass(L, id); } /* we assign the parent class if necessary */ if(!lua_isnoneornil(L, 2)) { if(lua_getmetatable(L, -1)) luaL_error(L, "class %s has been already assigned a parent class\n", tname); else { const char* parenttname = luaL_checkstring(L, 2); luaT_pushmetaclass(L, luaT_typename2id(L, parenttname)); if(lua_isnil(L, -1)) luaL_error(L, "bad argument #2 (invalid parent class name %s)", parenttname); lua_setmetatable(L, -2); } } /******** root-metatable ********/ /* id is the pointer on the metatable registry[id] = root-metatable, so try to see if it exists */ lua_pushlightuserdata(L, (void*)id); /* id */ lua_rawget(L, LUA_REGISTRYINDEX); /* not existing? we create a new one! */ if(lua_isnil(L, -1)) { lua_pop(L, 1); /* remove nil on stack */ lua_newtable(L); /* __index handling */ lua_pushcfunction(L, luaT_rmt__index); lua_setfield(L, -2, "__index"); /* __newindex handling */ lua_pushcfunction(L, luaT_rmt__newindex); lua_setfield(L, -2, "__newindex"); /* __metatable field (point on the metaclass) */ lua_pushvalue(L, -2); lua_setfield(L, -2, "__metatable"); /* __typename contains the typename */ lua_pushstring(L, tname); lua_setfield(L, -2, "__typename"); /* operators handling */ #define MT_ADD_OPERATOR(name) \ lua_pushcfunction(L, luaT_rmt__##name); \ lua_setfield(L, -2, "__" #name) MT_ADD_OPERATOR(tostring); MT_ADD_OPERATOR(add); MT_ADD_OPERATOR(sub); MT_ADD_OPERATOR(mul); MT_ADD_OPERATOR(div); MT_ADD_OPERATOR(mod); MT_ADD_OPERATOR(pow); MT_ADD_OPERATOR(unm); MT_ADD_OPERATOR(concat); MT_ADD_OPERATOR(len); MT_ADD_OPERATOR(eq); MT_ADD_OPERATOR(lt); MT_ADD_OPERATOR(le); MT_ADD_OPERATOR(call); /* assign the metaclass as metatable... */ lua_pushvalue(L, -2); lua_setmetatable(L, -2); /* id is the pointer on the metatable set registry[id] = root-metatable */ lua_pushlightuserdata(L, (void*)id); /* id */ lua_pushvalue(L, -2); /* metatable */ lua_rawset(L, LUA_REGISTRYINDEX); /* registry[id] = metatable */ } /* ok, so now we have the root-metatable on the stack */ /* register the destructor function */ if(!lua_isnoneornil(L, 4)) { /* does it exists already? */ lua_pushstring(L, "__gc"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__gc"); lua_pushvalue(L, 4); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a destructor", tname); } /* register the factory function */ if(!lua_isnoneornil(L, 5)) { /* does it exists already? */ lua_pushstring(L, "__factory"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__factory"); lua_pushvalue(L, 5); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a factory", tname); } /******** Constructor table and metatable ********/ lua_pushstring(L, "__constructor"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_newtable(L); /* fancy table */ lua_newtable(L); /* fancy metatable */ lua_pushvalue(L, -4); /* metaclass */ lua_setfield(L, -2, "__index"); /* so we can get the methods */ lua_pushcfunction(L, luaT_cmt__newindex); lua_setfield(L, -2, "__newindex"); /* so we cannot messup */ lua_pushcfunction(L, luaT_cmt__call); lua_setfield(L, -2, "__call"); /* so we can create */ lua_pushvalue(L, -4); lua_setfield(L, -2, "__metatable"); /* redirect to metatable with methods */ lua_setmetatable(L, -2); /* metatable is ... the fancy metatable */ /* set root-metatable[__constructor] = constructor-metatable */ lua_pushstring(L, "__constructor"); lua_pushvalue(L, -2); lua_rawset(L, -4); } /* register the constructor function */ if(!lua_isnoneornil(L, 3)) { /* get constructor metatable */ lua_getmetatable(L, -1); /* does it exists already? */ lua_pushstring(L, "__new"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__new"); lua_pushvalue(L, 3); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a constructor", tname); /* pop constructor metatable */ lua_pop(L, 1); } lua_setfield(L, 6, luaT_classrootname(tname)); /* module.name = constructor-metatable */ lua_pop(L, 1); /* pop the root-metatable */ return 1; /* returns the metaclass */ }
static Transform::Listener* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "TransformListener"); luaL_argcheck(state, userdata != NULL, 1, "'TransformListener' expected."); return (Transform::Listener*)((ScriptUtil::LuaObject*)userdata)->instance; }
static int str_pack (lua_State *L) { luaL_Buffer b; Header h; const char *fmt = luaL_checkstring(L, 1); /* format string */ int arg = 1; /* current argument to pack */ size_t totalsize = 0; /* accumulate total size of result */ initheader(L, &h); lua_pushnil(L); /* mark to separate arguments from string buffer */ luaL_buffinit(L, &b); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); totalsize += ntoalign + size; while (ntoalign-- > 0) luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ arg++; switch (opt) { case Kint: { /* signed integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) { /* need overflow check? */ lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); } packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); break; } case Kuint: { /* unsigned integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) /* need overflow check? */ luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), arg, "unsigned overflow"); packint(&b, (lua_Unsigned)n, h.islittle, size, 0); break; } case Kfloat: { /* floating-point options */ volatile Ftypes u; char *buff = luaL_prepbuffsize(&b, size); lua_Number n = luaL_checknumber(L, arg); /* get argument */ if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ else if (size == sizeof(u.d)) u.d = (double)n; else u.n = n; /* move 'u' to final result, correcting endianness if needed */ copywithendian(buff, u.buff, size, h.islittle); luaL_addsize(&b, size); break; } case Kchar: { /* fixed-size string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, len <= (size_t)size, arg, "string longer than given size"); luaL_addlstring(&b, s, len); /* add string */ while (len++ < (size_t)size) /* pad extra space */ luaL_addchar(&b, LUAL_PACKPADBYTE); break; } case Kstring: { /* strings with length count */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, "string length does not fit in given size"); packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ luaL_addlstring(&b, s, len); totalsize += len; break; } case Kzstr: { /* zero-terminated string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); luaL_addlstring(&b, s, len); luaL_addchar(&b, '\0'); /* add zero at the end */ totalsize += len + 1; break; } case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ case Kpaddalign: case Knop: arg--; /* undo increment */ break; } } luaL_pushresult(&b); return 1; }
static PhysicsFixedConstraint* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "PhysicsFixedConstraint"); luaL_argcheck(state, userdata != NULL, 1, "'PhysicsFixedConstraint' expected."); return (PhysicsFixedConstraint*)((ScriptUtil::LuaObject*)userdata)->instance; }
static int str_unpack (lua_State *L) { Header h; const char *fmt = luaL_checkstring(L, 1); size_t ld; const char *data = luaL_checklstring(L, 2, &ld); size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; int n = 0; /* number of results */ luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); initheader(L, &h); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) luaL_argerror(L, 2, "data string too short"); pos += ntoalign; /* skip alignment */ /* stack space for item + next position */ luaL_checkstack(L, 2, "too many results"); n++; switch (opt) { case Kint: case Kuint: { lua_Integer res = unpackint(L, data + pos, h.islittle, size, (opt == Kint)); lua_pushinteger(L, res); break; } case Kfloat: { volatile Ftypes u; lua_Number num; copywithendian(u.buff, data + pos, size, h.islittle); if (size == sizeof(u.f)) num = (lua_Number)u.f; else if (size == sizeof(u.d)) num = (lua_Number)u.d; else num = u.n; lua_pushnumber(L, num); break; } case Kchar: { lua_pushlstring(L, data + pos, size); break; } case Kstring: { size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); lua_pushlstring(L, data + pos + size, len); pos += len; /* skip string */ break; } case Kzstr: { size_t len = (int)strlen(data + pos); lua_pushlstring(L, data + pos, len); pos += len + 1; /* skip string plus final '\0' */ break; } case Kpaddalign: case Kpadding: case Knop: n--; /* undo increment */ break; } pos += size; } lua_pushinteger(L, pos + 1); /* next position */ return n + 1; }
// Lua: bool = mqtt:publish( topic, payload, qos, retain, function() ) static int mqtt_socket_publish( lua_State* L ) { NODE_DBG("enter mqtt_socket_publish.\n"); struct espconn *pesp_conn = NULL; lmqtt_userdata *mud; size_t l; uint8_t stack = 1; uint16_t msg_id = 0; mud = (lmqtt_userdata *)luaL_checkudata(L, stack, "mqtt.socket"); luaL_argcheck(L, mud, stack, "mqtt.socket expected"); stack++; if(mud==NULL){ NODE_DBG("userdata is nil.\n"); lua_pushboolean(L, 0); return 1; } if(mud->pesp_conn == NULL){ NODE_DBG("mud->pesp_conn is NULL.\n"); lua_pushboolean(L, 0); return 1; } if(!mud->connected){ luaL_error( L, "not connected" ); lua_pushboolean(L, 0); return 1; } const char *topic = luaL_checklstring( L, stack, &l ); stack ++; if (topic == NULL){ luaL_error( L, "need topic" ); lua_pushboolean(L, 0); return 1; } const char *payload = luaL_checklstring( L, stack, &l ); stack ++; uint8_t qos = luaL_checkinteger( L, stack); stack ++; uint8_t retain = luaL_checkinteger( L, stack); stack ++; uint8_t temp_buffer[MQTT_BUF_SIZE]; mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); mqtt_message_t *temp_msg = mqtt_msg_publish(&mud->mqtt_state.mqtt_connection, topic, payload, l, qos, retain, &msg_id); if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(mud->cb_puback_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_puback_ref); mud->cb_puback_ref = luaL_ref(L, LUA_REGISTRYINDEX); } msg_queue_t *node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, msg_id, MQTT_MSG_TYPE_PUBLISH, (int)qos ); if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){ mud->event_timeout = MQTT_SEND_TIMEOUT; NODE_DBG("Sent: %d\n", node->msg.length); if( mud->secure ) espconn_secure_sent( mud->pesp_conn, node->msg.data, node->msg.length ); else espconn_sent( mud->pesp_conn, node->msg.data, node->msg.length ); mud->keep_alive_tick = 0; } if(!node){ lua_pushboolean(L, 0); } else { lua_pushboolean(L, 1); // enqueued succeed. } NODE_DBG("publish, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q))); NODE_DBG("leave mqtt_socket_publish.\n"); return 1; }
// helper function: retrieve and check userdata argument static lucg_userdata_t *get_lud( lua_State *L ) { lucg_userdata_t *lud = (lucg_userdata_t *)luaL_checkudata(L, 1, "ucg.display"); luaL_argcheck(L, lud, 1, "ucg.display expected"); return lud; }
// Lua: mqtt.delete( socket ) // call close() first // socket: unref everything static int mqtt_delete( lua_State* L ) { NODE_DBG("enter mqtt_delete.\n"); lmqtt_userdata *mud = (lmqtt_userdata *)luaL_checkudata(L, 1, "mqtt.socket"); luaL_argcheck(L, mud, 1, "mqtt.socket expected"); if(mud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } os_timer_disarm(&mud->mqttTimer); mud->connected = false; // ---- alloc-ed in mqtt_socket_connect() if(mud->pesp_conn){ // for client connected to tcp server, this should set NULL in disconnect cb mud->pesp_conn->reverse = NULL; if(mud->pesp_conn->proto.tcp) c_free(mud->pesp_conn->proto.tcp); mud->pesp_conn->proto.tcp = NULL; c_free(mud->pesp_conn); mud->pesp_conn = NULL; // for socket, it will free this when disconnected } // ---- alloc-ed in mqtt_socket_lwt() if(mud->connect_info.will_topic){ c_free(mud->connect_info.will_topic); mud->connect_info.will_topic = NULL; } if(mud->connect_info.will_message){ c_free(mud->connect_info.will_message); mud->connect_info.will_message = NULL; } // ---- //--------- alloc-ed in mqtt_socket_client() if(mud->connect_info.client_id){ c_free(mud->connect_info.client_id); mud->connect_info.client_id = NULL; } if(mud->connect_info.username){ c_free(mud->connect_info.username); mud->connect_info.username = NULL; } if(mud->connect_info.password){ c_free(mud->connect_info.password); mud->connect_info.password = NULL; } // ------- // free (unref) callback ref if(LUA_NOREF!=mud->cb_connect_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_connect_ref); mud->cb_connect_ref = LUA_NOREF; } if(LUA_NOREF!=mud->cb_disconnect_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_disconnect_ref); mud->cb_disconnect_ref = LUA_NOREF; } if(LUA_NOREF!=mud->cb_message_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_message_ref); mud->cb_message_ref = LUA_NOREF; } if(LUA_NOREF!=mud->cb_suback_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_suback_ref); mud->cb_suback_ref = LUA_NOREF; } if(LUA_NOREF!=mud->cb_puback_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_puback_ref); mud->cb_puback_ref = LUA_NOREF; } lua_gc(L, LUA_GCSTOP, 0); if(LUA_NOREF!=mud->self_ref){ luaL_unref(L, LUA_REGISTRYINDEX, mud->self_ref); mud->self_ref = LUA_NOREF; } lua_gc(L, LUA_GCRESTART, 0); NODE_DBG("leave mqtt_delete.\n"); return 0; }
/* ** Get a connection object from the first stack position. */ static conn_data *getconnection (lua_State *L) { conn_data *conn = (conn_data *)luaL_checkudata (L, 1, LUALDAP_CONNECTION_METATABLE); luaL_argcheck(L, conn!=NULL, 1, LUALDAP_PREFIX"LDAP connection expected"); luaL_argcheck(L, conn->ld, 1, LUALDAP_PREFIX"LDAP connection is closed"); return conn; }
static BoundingBox* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "BoundingBox"); luaL_argcheck(state, userdata != NULL, 1, "'BoundingBox' expected."); return (BoundingBox*)((ScriptUtil::LuaObject*)userdata)->instance; }
/* ** Get a search object from the first upvalue position. */ static search_data *getsearch (lua_State *L) { /* don't need to check upvalue's integrity */ search_data *search = (search_data *)lua_touserdata (L, lua_upvalueindex (1)); luaL_argcheck (L,search->conn!=LUA_NOREF,1,LUALDAP_PREFIX"LDAP search is closed"); return search; }
static uv_prepare_t* luv_check_prepare(lua_State* L, int index) { uv_prepare_t* handle = luv_checkudata(L, index, "uv_prepare"); luaL_argcheck(L, handle->type == UV_PREPARE && handle->data, index, "Expected uv_prepare_t"); return handle; }
static time_t l_checktime (lua_State *L, int arg) { lua_Integer t = luaL_checkinteger(L, arg); luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); return (time_t)t; }
static uv_fs_poll_t* luv_check_fs_poll(lua_State* L, int index) { uv_fs_poll_t* handle = luaL_checkudata(L, index, "uv_fs_poll"); luaL_argcheck(L, handle->type == UV_FS_POLL && handle->data, index, "Expected uv_fs_poll_t"); return handle; }
static VertexFormat* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "VertexFormat"); luaL_argcheck(state, userdata != NULL, 1, "'VertexFormat' expected."); return (VertexFormat*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance; }
static AIStateMachine* getInstance(lua_State* state) { void* userdata = luaL_checkudata(state, 1, "AIStateMachine"); luaL_argcheck(state, userdata != NULL, 1, "'AIStateMachine' expected."); return (AIStateMachine*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance; }
int _wrap_registerSignal(lua_State *L) { luaL_argcheck(L, lua_isnumber(L, 1), 1, "Expected number"); lua_pushboolean(L, instance->registerSignal(lua_tonumber(L, 1))); return 1; }