static int luazmq_skt_recv_len (lua_State *L) { zsocket *skt = luazmq_getsocket(L); size_t len = luaL_checkint(L, 2); int flags = luaL_optint(L,3,0); int ret, more; size_t more_size = sizeof(more); LUAZMQ_DEFINE_TEMP_BUFFER(tmp); char *buffer = LUAZMQ_ALLOC_TEMP(tmp, len); if(!buffer) return luazmq_allocfail(L); ret = zmq_recv(skt->skt, buffer, len, flags); if(-1 == ret){ LUAZMQ_FREE_TEMP(tmp, buffer); return luazmq_fail(L, skt); } assert(ret >= 0); lua_pushlstring(L, buffer, (ret < len)?ret:len); LUAZMQ_FREE_TEMP(tmp, buffer); len = ret; ret = zmq_getsockopt(skt->skt, ZMQ_RCVMORE, &more, &more_size); if(-1 == ret) return luazmq_fail(L, skt); if( more ){ skt->flags |= LUAZMQ_FLAG_MORE; lua_pushboolean(L, 1); } else{ skt->flags &= ~LUAZMQ_FLAG_MORE; lua_pushboolean(L, 0); } lua_pushinteger(L, len); return 3; }
static int luazmq_skt_recv_all (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmq_msg_t msg; int flags = luaL_optint(L,2,0); int i = 0; int result_index = lua_gettop(L) + 1; lua_newtable(L); while(1){ int ret = zmq_msg_init(&msg); if(-1 == ret){ ret = luazmq_fail(L, skt); lua_pushvalue(L,result_index); return ret + 1; } ret = zmq_msg_recv(&msg, skt->skt, flags); if(-1 == ret){ ret = luazmq_fail(L, skt); zmq_msg_close(&msg); lua_pushvalue(L,result_index); return ret + 1; } lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg)); lua_rawseti(L, result_index, ++i); ret = zmq_msg_more(&msg); zmq_msg_close(&msg); if(!ret) break; } return 1; }
static int luazmq_skt_set_i64 (lua_State *L, int option_name) { zsocket *skt = luazmq_getsocket(L); int64_t option_value = (int64_t)luaL_checknumber(L, 2); int ret = zmq_setsockopt(skt->skt, option_name, &option_value, sizeof(option_value)); if (ret == -1) return luazmq_fail(L, skt); return luazmq_pass(L); }
int luazmq_msg_init_data_array(lua_State *L){ size_t top = lua_rawlen(L, 1); size_t i; size_t size = 0; for(i = 1; i<=top; ++i){ lua_rawgeti(L,1,i); size += lua_rawlen(L,-1); lua_pop(L, 1); } if (0 == size) return luazmq_msg_init(L); { zmessage *zmsg = luazmq_newudata(L, zmessage, LUAZMQ_MESSAGE); int err = zmq_msg_init_size(&zmsg->msg, size); size_t pos; if(-1 == err) return luazmq_fail(L, NULL); for(pos = 0, i = 1; i<=top; ++i){ const char *data; lua_rawgeti(L, 1, i); data = luaL_checklstring(L,-1,&size); memcpy((char*)zmq_msg_data(&zmsg->msg) + pos, data, size); pos += size; lua_pop(L, 1); } } return 1; }
int luazmq_msg_init_size(lua_State *L){ size_t size = luaL_checkinteger(L,1); zmessage *zmsg = luazmq_newudata(L, zmessage, LUAZMQ_MESSAGE); int err = zmq_msg_init_size(&zmsg->msg, size); if(-1 == err) return luazmq_fail(L, NULL); return 1; }
static int luazmq_skt_monitor (lua_State *L) { zsocket *skt = luazmq_getsocket(L); char endpoint[128]; const char *bind; int ret, events; if( (lua_gettop(L) == 1) || /* s:monitor() */ (lua_type(L, 2) == LUA_TNUMBER) /* s:monitor(EVENT_ALL) */ ){ #ifdef _MSC_VER sprintf_s(endpoint, sizeof(endpoint), "inproc://lzmq.monitor.%p", skt->skt); #else sprintf(endpoint, "inproc://lzmq.monitor.%p", skt->skt); #endif bind = endpoint; events = luaL_optint(L, 2, ZMQ_EVENT_ALL); } else{ bind = luaL_checkstring(L, 2); events = luaL_optint(L, 3, ZMQ_EVENT_ALL); } ret = zmq_socket_monitor (skt->skt, bind, events); if(-1 == ret){ return luazmq_fail(L, skt); } lua_pushstring(L, bind); return 1; }
static int luazmq_skt_get_fdt (lua_State *L, int option_name) { /** @fixme return lightuserdata because of SOCKET has 64 bit * on Windows x64. */ zsocket *skt = luazmq_getsocket(L); int ret; fd_t option_value; #if defined(ZMQ_IDENTITY_FD) if(option_name == ZMQ_IDENTITY_FD){ char buffer[255]; size_t len; const char *id = luaL_checklstring(L, 2, &len); luaL_argcheck(L, len <= sizeof(buffer), 2, "identity too big"); memcpy(buffer, id, len); ret = zmq_getsockopt(skt->skt, option_name, buffer, &len); memcpy(&option_value, buffer, sizeof(option_value)); } else #endif { size_t len = sizeof(option_value); ret = zmq_getsockopt(skt->skt, option_name, &option_value, &len); } if (ret == -1) return luazmq_fail(L, skt); lua_pushnumber(L, (lua_Number)option_value); return 1; }
static int luazmq_skt_get_str (lua_State *L, int option_name) { zsocket *skt = luazmq_getsocket(L); char option_value[255]; size_t len = sizeof(option_value); int ret = zmq_getsockopt(skt->skt, option_name, option_value, &len); if (ret == -1) return luazmq_fail(L, skt); lua_pushlstring(L, option_value, len); return 1; }
static int luazmq_skt_set_str (lua_State *L, int option_name) { zsocket *skt = luazmq_getsocket(L); size_t len; const char *option_value = luaL_checklstring(L, 2, &len); int ret = zmq_setsockopt(skt->skt, option_name, option_value, len); if (ret == -1) return luazmq_fail(L, skt); return luazmq_pass(L); }
static int luazmq_skt_send_msg (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmessage *msg = luazmq_getmessage_at(L,2); int flags = luaL_optint(L,3,0); int ret = zmq_msg_send(&msg->msg, skt->skt, flags); if(-1 == ret) return luazmq_fail(L, skt); return luazmq_pass(L); }
static int luazmq_msg_get(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); int optname = luaL_checkinteger(L,1); int err = zmq_msg_get(&zmsg->msg, optname); if(-1 == err)return luazmq_fail(L, NULL); lua_pushinteger(L, err); return 1; }
static int luazmq_msg_set(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); int optname = luaL_checkinteger(L,1); int optval = luaL_checkinteger(L,2); int err = zmq_msg_set(&zmsg->msg, optname, optval); if(-1 == err)return luazmq_fail(L, NULL); return luazmq_pass(L); }
static int luazmq_msg_send(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); zsocket *zskt = luazmq_getsocket_at(L, 2); int flags = luaL_optint(L, 3, 0); int err = zmq_msg_send(&zmsg->msg, zskt->skt, flags); if(-1 == err)return luazmq_fail(L, zskt); return luazmq_pass(L); }
static int luazmq_skt_get_i64 (lua_State *L, int option_name) { zsocket *skt = luazmq_getsocket(L); int64_t option_value; size_t len = sizeof(option_value); int ret = zmq_getsockopt(skt->skt, option_name, &option_value, &len); if (ret == -1) return luazmq_fail(L, skt); lua_pushnumber(L, (lua_Number)option_value); return 1; }
static int luazmq_skt_reset_monitor (lua_State *L) { zsocket *skt = luazmq_getsocket(L); int ret = zmq_socket_monitor (skt->skt, NULL, 0); if(-1 == ret){ return luazmq_fail(L, skt); } return luazmq_pass(L); }
int luazmq_msg_init_data(lua_State *L){ zmessage *zmsg = luazmq_newudata(L, zmessage, LUAZMQ_MESSAGE); size_t size; const char *data = luaL_checklstring(L,1,&size); int err = zmq_msg_init_size(&zmsg->msg, size); if(-1 == err) return luazmq_fail(L, NULL); memcpy(zmq_msg_data(&zmsg->msg), data, size); return 1; }
static int luazmq_msg_copy(lua_State *L){ zmessage *dst, *src; int err; if(lua_gettop(L) == 1){ src = luazmq_getmessage_at(L, 1); dst = luazmq_newudata(L, zmessage, LUAZMQ_MESSAGE); err = zmq_msg_init(&dst->msg); if(-1 == err) return luazmq_fail(L, NULL); } else{ dst = luazmq_getmessage_at(L, 1); src = luazmq_getmessage_at(L, 2); lua_pushvalue(L, 1); // result } err = zmq_msg_copy(&dst->msg, &src->msg); if(-1 == err) return luazmq_fail(L, NULL); return 1; }
static int luazmq_msg_recv(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); zsocket *zskt = luazmq_getsocket_at(L, 2); int flags = luaL_optint(L, 3, 0); int err = zmq_msg_recv(&zmsg->msg, zskt->skt, flags); if(-1 == err)return luazmq_fail(L, zskt); lua_settop(L, 1); lua_pushboolean(L, zmq_msg_more(&zmsg->msg)); return 2; }
static int luazmq_skt_send (lua_State *L) { zsocket *skt = luazmq_getsocket(L); size_t len; const char *data = luaL_checklstring(L, 2, &len); int ret, flags = luaL_optint(L,3,0); #ifdef LUAZMQ_USE_SEND_AS_BUF ret = zmq_send(skt->skt, data, len, flags); #else zmq_msg_t msg; ret = zmq_msg_init_size(&msg, len); if(-1 == ret) return luazmq_fail(L, skt); memcpy(zmq_msg_data(&msg), data, len); ret = zmq_msg_send(&msg, skt->skt, flags); zmq_msg_close(&msg); #endif if(-1 == ret) return luazmq_fail(L, skt); return luazmq_pass(L); }
static int luazmq_skt_send_all (lua_State *L) { zsocket *skt = luazmq_getsocket(L); int flags = luaL_optint(L,3,0); int n, i = luaL_optint(L,4,1); if(lua_isnoneornil(L, 5)){ n = lua_objlen(L, 2); } else{ n = luaL_checkint(L, 5); luaL_argcheck(L, n >= i, 5, "invalid range"); } if(flags & (~ZMQ_SNDMORE)){ lua_pushnil(L); luazmq_error_create(L, ENOTSUP); return 2; } for(;i <= n; ++i){ zmq_msg_t msg; const char *data;size_t len; int ret; lua_rawgeti(L, 2, i); data = luaL_checklstring(L, -1, &len); ret = zmq_msg_init_size(&msg, len); if(-1 == ret){ ret = luazmq_fail(L, skt); lua_pushinteger(L, i); return ret + 1; } memcpy(zmq_msg_data(&msg), data, len); ret = zmq_msg_send(&msg, skt->skt, (i == n)?flags:ZMQ_SNDMORE); zmq_msg_close(&msg); if(-1 == ret){ ret = luazmq_fail(L, skt); lua_pushinteger(L, i); return ret + 1; } } return luazmq_pass(L); }
static int luazmq_msg_set_size(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); size_t nsize = luaL_checkinteger(L, 2); size_t osize = zmq_msg_size(&zmsg->msg); int err; zmq_msg_t msg; if(nsize == osize) return luazmq_pass(L); err = zmq_msg_init_size(&msg, nsize); if(-1 == err)return luazmq_fail(L, NULL); memcpy(zmq_msg_data(&msg), zmq_msg_data(&zmsg->msg), (nsize>osize)?osize:nsize); err = zmq_msg_move(&zmsg->msg, &msg); if(-1 == err){ zmq_msg_close(&msg); return luazmq_fail(L, NULL); } zmq_msg_close(&msg); // @FIXME do not close message return luazmq_pass(L); }
static int luazmq_skt_sendx_impl(lua_State *L, int last_flag) { zsocket *skt = luazmq_getsocket(L); size_t i, n = lua_gettop(L); for(i = 2; i<=n; ++i){ zmq_msg_t msg; size_t len; const char *data = luaL_checklstring(L, i, &len); int ret = zmq_msg_init_size(&msg, len); if(-1 == ret){ ret = luazmq_fail(L, skt); lua_pushinteger(L, i); return ret + 1; } memcpy(zmq_msg_data(&msg), data, len); ret = zmq_msg_send(&msg, skt->skt, (i == n)?last_flag:ZMQ_SNDMORE); zmq_msg_close(&msg); if(-1 == ret){ ret = luazmq_fail(L, skt); lua_pushinteger(L, i); return ret + 1; } } return luazmq_pass(L); }
static int luazmq_skt_poll (lua_State *L) { zsocket *skt = luazmq_getsocket(L); int timeout = luaL_optint(L, 2, -1); int mask = luaL_optint(L, 3, ZMQ_POLLIN); zmq_pollitem_t items [] = { { skt->skt, 0, mask, 0 } }; if(-1 == zmq_poll (items, 1, timeout)){ return luazmq_fail(L, skt); } lua_pushboolean(L, (items[0].revents & mask)?1:0); lua_pushinteger(L, items[0].revents); return 2; }
static int luazmq_skt_sendv_impl(lua_State *L, int flags) { zsocket *skt = luazmq_getsocket(L); size_t i, size = 0, top = lua_gettop(L); zmq_msg_t msg; int ret; for(i = 2; i<=top; ++i){ size_t s; luaL_checklstring(L,i,&s); size += s; } if (0 == size){ ret = zmq_msg_init(&msg); } else { ret = zmq_msg_init_size(&msg, size); } if(-1 == ret) return luazmq_fail(L, skt); { size_t pos; for(pos = 0, i = 2; i<=top; ++i){ const char *data = luaL_checklstring(L,i,&size); memcpy((char*)zmq_msg_data(&msg) + pos, data, size); pos += size; } } ret = zmq_msg_send(&msg, skt->skt, flags); zmq_msg_close(&msg); if(-1 == ret) return luazmq_fail(L, skt); return luazmq_pass(L); }
static int luazmq_skt_recv (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmq_msg_t msg; int flags = luaL_optint(L,2,0); int ret = zmq_msg_init(&msg); if(-1 == ret) return luazmq_fail(L, skt); ret = zmq_msg_recv(&msg, skt->skt, flags); if(-1 == ret){ zmq_msg_close(&msg); return luazmq_fail(L, skt); } lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg)); if( zmq_msg_more(&msg) ){ skt->flags |= LUAZMQ_FLAG_MORE; lua_pushboolean(L, 1); } else{ skt->flags &= ~LUAZMQ_FLAG_MORE; lua_pushboolean(L, 0); } zmq_msg_close(&msg); return 2; }
static int luazmq_skt_recvx (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmq_msg_t msg; int flags = luaL_optint(L,2,0); int i = 0; lua_settop(L, 1); while(1){ int ret = zmq_msg_init(&msg); if(-1 == ret){ ret = luazmq_fail(L, skt); {int j;for(j = ret; j >= 0; --j){ lua_insert(L, 1); }} return ret + i; } ret = zmq_msg_recv(&msg, skt->skt, flags); if(-1 == ret){ zmq_msg_close(&msg); ret = luazmq_fail(L, skt); {int j;for(j = ret; j >= 0; --j){ lua_insert(L, 1); }} return ret + i; } i++; lua_checkstack(L, i); lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg)); ret = zmq_msg_more(&msg); zmq_msg_close(&msg); if(!ret) break; } return i; }
static int luazmq_msg_set_data(lua_State *L){ zmessage *zmsg = luazmq_getmessage(L); int start_pos = (lua_gettop(L) >= 3)?luaL_optint(L,2,1):1; size_t size; const char *data = luaL_checklstring(L, (lua_gettop(L) >= 3)?3:2, &size); int err; luaL_argcheck(L, start_pos >= 0, 2, "can not be negative or zero"); start_pos = start_pos - 1; if((start_pos + size) > zmq_msg_size(&zmsg->msg)){ zmq_msg_t msg; err = zmq_msg_init_size(&msg, start_pos + size); if(-1 == err)return luazmq_fail(L, NULL); memcpy(zmq_msg_data(&msg), zmq_msg_data(&zmsg->msg), zmq_msg_size(&zmsg->msg)); err = zmq_msg_move(&zmsg->msg, &msg); if(-1 == err){ zmq_msg_close(&msg); return luazmq_fail(L, NULL); } zmq_msg_close(&msg); // @FIXME do not close message } memcpy( (char*)zmq_msg_data(&zmsg->msg) + start_pos, data, size); return luazmq_pass(L); }
static int luazmq_skt_has_event (lua_State *L) { zsocket *skt = luazmq_getsocket(L); int i, top = lua_gettop(L); int option_value; size_t len = sizeof(option_value); int ret = zmq_getsockopt(skt->skt, ZMQ_EVENTS, &option_value, &len); if (ret == -1) return luazmq_fail(L, skt); luaL_checkint(L, 2); /* we need at least one event */ for(i = 2; i <= top; ++i){ lua_pushboolean(L, option_value & luaL_checkint(L, i)); lua_replace(L, i); } return top - 1; }
static int luazmq_skt_recv_msg (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmessage *msg = luazmq_getmessage_at(L,2); int flags = luaL_optint(L,3,0); int ret = zmq_msg_recv(&msg->msg, skt->skt, flags); if(-1 == ret) return luazmq_fail(L, skt); lua_settop(L, 2); // remove flags if( zmq_msg_more(&msg->msg) ){ skt->flags |= LUAZMQ_FLAG_MORE; lua_pushboolean(L, 1); } else{ skt->flags &= ~LUAZMQ_FLAG_MORE; lua_pushboolean(L, 0); } return 2; }
static int luazmq_skt_bind_to_random_port (lua_State *L) { zsocket *skt = luazmq_getsocket(L); LUAZMQ_DEFINE_TEMP_BUFFER(buffer_storage); size_t dest_len; const char *base_address = luaL_checklstring(L, 2, &dest_len); int base_port = luaL_optint(L, 3, RANDOM_PORT_BASE); int max_tries = luaL_optint(L, 4, RANDOM_PORT_MAX - base_port + 1); char *dest; luaL_argcheck(L, ((base_port > 0) && (base_port <= RANDOM_PORT_MAX)), 3, "invalid port number"); luaL_argcheck(L, (max_tries > 0), 4, "invalid max tries value"); dest = LUAZMQ_ALLOC_TEMP(buffer_storage, dest_len + 10); memcpy(dest, base_address, dest_len); dest[dest_len] = ':'; for(;(base_port <= RANDOM_PORT_MAX)&&(max_tries > 0); --max_tries, ++base_port){ int ret; sprintf(&dest[dest_len+1], "%d", base_port); ret = zmq_bind(skt->skt, dest); if(ret != -1){ LUAZMQ_FREE_TEMP(buffer_storage, dest); lua_pushinteger(L, base_port); return 1; } else{ int err = zmq_errno(); if(err == EADDRINUSE) continue; if(err == EACCES) continue; #ifdef _WIN32 #if !defined(_MSC_VER) || (_MSC_VER < 1600) if(strcmp(zmq_strerror(err), "Address in use") == 0) continue; #endif #endif break; } } LUAZMQ_FREE_TEMP(buffer_storage, dest); return luazmq_fail(L, skt); }