summaryrefslogtreecommitdiffstats
path: root/main/lua-zmq/git-20121231.patch
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2013-10-09 12:32:19 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2013-10-09 12:32:19 +0000
commit33c6ff68a8f4636af737bcb8835b246628ce327a (patch)
treea07ba38227cf5af80286ab35be4a45420c9cab38 /main/lua-zmq/git-20121231.patch
parent22cdb9ccdfc90c1087dc7db9c4138aca7fb823ef (diff)
downloadaports-33c6ff68a8f4636af737bcb8835b246628ce327a.tar.bz2
aports-33c6ff68a8f4636af737bcb8835b246628ce327a.tar.xz
main/lua-zmq: upgrade to git 20130709 and build for both lua 5.1 and 5.2
Diffstat (limited to 'main/lua-zmq/git-20121231.patch')
-rw-r--r--main/lua-zmq/git-20121231.patch13813
1 files changed, 0 insertions, 13813 deletions
diff --git a/main/lua-zmq/git-20121231.patch b/main/lua-zmq/git-20121231.patch
deleted file mode 100644
index cfeaaebc3..000000000
--- a/main/lua-zmq/git-20121231.patch
+++ /dev/null
@@ -1,13813 +0,0 @@
-diff --git a/API.md b/API.md
-index f15da79..9cdcb8e 100644
---- a/API.md
-+++ b/API.md
-@@ -147,6 +147,14 @@ See [zmq_msg_copy(3)](http://api.zeromq.org/zmq_msg_copy.html).
-
- msg1:copy(msg2) -- copy contents from msg2 -> msg1
-
-+## set_size(size)
-+
-+Re-initialize the message with a new size. The current contents will be lost.
-+See [zmq_msg_init_size(3)](http://api.zeromq.org/zmq_msg_init_size.html).
-+
-+ msg:set_size(size) -- re-initialize message if size is different from current size.
-+ local buf = msg:data() -- get buffer to fill message with new contents.
-+
- ## set_data(data)
-
- Change the message contents.
-@@ -156,7 +164,7 @@ See [zmq_msg_data(3)](http://api.zeromq.org/zmq_msg_data.html).
-
- ## data()
-
--Get the message contents.
-+Get a lightuserdata pointer to the message contents.
- See [zmq_msg_data(3)](http://api.zeromq.org/zmq_msg_data.html).
-
- local data = msg:data() -- get the message contents
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 6c3ed78..6471a17 100755
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -9,12 +9,10 @@ set(BUILD_SHARED_LIBS TRUE)
-
- set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
-
--set(INSTALL_LMOD share/lua/5.1 CACHE PATH "Directory to install Lua source modules (configure lua via LUA_PATH)")
--set(INSTALL_CMOD lib/lua/5.1 CACHE PATH "Directory to install Lua binary modules (configure lua via LUA_CPATH)")
--set(LUA_NATIVE_OBJECTS_PATH ../LuaNativeObjects CACHE PATH
-- "Directory to LuaNativeObjects bindings generator.")
--set(USE_PRE_GENERATED_BINDINGS TRUE CACHE BOOL
-- "Set this to FALSE to re-generate bindings using LuaNativeObjects")
-+set(INSTALL_LMOD ${CMAKE_INSTALL_PREFIX}/share/lua/5.1 CACHE PATH
-+ "Directory to install Lua source modules (configure lua via LUA_PATH)")
-+set(INSTALL_CMOD ${CMAKE_INSTALL_PREFIX}/lib/lua/5.1 CACHE PATH
-+ "Directory to install Lua binary modules (configure lua via LUA_CPATH)")
- set(ZMQ_PATH "" CACHE PATH
- "Directory to libzmq. (by default use pkg-config to detect path)")
-
-@@ -27,6 +25,17 @@ include(FindLua51)
- if(NOT ${LUA51_FOUND})
- message(FATAL_ERROR "The FindLua51 module could not find lua :-(")
- endif()
-+if(WIN32)
-+ set(COMMON_CFLAGS "${COMMON_CFLAGS} -I${LUA_INCLUDE_DIR}")
-+ set(COMMON_LDFLAGS "${COMMON_LDFLAGS} ${LUA_LIBRARY}")
-+ if(NOT MSVC)
-+ set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -Wl,--export-all-symbols")
-+ endif()
-+endif()
-+## MAC OSX needs extra linker flags
-+if(APPLE)
-+ set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -undefined dynamic_lookup")
-+endif()
-
- ## LibZMQ
- if(WIN32)
-@@ -38,8 +47,13 @@ if(WIN32)
- endif()
- if(IS_DIRECTORY ${ZMQ_PATH})
- set(COMMON_CFLAGS "${COMMON_CFLAGS} -I${ZMQ_PATH}/include")
-- set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -L${ZMQ_PATH}/lib")
-- set(COMMON_LIBS "${COMMON_LIBS};zmq")
-+ if(MSVC)
-+ set(COMMON_LIBS "${COMMON_LIBS};libzmq")
-+ else()
-+ set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -L${ZMQ_PATH}/lib")
-+ set(COMMON_LIBS "${COMMON_LIBS};zmq")
-+ endif()
-+ link_directories(${ZMQ_PATH}/lib)
- else()
- ## fallback to using pkg-config
- include(FindPkgConfig)
-@@ -51,13 +65,12 @@ endif()
-
- ## LuaNativeObjects
- include(LuaNativeObjects)
-+include(CustomMacros)
-
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${LUA_INCLUDE_DIR})
-
--link_directories(${ZMQ_LIBRARY_DIRS})
--
- ## LuaZMQ
- set(LUA_ZMQ_SRC
- zmq.nobj.lua
-@@ -79,8 +92,8 @@ endif()
- add_library(lua-zmq MODULE ${LUA_ZMQ_SRC})
- target_link_libraries(lua-zmq ${COMMON_LIBS})
- set_target_properties(lua-zmq PROPERTIES PREFIX "")
--set_target_properties(lua-zmq PROPERTIES COMPILE_FLAGS "${COMMON_CFLAGS}")
--set_target_properties(lua-zmq PROPERTIES LINK_FLAGS "${COMMON_LDFLAGS}")
-+add_target_properties(lua-zmq COMPILE_FLAGS "${COMMON_CFLAGS}")
-+add_target_properties(lua-zmq LINK_FLAGS "${LD_FLAGS} ${COMMON_LDFLAGS}")
- set_target_properties(lua-zmq PROPERTIES OUTPUT_NAME zmq)
-
- install(TARGETS lua-zmq
-diff --git a/COPYRIGHT b/COPYRIGHT
-new file mode 100644
-index 0000000..9840d93
---- /dev/null
-+++ b/COPYRIGHT
-@@ -0,0 +1,19 @@
-+Copyright (c) 2011 by Robert G. Jakabosky <bobby@neoawareness.com>
-+
-+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/README.md b/README.md
-index eac5f5f..830e350 100644
---- a/README.md
-+++ b/README.md
-@@ -3,6 +3,11 @@ About
-
- Lua bindings to zeromq2. Check out the [ZeroMQ Guide with Lua examples](http://zguide.zeromq.org/lua:all).
-
-+Windows
-+=======
-+
-+Download a compiled version of [LuaJIT 2.0.0-beta11 + lua-zmq + zeromq2.2.0](https://github.com/downloads/Neopallium/lua-zmq/luajit2.0_beta11_zmq2.2_llthreads.zip) 32bit & 64bit.
-+
- API
- ===
-
-@@ -12,7 +17,7 @@ See [API.md](https://github.com/Neopallium/lua-zmq/blob/master/API.md) and
- Requirements
- ============
-
--* ZeroMQ version 2.1.x.
-+* ZeroMQ version 2.1, 2.2 or 3.2.
- * Might work with some 2.0.x versions (2.0.6 and lower are not supported).
-
- For Ubuntu 10.10 users:
-@@ -22,7 +27,7 @@ For Ubuntu 10.10 users:
- Installation
- ============
-
--It is recommended to either compile Lua with the "-pthread" flag or preload libpthread.so on Linux when using this module ([See this glibc bug report](http://sourceware.org/bugzilla/show_bug.cgi?id=10652):
-+It is recommended to either compile Lua with the "-pthread" flag or preload libpthread.so on Linux when using this module ([see this glibc bug report](http://sourceware.org/bugzilla/show_bug.cgi?id=10652)):
-
- $ LD_PRELOAD=/lib/libpthread.so lua
-
-@@ -45,12 +50,12 @@ Latest Git revision
-
- With LuaRocks 2.0.4.1:
-
-- $ sudo luarocks install https://github.com/Neopallium/lua-zmq/raw/master/rockspecs/lua-zmq-scm-1.rockspec
-+ $ sudo luarocks install https://raw.github.com/Neopallium/lua-zmq/master/rockspecs/lua-zmq-scm-1.rockspec
-
- For threads support:
-
-- $ sudo luarocks install https://github.com/Neopallium/lua-llthreads/raw/master/rockspecs/lua-llthreads-scm-0.rockspec
-- $ sudo luarocks install https://github.com/Neopallium/lua-zmq/raw/master/rockspecs/lua-zmq-threads-scm-0.rockspec
-+ $ sudo luarocks install https://raw.github.com/Neopallium/lua-llthreads/master/rockspecs/lua-llthreads-scm-0.rockspec
-+ $ sudo luarocks install https://raw.github.com/Neopallium/lua-zmq/master/rockspecs/lua-zmq-threads-scm-0.rockspec
-
- With CMake:
-
-diff --git a/cmake/CustomMacros.cmake b/cmake/CustomMacros.cmake
-new file mode 100644
-index 0000000..312eeff
---- /dev/null
-+++ b/cmake/CustomMacros.cmake
-@@ -0,0 +1,61 @@
-+## Orignal Macros copied from lighttpd 2.0
-+
-+## modules are without the "lib" prefix
-+
-+macro(setup_static_modules TARGET)
-+ file(WRITE ${TARGET}_builtins.h "/* auto-generated by CMake build do not edit */\n\n")
-+endmacro(setup_static_modules)
-+
-+macro(add_module TARGET MODNAME)
-+ set(_static_mod ${BUILD_STATIC})
-+
-+ ## create list of module source files.
-+ set(_srcfiles)
-+ set(_def_module_src ${CMAKE_CURRENT_SOURCE_DIR}/modules/${MODNAME}.c)
-+ if(EXISTS ${_def_module_src})
-+ set(_srcfiles ${_def_module_src})
-+ endif(EXISTS ${_def_module_src})
-+ foreach(_srcfile ${ARGN})
-+ if(_srcfile STREQUAL "STATIC")
-+ set(_static_mod TRUE)
-+ else(_srcfile STREQUAL "STATIC")
-+ set(_srcfiles ${_srcfiles} ${_srcfile})
-+ endif(_srcfile STREQUAL "STATIC")
-+ endforeach(_srcfile)
-+
-+ if(_static_mod)
-+ set(STATIC_MODULE_SRC ${STATIC_MODULE_SRC} ${_srcfiles})
-+ file(APPEND ${TARGET}_builtins.h "STATIC_MOD(${MODNAME})\n")
-+ else(_static_mod)
-+ add_library(${MODNAME} MODULE ${_srcfiles})
-+ set(MODULE_TARGETS ${MODULE_TARGETS} ${MODNAME})
-+
-+ add_target_properties(${MODNAME} LINK_FLAGS ${COMMON_LDFLAGS})
-+ add_target_properties(${MODNAME} COMPILE_FLAGS ${COMMON_CFLAGS})
-+ set_target_properties(${MODNAME} PROPERTIES CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
-+
-+ ## Windows likes to link it this way back to app!
-+ if(WIN32)
-+ set_target_properties(${MODNAME} PROPERTIES LINK_FLAGS ${TARGET}.lib)
-+ endif(WIN32)
-+
-+ if(APPLE)
-+ set_target_properties(${MODNAME} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
-+ endif(APPLE)
-+ endif(_static_mod)
-+endmacro(add_module)
-+
-+macro(add_target_properties _target _name)
-+ set(_properties)
-+ foreach(_prop ${ARGN})
-+ set(_properties "${_properties} ${_prop}")
-+ endforeach(_prop)
-+ get_target_property(_old_properties ${_target} ${_name})
-+ ##message(STATUS "adding property to ${_target} ${_name}:" ${_properties})
-+ if(NOT _old_properties)
-+ # in case it's NOTFOUND
-+ set(_old_properties)
-+ endif(NOT _old_properties)
-+ set_target_properties(${_target} PROPERTIES ${_name} "${_old_properties} ${_properties}")
-+endmacro(add_target_properties)
-+
-diff --git a/cmake/LuaNativeObjects.cmake b/cmake/LuaNativeObjects.cmake
-index a1b0e2d..e9e47de 100644
---- a/cmake/LuaNativeObjects.cmake
-+++ b/cmake/LuaNativeObjects.cmake
-@@ -1,19 +1,39 @@
- #
- # Lua Native Objects
- #
-+
-+set(LUA_NATIVE_OBJECTS_PATH ${CMAKE_SOURCE_DIR}/../LuaNativeObjects CACHE PATH
-+ "Directory to LuaNativeObjects bindings generator.")
-+set(USE_PRE_GENERATED_BINDINGS TRUE CACHE BOOL
-+ "Set this to FALSE to re-generate bindings using LuaNativeObjects")
-+
-+set(GENERATE_LUADOCS TRUE CACHE BOOL
-+ "Set this to FALSE to avoid generation of docs using LuaDoc")
-+
- macro(GenLuaNativeObjects _src_files_var)
- set(_new_src_files)
- foreach(_src_file ${${_src_files_var}})
- if(_src_file MATCHES ".nobj.lua")
- string(REGEX REPLACE ".nobj.lua" ".nobj.c" _src_file_out ${_src_file})
-- string(REGEX REPLACE ".nobj.lua" ".nobj.h" _header_file_out ${_src_file})
-- add_custom_command(OUTPUT ${_src_file_out} ${_header_file_out}
-+ string(REGEX REPLACE ".nobj.lua" ".nobj.ffi.lua" _ffi_file_out ${_src_file})
-+ add_custom_command(OUTPUT ${_src_file_out} ${_ffi_file_out}
- COMMAND lua ${LUA_NATIVE_OBJECTS_PATH}/native_objects.lua -outpath ${CMAKE_CURRENT_BINARY_DIR} -gen lua ${_src_file}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS ${_src_file}
- )
- set_source_files_properties(${_src_file_out} PROPERTIES GENERATED TRUE)
-- set_source_files_properties(${_header_file_out} PROPERTIES GENERATED TRUE)
-+ set_source_files_properties(${_ffi_file_out} PROPERTIES GENERATED TRUE)
-+ if (${GENERATE_LUADOCS})
-+ string(REGEX REPLACE ".nobj.lua" "" _doc_base ${_src_file})
-+ string(REGEX REPLACE ".nobj.lua" ".luadoc" _doc_file_out ${_src_file})
-+ add_custom_target(${_doc_file_out} ALL
-+ COMMAND lua ${LUA_NATIVE_OBJECTS_PATH}/native_objects.lua -outpath docs -gen luadoc ${_src_file}
-+ COMMAND luadoc -nofiles -d docs docs
-+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-+ DEPENDS ${_src_file}
-+ )
-+ endif()
-+ set_source_files_properties(${_doc_file_out} PROPERTIES GENERATED TRUE)
- set(_new_src_files ${_new_src_files} ${_src_file_out})
- else(_src_file MATCHES ".nobj.lua")
- set(_new_src_files ${_new_src_files} ${_src_file})
-diff --git a/examples/client.lua b/examples/client.lua
-index 682a549..5e9849c 100644
---- a/examples/client.lua
-+++ b/examples/client.lua
-@@ -18,15 +18,24 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
--require("zmq")
-+local zmq = require"zmq"
-
--local ctx = zmq.init(1)
-+local N=tonumber(arg[1] or 100)
-+
-+local ctx = zmq.init()
- local s = ctx:socket(zmq.REQ)
-
- s:connect("tcp://localhost:5555")
-
--s:send("SELECT * FROM mytable")
--print(s:recv())
-+for i=1,N do
-+ s:send("SELECT * FROM mytable")
-+ local data, err = s:recv()
-+ if data then
-+ print(data)
-+ else
-+ print("s:recv() error:", err)
-+ end
-+end
-
- s:close()
- ctx:term()
-diff --git a/examples/client_multipart.lua b/examples/client_multipart.lua
-index e82ca26..4f10c58 100644
---- a/examples/client_multipart.lua
-+++ b/examples/client_multipart.lua
-@@ -18,17 +18,26 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
--require("zmq")
-+local zmq = require"zmq"
-
--local ctx = zmq.init(1)
-+local N=tonumber(arg[1] or 100)
-+
-+local ctx = zmq.init()
- local s = ctx:socket(zmq.REQ)
-
- s:connect("tcp://localhost:5555")
-
--s:send("SELECT * FROM mytable ", zmq.SNDMORE)
--s:send("WHERE library = 'zmq'")
-+for i=1,N do
-+ s:send("SELECT * FROM mytable ", zmq.SNDMORE)
-+ s:send("WHERE library = 'zmq'")
-
--print(s:recv())
-+ local data, err = s:recv()
-+ if data then
-+ print(data)
-+ else
-+ print("s:recv() error:", err)
-+ end
-+end
-
- s:close()
- ctx:term()
-diff --git a/examples/client_poll.lua b/examples/client_poll.lua
-new file mode 100644
-index 0000000..c49af9b
---- /dev/null
-+++ b/examples/client_poll.lua
-@@ -0,0 +1,108 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local poller = require"examples.poller"
-+local poll = poller.new()
-+
-+local zmq = require"zmq"
-+local z_NOBLOCK = zmq.NOBLOCK
-+local z_EVENTS = zmq.EVENTS
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+
-+local N=tonumber(arg[1] or 100)
-+
-+local ctx = zmq.init()
-+local s = ctx:socket(zmq.REQ)
-+local s_FD = s:getopt(zmq.FD)
-+
-+s:connect("tcp://localhost:5555")
-+
-+-- current socket state
-+local blocked_state
-+local blocked_event
-+local on_sock_recv
-+local on_sock_send
-+
-+-- IO event callback when socket was blocked
-+local function on_sock_io()
-+ local events = s:getopt(z_EVENTS)
-+ local unblocked = false
-+ if events == blocked_event then
-+ -- got the event the socket was blocked on.
-+ unblocked = true
-+ elseif events == z_POLLIN_OUT then
-+ -- got both in & out events
-+ unblocked = true
-+ end
-+ if unblocked then
-+ -- got the event we are blocked on resume.
-+ blocked_event = nil
-+ blocked_state()
-+ -- check if blocked event was processed.
-+ if not blocked_event then
-+ poll:remove_read(s_FD)
-+ end
-+ end
-+end
-+local function sock_blocked(state, event)
-+ if not blocked_event then
-+ -- need to register socket's fd with event loop
-+ poll:add_read(s_FD, on_sock_io)
-+ end
-+ blocked_state = state
-+ blocked_event = event
-+end
-+
-+-- sock state functions
-+function on_sock_send()
-+ N = N - 1
-+ if N == 0 then
-+ return poll:stop()
-+ end
-+ local sent, err = s:send("SELECT * FROM mytable", z_NOBLOCK)
-+ if not sent then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_send, z_POLLOUT)
-+ end
-+ -- yield back to event loop
-+ poll:add_work(on_sock_recv)
-+end
-+
-+function on_sock_recv()
-+ local data, err = s:recv(z_NOBLOCK)
-+ if not data then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_recv, z_POLLIN)
-+ end
-+ print(data)
-+ return on_sock_send()
-+end
-+
-+-- start processing of the socket.
-+poll:add_work(on_sock_send)
-+
-+-- start event loop
-+poll:start()
-+
-+s:close()
-+ctx:term()
-+
-diff --git a/examples/ev_subscriber.lua b/examples/ev_subscriber.lua
-deleted file mode 100644
-index 876a0ea..0000000
---- a/examples/ev_subscriber.lua
-+++ /dev/null
-@@ -1,92 +0,0 @@
---- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
----
---- 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.
--
--require("zmq")
--local ev = require'ev'
--local loop = ev.Loop.default
--
---- define a sub_worker class
--local sub_worker_mt = {}
--function sub_worker_mt:close(...)
-- self.s_io_idle:stop(self.loop)
-- self.s_io_read:stop(self.loop)
-- return self.socket:close(...)
--end
--function sub_worker_mt:bind(...)
-- return self.socket:bind(...)
--end
--function sub_worker_mt:connect(...)
-- return self.socket:connect(...)
--end
--function sub_worker_mt:sub(topic)
-- return self.socket:setopt(zmq.SUBSCRIBE, topic)
--end
--function sub_worker_mt:unsub(topic)
-- return self.socket:setopt(zmq.UNSUBSCRIBE, topic)
--end
--sub_worker_mt.__index = sub_worker_mt
--
--local function sub_worker(loop, ctx, msg_cb)
-- local s = ctx:socket(zmq.SUB)
-- local self = { loop = loop, socket = s, msg_cb = msg_cb }
-- setmetatable(self, sub_worker_mt)
-- -- create ev callbacks for recving data.
-- -- need idle watcher since ZeroMQ sockets are edge-triggered instead of level-triggered
-- local s_io_idle
-- local s_io_read
-- s_io_idle = ev.Idle.new(function()
-- local msg, err = s:recv(zmq.NOBLOCK)
-- if err == 'timeout' then
-- -- need to block on read IO
-- s_io_idle:stop(loop)
-- s_io_read:start(loop)
-- return
-- end
-- self:msg_cb(msg)
-- end)
-- s_io_idle:start(loop)
-- s_io_read = ev.IO.new(function()
-- s_io_idle:start(loop)
-- s_io_read:stop(loop)
-- end, s:getopt(zmq.FD), ev.READ)
-- self.s_io_idle = s_io_idle
-- self.s_io_read = s_io_read
-- return self
--end
--
--local ctx = zmq.init(1)
--
---- message handling function.
--local function handle_msg(worker, msg)
-- local msg_id = tonumber(msg)
-- if math.mod(msg_id, 10000) == 0 then print(worker.id, msg_id) end
--end
--
--local sub1 = sub_worker(loop, ctx, handle_msg)
--sub1.id = 'sub1'
--sub1:sub('')
--sub1:connect("tcp://localhost:5555")
--local sub2 = sub_worker(loop, ctx, handle_msg)
--sub2.id = 'sub2'
--sub2:sub('')
--sub2:connect("tcp://localhost:5555")
--
--loop:loop()
--
-diff --git a/examples/forward_poll.lua b/examples/forward_poll.lua
-new file mode 100644
-index 0000000..25e1e4f
---- /dev/null
-+++ b/examples/forward_poll.lua
-@@ -0,0 +1,39 @@
-+local zmq = require'zmq'
-+local poller = require"examples.poller"
-+local poll_zsock = require"examples.poll_zsock"
-+
-+local poll = poller.new()
-+poll_zsock.set_poller(poll)
-+
-+local c = zmq.init(1)
-+local xreq = poll_zsock(c:socket(zmq.XREQ))
-+xreq:bind('tcp://127.0.0.1:13333')
-+local xrep = poll_zsock(c:socket(zmq.XREP))
-+xrep:bind('tcp://127.0.0.1:13334')
-+
-+local max_recv = 10
-+
-+local function forward_io(src,dst)
-+ src.on_data = function()
-+ for i=1,max_recv do
-+ repeat
-+ local data, err = src:recv(zmq.NOBLOCK)
-+ if not data then
-+ if err == 'timeout' then
-+ return
-+ else
-+ error("socket recv error:" .. err)
-+ end
-+ end
-+ local more = src:getopt(zmq.RCVMORE) > 0
-+ dst:send(data,more and zmq.SNDMORE or 0)
-+ until not more
-+ end
-+ end
-+end
-+
-+forward_io(xrep,xreq)
-+forward_io(xreq,xrep)
-+
-+poll:start()
-+
-diff --git a/examples/poll_zsock.lua b/examples/poll_zsock.lua
-new file mode 100644
-index 0000000..5d2ca04
---- /dev/null
-+++ b/examples/poll_zsock.lua
-@@ -0,0 +1,177 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local zmq = require"zmq"
-+
-+local z_EVENTS = zmq.EVENTS
-+
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+
-+local poll
-+
-+local meths = {}
-+local zsock_mt = { __index=meths }
-+
-+local function zsock_check_events(self)
-+ if not self.check_enabled then
-+ -- enable 'on_work' callback to handle checking for socket events.
-+ self.check_enabled = true
-+ poll:add_work(self.on_work)
-+ end
-+end
-+
-+function meths:events()
-+ zsock_check_events(self)
-+ return self.sock:events()
-+end
-+
-+function meths:getopt(opt)
-+ if (opt == z_EVENTS) then
-+ zsock_check_events(self)
-+ end
-+ return self.sock:getopt(opt)
-+end
-+
-+function meths:setopt(opt,val)
-+ return self.sock:setopt(opt,val)
-+end
-+
-+function meths:sub(topic)
-+ return self.sock:sub(topic)
-+end
-+
-+function meths:unsub(topic)
-+ return self.sock:unsub(topic)
-+end
-+
-+function meths:identity(id)
-+ return self.sock:identity(id)
-+end
-+
-+function meths:bind(addr)
-+ return self.sock:bind(addr)
-+end
-+
-+function meths:connect(addr)
-+ return self.sock:connect(addr)
-+end
-+
-+function meths:close()
-+ return self.sock:close()
-+end
-+
-+function meths:send(msg, flags)
-+ zsock_check_events(self)
-+ local sent, err = self.sock:send(msg, flags)
-+ if not sent and err == 'timeout' then
-+ self.send_blocked = true
-+ end
-+ return sent, err
-+end
-+
-+function meths:send_msg(msg, flags)
-+ zsock_check_events(self)
-+ local sent, err = self.sock:send_msg(msg, flags)
-+ if not sent and err == 'timeout' then
-+ self.send_blocked = true
-+ end
-+ return sent, err
-+end
-+
-+function meths:recv(flags)
-+ zsock_check_events(self)
-+ local msg, err = self.sock:recv(flags)
-+ if not msg and err == 'timeout' then
-+ self.recv_blocked = true
-+ end
-+ return msg, err
-+end
-+
-+function meths:recv_msg(msg, flags)
-+ zsock_check_events(self)
-+ local stat, err = self.sock:recv_msg(msg, flags)
-+ if not stat and err == 'timeout' then
-+ self.recv_blocked = true
-+ end
-+ return stat, err
-+end
-+
-+local function nil_cb()
-+end
-+
-+local function wrap_zsock(sock, on_data, on_drain)
-+ local self = setmetatable({
-+ sock = sock,
-+ on_data = on_data or nil_cb,
-+ on_drain = on_drain or nil_cb,
-+ recv_blocked = false,
-+ send_blocked = false,
-+ check_enabled = false,
-+ }, zsock_mt)
-+
-+ local function on_work()
-+ self.check_enabled = false
-+ local events = sock:events()
-+ local read = false
-+ local write = false
-+ if events == z_POLLIN_OUT then
-+ read = true
-+ write = true
-+ elseif events == z_POLLIN then
-+ read = true
-+ elseif events == z_POLLOUT then
-+ write = true
-+ else
-+ return
-+ end
-+ if read then
-+ self.recv_blocked = false
-+ self:on_data(sock)
-+ -- there might be more messages to read.
-+ if not self.recv_blocked then
-+ zsock_check_events(self)
-+ end
-+ end
-+ if write and self.send_blocked then
-+ self:on_drain(sock)
-+ end
-+ end
-+ self.on_work = on_work
-+
-+ -- listen for read events to enable socket.
-+ poll:add_read(sock:fd(), function()
-+ on_work()
-+ end)
-+
-+ zsock_check_events(self)
-+ return self
-+end
-+
-+return setmetatable({
-+set_poller = function(poller)
-+ local old = poll
-+ poll = poller
-+ return old
-+end,
-+wrap_zsock = wrap_zsock,
-+}, { __call = function(tab, ...) return wrap_zsock(...) end})
-+
-diff --git a/examples/poller.lua b/examples/poller.lua
-new file mode 100644
-index 0000000..90bee0a
---- /dev/null
-+++ b/examples/poller.lua
-@@ -0,0 +1,45 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+-- safe require.
-+local require = require
-+local function safe_require(...)
-+ return pcall(require, ...)
-+end
-+
-+local mod_name = ...
-+
-+local backends = {
-+ "epoll",
-+ "ev",
-+}
-+
-+for i=1,#backends do
-+ local backend = backends[i]
-+ local name = mod_name .. '.' .. backend
-+ local status, mod = safe_require(name)
-+ if status then
-+ --print("Loaded backend:", name)
-+ return mod
-+ end
-+end
-+
-+error("Failed to load backend for: " .. mod_name)
-+
-diff --git a/examples/poller/epoll.lua b/examples/poller/epoll.lua
-new file mode 100644
-index 0000000..d79597c
---- /dev/null
-+++ b/examples/poller/epoll.lua
-@@ -0,0 +1,121 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local epoll = require"epoll"
-+local EPOLLIN = epoll.EPOLLIN
-+local EPOLLOUT = epoll.EPOLLOUT
-+
-+local poller_meths = {}
-+local poller_mt = {__index = poller_meths}
-+
-+local function poller_new()
-+ local reads = {}
-+ -- create closure for epoll io_event callback.
-+ local function do_io_event(fd, ev)
-+ local cb = reads[fd]
-+ return cb(fd, ev)
-+ end
-+
-+ return setmetatable({
-+ work_cur = {},
-+ work_last = {},
-+ reads = reads,
-+ io_events = 0,
-+ do_io_event = do_io_event,
-+ poller = epoll.new(),
-+ }, poller_mt)
-+end
-+
-+function poller_meths:add_work(task)
-+ -- add task to current work queue.
-+ self.work_cur[#self.work_cur + 1] = task
-+end
-+
-+function poller_meths:add_read(fd, cb)
-+ -- make sure read event hasn't been registered yet.
-+ if not self.reads[fd] then
-+ self.io_events = self.io_events + 1
-+ self.reads[fd] = cb
-+ return self.poller:add(fd, EPOLLIN, fd)
-+ else
-+ -- update read callback?
-+ self.reads[fd] = cb
-+ end
-+end
-+
-+function poller_meths:remove_read(fd)
-+ -- make sure there was a read event registered.
-+ if self.reads[fd] then
-+ self.io_events = self.io_events - 1
-+ self.reads[fd] = nil
-+ return self.poller:del(fd)
-+ end
-+end
-+
-+local function poller_do_work(self)
-+ local tasks = #self.work_cur
-+ -- check if there is any work
-+ if tasks > 0 then
-+ -- swap work queues.
-+ local last, cur = self.work_cur, self.work_last
-+ self.work_cur, self.work_last = cur, last
-+ for i=1,tasks do
-+ local task = last[i]
-+ last[i] = nil
-+ task()
-+ end
-+ -- return new work queue length.
-+ return #cur
-+ end
-+ return tasks
-+end
-+
-+function poller_meths:start()
-+ local do_io_event = self.do_io_event
-+ local poller = self.poller
-+ self.is_running = true
-+ while self.is_running do
-+ -- run work task
-+ local new_work = poller_do_work(self)
-+ -- wait == 0, if there is work to do, else wait == -1
-+ local wait = (new_work > 0) and 0 or -1
-+ -- poll for fd events, if there are events to poll for.
-+--print("poller:step()", new_work, self.io_events)
-+ if self.io_events > 0 then
-+ assert(poller:wait_callback(do_io_event, wait))
-+ else
-+ -- no io events to poll, do we still have work?
-+ if #self.work_cur == 0 then
-+ -- nothing to do, exit event loop
-+ self.is_running = false
-+ return
-+ end
-+ end
-+ end
-+end
-+
-+function poller_meths:stop()
-+ self.is_running = false
-+end
-+
-+-- module only exports a 'new' function.
-+return {
-+new = poller_new,
-+}
-diff --git a/examples/poller/ev.lua b/examples/poller/ev.lua
-new file mode 100644
-index 0000000..f8b1733
---- /dev/null
-+++ b/examples/poller/ev.lua
-@@ -0,0 +1,119 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local ev = require'ev'
-+local ev_READ = ev.READ
-+local ev_WRITE = ev.WRITE
-+local loop = ev.Loop.default
-+
-+assert(ev.Idle,"Need version > 1.3 of lua-ev that supports Idle watchers.")
-+
-+local poller_meths = {}
-+local poller_mt = {__index = poller_meths}
-+
-+local function poller_new()
-+ local self = {
-+ work_cur = {},
-+ work_last = {},
-+ io_events = 0,
-+ reads = {},
-+ idle_enabled = false,
-+ }
-+
-+ self.idle = ev.Idle.new(function()
-+ local tasks = #self.work_cur
-+ -- check if there is any work
-+ if tasks > 0 then
-+ -- swap work queues.
-+ local last, cur = self.work_cur, self.work_last
-+ self.work_cur, self.work_last = cur, last
-+ for i=1,tasks do
-+ local task = last[i]
-+ last[i] = nil
-+ task()
-+ end
-+ -- check if there is more work.
-+ if #cur > 0 then
-+ return -- don't disable idle watcher, when we have work.
-+ end
-+ end
-+--print("STOP IDLE:", #self.work_cur, #self.work_last)
-+ -- stop idle watcher, no work.
-+ self.idle_enabled = false
-+ self.idle:stop(loop)
-+ end)
-+ -- set priority to max, to make sure the work queue is processed on each loop.
-+ self.idle:priority(ev.MAXPRI)
-+
-+ return setmetatable(self, poller_mt)
-+end
-+
-+function poller_meths:add_work(task)
-+ local idx = #self.work_cur + 1
-+ -- add task to current work queue.
-+ self.work_cur[idx] = task
-+ -- make sure the idle watcher is enabled.
-+ if not self.idle_enabled then
-+ self.idle_enabled = true
-+ self.idle:start(loop)
-+ end
-+end
-+
-+function poller_meths:add_read(fd, cb)
-+ local io_read = self.reads[fd]
-+ -- make sure read event hasn't been registered yet.
-+ if not io_read then
-+ self.io_events = self.io_events + 1
-+ io_read = ev.IO.new(function()
-+ cb(fd)
-+ end, fd, ev_READ)
-+ self.reads[fd] = io_read
-+ io_read:start(loop)
-+ else
-+ -- update read callback?
-+ io_read:callback(cb)
-+ -- need to re-start watcher?
-+ if not io_read:is_active() then
-+ io_read:start(loop)
-+ end
-+ end
-+end
-+
-+function poller_meths:remove_read(fd)
-+ local io_read = self.reads[fd]
-+ -- make sure there was a read event registered.
-+ if io_read then
-+ self.io_events = self.io_events - 1
-+ io_read:stop(loop)
-+ end
-+end
-+
-+function poller_meths:start()
-+ return loop:loop()
-+end
-+
-+function poller_meths:stop()
-+ return loop:unloop()
-+end
-+
-+-- module only exports a 'new' function.
-+return {
-+new = poller_new,
-+}
-diff --git a/examples/publiser.lua b/examples/publiser.lua
-deleted file mode 100644
-index 12e240e..0000000
---- a/examples/publiser.lua
-+++ /dev/null
-@@ -1,32 +0,0 @@
---- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
----
---- 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.
--
--require("zmq")
--
--local ctx = zmq.init(1)
--local s = ctx:socket(zmq.PUB)
--
--s:bind("tcp://lo:5555")
--
--local msg_id = 1
--while true do
-- s:send(tostring(msg_id))
-- msg_id = msg_id + 1
--end
-diff --git a/examples/publisher.lua b/examples/publisher.lua
-new file mode 100644
-index 0000000..a5f943e
---- /dev/null
-+++ b/examples/publisher.lua
-@@ -0,0 +1,32 @@
-+-- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
-+--
-+-- 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.
-+
-+local zmq = require"zmq"
-+
-+local ctx = zmq.init()
-+local s = ctx:socket(zmq.PUB)
-+
-+s:bind("tcp://lo:5555")
-+
-+local msg_id = 1
-+while true do
-+ s:send(tostring(msg_id))
-+ msg_id = msg_id + 1
-+end
-diff --git a/examples/publisher_poll.lua b/examples/publisher_poll.lua
-new file mode 100644
-index 0000000..0cfbe79
---- /dev/null
-+++ b/examples/publisher_poll.lua
-@@ -0,0 +1,95 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local poller = require"examples.poller"
-+local poll = poller.new()
-+
-+local zmq = require"zmq"
-+local z_NOBLOCK = zmq.NOBLOCK
-+local z_EVENTS = zmq.EVENTS
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+
-+local ctx = zmq.init()
-+local s = ctx:socket(zmq.PUB)
-+local s_FD = s:getopt(zmq.FD)
-+
-+s:bind("tcp://lo:5555")
-+
-+-- current socket state
-+local blocked_state
-+local blocked_event
-+local on_sock_recv
-+local on_sock_send
-+
-+-- IO event callback when socket was blocked
-+local function on_sock_io()
-+ local events = s:getopt(z_EVENTS)
-+ local unblocked = false
-+ if events == blocked_event then
-+ -- got the event the socket was blocked on.
-+ unblocked = true
-+ elseif events == z_POLLIN_OUT then
-+ -- got both in & out events
-+ unblocked = true
-+ end
-+ if unblocked then
-+ -- got the event we are blocked on resume.
-+ blocked_event = nil
-+ blocked_state()
-+ -- check if blocked event was processed.
-+ if not blocked_event then
-+ poll:remove_read(s_FD)
-+ end
-+ end
-+end
-+local function sock_blocked(state, event)
-+ if not blocked_event then
-+ -- need to register socket's fd with event loop
-+ poll:add_read(s_FD, on_sock_io)
-+ end
-+ blocked_state = state
-+ blocked_event = event
-+end
-+
-+-- sock state functions
-+local msg_id = 1
-+function on_sock_send()
-+ local sent, err = s:send(tostring(msg_id), z_NOBLOCK)
-+ if not sent then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_send, z_POLLOUT)
-+ end
-+ -- message sent, inc. id
-+ msg_id = msg_id + 1
-+ -- yield back to event loop
-+ poll:add_work(on_sock_send)
-+end
-+
-+-- start processing of the socket.
-+poll:add_work(on_sock_send)
-+
-+-- start event loop
-+poll:start()
-+
-+s:close()
-+ctx:term()
-+
-diff --git a/examples/server.lua b/examples/server.lua
-index 57bb278..3423c4e 100644
---- a/examples/server.lua
-+++ b/examples/server.lua
-@@ -18,14 +18,14 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
--require("zmq")
-+local zmq = require"zmq"
-
--local ctx = zmq.init(1)
-+local ctx = zmq.init()
- local s = ctx:socket(zmq.REP)
-
- s:bind("tcp://lo:5555")
-
- while true do
-- print(string.format("Received query: '%s'", s:recv()))
-- s:send("OK")
-+ print(string.format("Received query: '%s'", s:recv()))
-+ s:send("OK")
- end
-diff --git a/examples/server_multipart.lua b/examples/server_multipart.lua
-index 663c3f7..c26e3e0 100644
---- a/examples/server_multipart.lua
-+++ b/examples/server_multipart.lua
-@@ -18,18 +18,18 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
--require("zmq")
-+local zmq = require"zmq"
-
--local ctx = zmq.init(1)
-+local ctx = zmq.init()
- local s = ctx:socket(zmq.REP)
-
- s:bind("tcp://lo:5555")
-
- while true do
-- local query = s:recv()
-- while s:getopt(zmq.RCVMORE) == 1 do
-- query = query .. s:recv()
-- end
-- print(string.format("Received query: '%s'", query))
-- s:send("OK")
-+ local query = s:recv()
-+ while s:getopt(zmq.RCVMORE) == 1 do
-+ query = query .. s:recv()
-+ end
-+ print(string.format("Received query: '%s'", query))
-+ s:send("OK")
- end
-diff --git a/examples/server_poll.lua b/examples/server_poll.lua
-new file mode 100644
-index 0000000..42c8862
---- /dev/null
-+++ b/examples/server_poll.lua
-@@ -0,0 +1,102 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local poller = require"examples.poller"
-+local poll = poller.new()
-+
-+local zmq = require"zmq"
-+local z_NOBLOCK = zmq.NOBLOCK
-+local z_EVENTS = zmq.EVENTS
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+
-+local ctx = zmq.init()
-+local s = ctx:socket(zmq.REP)
-+local s_FD = s:getopt(zmq.FD)
-+
-+s:bind("tcp://lo:5555")
-+
-+-- current socket state
-+local blocked_state
-+local blocked_event
-+local on_sock_recv
-+local on_sock_send
-+
-+-- IO event callback when socket was blocked
-+local function on_sock_io()
-+ local events = s:getopt(z_EVENTS)
-+ local unblocked = false
-+ if events == blocked_event then
-+ -- got the event the socket was blocked on.
-+ unblocked = true
-+ elseif events == z_POLLIN_OUT then
-+ -- got both in & out events
-+ unblocked = true
-+ end
-+ if unblocked then
-+ -- got the event we are blocked on resume.
-+ blocked_event = nil
-+ blocked_state()
-+ -- check if blocked event was processed.
-+ if not blocked_event then
-+ poll:remove_read(s_FD)
-+ end
-+ end
-+end
-+local function sock_blocked(state, event)
-+ if not blocked_event then
-+ -- need to register socket's fd with event loop
-+ poll:add_read(s_FD, on_sock_io)
-+ end
-+ blocked_state = state
-+ blocked_event = event
-+end
-+
-+-- sock state functions
-+function on_sock_recv()
-+ local data, err = s:recv(z_NOBLOCK)
-+ if not data then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_recv, z_POLLIN)
-+ end
-+ print(string.format("Received query: '%s'", data))
-+ return on_sock_send()
-+end
-+
-+function on_sock_send()
-+ local sent, err = s:send("OK", z_NOBLOCK)
-+ if not sent then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_send, z_POLLOUT)
-+ end
-+ -- yield back to event loop
-+ poll:add_work(on_sock_recv)
-+end
-+
-+-- start processing of the socket.
-+poll:add_work(on_sock_recv)
-+
-+-- start event loop
-+poll:start()
-+
-+s:close()
-+ctx:term()
-+
-diff --git a/examples/subscriber.lua b/examples/subscriber.lua
-index 370b7dc..41434c7 100644
---- a/examples/subscriber.lua
-+++ b/examples/subscriber.lua
-@@ -18,14 +18,14 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
--require("zmq")
-+local zmq = require"zmq"
-
--local ctx = zmq.init(1)
-+local ctx = zmq.init()
- local s = ctx:socket(zmq.SUB)
- s:setopt(zmq.SUBSCRIBE, "")
- s:connect("tcp://localhost:5555")
- while true do
-- local msg = s:recv()
-- local msg_id = tonumber(msg)
-- if math.mod(msg_id, 10000) == 0 then print(msg_id) end
-+ local msg = s:recv()
-+ local msg_id = tonumber(msg)
-+ if math.mod(msg_id, 10000) == 0 then print(msg_id) end
- end
-diff --git a/examples/subscriber_ev.lua b/examples/subscriber_ev.lua
-new file mode 100644
-index 0000000..ae8506c
---- /dev/null
-+++ b/examples/subscriber_ev.lua
-@@ -0,0 +1,113 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local zmq = require"zmq"
-+local z_NOBLOCK = zmq.NOBLOCK
-+local z_EVENTS = zmq.EVENTS
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+local ev = require'ev'
-+local loop = ev.Loop.default
-+
-+-- define a sub_worker class
-+local sub_worker_mt = {}
-+function sub_worker_mt:close(...)
-+ self.s_io_idle:stop(self.loop)
-+ self.s_io_read:stop(self.loop)
-+ return self.socket:close(...)
-+end
-+function sub_worker_mt:bind(...)
-+ return self.socket:bind(...)
-+end
-+function sub_worker_mt:connect(...)
-+ return self.socket:connect(...)
-+end
-+function sub_worker_mt:sub(topic)
-+ return self.socket:setopt(zmq.SUBSCRIBE, topic)
-+end
-+function sub_worker_mt:unsub(topic)
-+ return self.socket:setopt(zmq.UNSUBSCRIBE, topic)
-+end
-+sub_worker_mt.__index = sub_worker_mt
-+
-+local function sub_worker(loop, ctx, msg_cb)
-+ local s = ctx:socket(zmq.SUB)
-+ local self = { loop = loop, socket = s, msg_cb = msg_cb }
-+ setmetatable(self, sub_worker_mt)
-+ -- create ev callbacks for recving data.
-+ -- need idle watcher since ZeroMQ sockets are edge-triggered instead of level-triggered
-+ local s_io_idle
-+ local s_io_read
-+ local max_recvs = 10
-+ local function s_recv(recv_cnt)
-+ local msg, err = s:recv(z_NOBLOCK)
-+ if err == 'timeout' then
-+ -- need to block on read IO
-+ return false
-+ end
-+ self:msg_cb(msg)
-+ if recv_cnt > 1 then
-+ return s_recv(recv_cnt - 1)
-+ end
-+ return true
-+ end
-+ s_io_idle = ev.Idle.new(function()
-+ if not s_recv(max_recvs) then
-+ -- need to block on read IO
-+ s_io_idle:stop(loop)
-+ s_io_read:start(loop)
-+ end
-+ end)
-+ s_io_idle:start(loop)
-+ s_io_read = ev.IO.new(function()
-+ local events = s:getopt(z_EVENTS)
-+ if events == z_POLLIN or events == z_POLLIN_OUT then
-+ if s_recv(max_recvs) then
-+ -- read IO is not block, enable idle watcher to handle reads.
-+ s_io_idle:start(loop)
-+ s_io_read:stop(loop)
-+ end
-+ end
-+ end, s:getopt(zmq.FD), ev.READ)
-+ self.s_io_idle = s_io_idle
-+ self.s_io_read = s_io_read
-+ return self
-+end
-+
-+local ctx = zmq.init()
-+
-+-- message handling function.
-+local function handle_msg(worker, msg)
-+ local msg_id = tonumber(msg)
-+ if math.mod(msg_id, 10000) == 0 then print(worker.id, msg_id) end
-+end
-+
-+local sub1 = sub_worker(loop, ctx, handle_msg)
-+sub1.id = 'sub1'
-+sub1:sub('')
-+sub1:connect("tcp://localhost:5555")
-+local sub2 = sub_worker(loop, ctx, handle_msg)
-+sub2.id = 'sub2'
-+sub2:sub('')
-+sub2:connect("tcp://localhost:5555")
-+
-+loop:loop()
-+
-diff --git a/examples/subscriber_poll.lua b/examples/subscriber_poll.lua
-new file mode 100644
-index 0000000..1be24b2
---- /dev/null
-+++ b/examples/subscriber_poll.lua
-@@ -0,0 +1,96 @@
-+-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
-+--
-+-- 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.
-+
-+local poller = require"examples.poller"
-+local poll = poller.new()
-+
-+local zmq = require"zmq"
-+local z_NOBLOCK = zmq.NOBLOCK
-+local z_EVENTS = zmq.EVENTS
-+local z_POLLIN = zmq.POLLIN
-+local z_POLLOUT = zmq.POLLOUT
-+local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
-+
-+local N=tonumber(arg[1] or 100)
-+
-+local ctx = zmq.init()
-+local s = ctx:socket(zmq.SUB)
-+local s_FD = s:getopt(zmq.FD)
-+
-+s:setopt(zmq.SUBSCRIBE, "")
-+s:connect("tcp://localhost:5555")
-+
-+-- current socket state
-+local blocked_state
-+local blocked_event
-+local on_sock_recv
-+local on_sock_send
-+
-+-- IO event callback when socket was blocked
-+local function on_sock_io()
-+ local events = s:getopt(z_EVENTS)
-+ local unblocked = false
-+ if events == blocked_event then
-+ -- got the event the socket was blocked on.
-+ unblocked = true
-+ elseif events == z_POLLIN_OUT then
-+ -- got both in & out events
-+ unblocked = true
-+ end
-+ if unblocked then
-+ -- got the event we are blocked on resume.
-+ blocked_event = nil
-+ blocked_state()
-+ -- check if blocked event was processed.
-+ if not blocked_event then
-+ poll:remove_read(s_FD)
-+ end
-+ end
-+end
-+local function sock_blocked(state, event)
-+ if not blocked_event then
-+ -- need to register socket's fd with event loop
-+ poll:add_read(s_FD, on_sock_io)
-+ end
-+ blocked_state = state
-+ blocked_event = event
-+end
-+
-+-- sock state functions
-+function on_sock_recv()
-+ local data, err = s:recv(z_NOBLOCK)
-+ if not data then
-+ assert(err == 'timeout', "Bad error on zmq socket.")
-+ return sock_blocked(on_sock_recv, z_POLLIN)
-+ end
-+ local msg_id = tonumber(data)
-+ if (msg_id % 10000) == 0 then print(data) end
-+ return on_sock_recv()
-+end
-+
-+-- start processing of the socket.
-+poll:add_work(on_sock_recv)
-+
-+-- start event loop
-+poll:start()
-+
-+s:close()
-+ctx:term()
-+
-diff --git a/perf/local_lat.lua b/perf/local_lat.lua
-index d6a4ec1..027c583 100644
---- a/perf/local_lat.lua
-+++ b/perf/local_lat.lua
-@@ -35,11 +35,26 @@ s:bind(bind_to)
-
- local msg = zmq.zmq_msg_t()
-
-+local timer
-+
- for i = 1, roundtrip_count do
- assert(s:recv_msg(msg))
-+ if not timer then
-+ timer = zmq.stopwatch_start()
-+ end
- assert(msg:size() == message_size, "Invalid message size")
- assert(s:send_msg(msg))
- end
-
-+local elapsed = timer:stop()
-+
- s:close()
- ctx:term()
-+
-+local latency = elapsed / roundtrip_count / 2
-+
-+print(string.format("mean latency: %.3f [us]", latency))
-+local secs = elapsed / (1000 * 1000)
-+print(string.format("elapsed = %f", secs))
-+print(string.format("msg/sec = %f", roundtrip_count / secs))
-+
-diff --git a/perf/local_thr_poll.lua b/perf/local_thr_poll.lua
-new file mode 100644
-index 0000000..bfe0d33
---- /dev/null
-+++ b/perf/local_thr_poll.lua
-@@ -0,0 +1,77 @@
-+-- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
-+--
-+-- 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.
-+
-+if not arg[3] then
-+ print("usage: lua local_thr.lua <bind-to> <message-size> <message-count>")
-+ os.exit()
-+end
-+
-+local bind_to = arg[1]
-+local message_size = tonumber(arg[2])
-+local message_count = tonumber(arg[3])
-+
-+local zmq = require"zmq"
-+local z_poller = require"zmq.poller"
-+local z_NOBLOCK = zmq.NOBLOCK
-+
-+local poller = z_poller(64)
-+
-+local ctx = zmq.init(1)
-+local s = ctx:socket(zmq.SUB)
-+s:setopt(zmq.SUBSCRIBE, "");
-+s:bind(bind_to)
-+
-+print(string.format("message size: %i [B]", message_size))
-+print(string.format("message count: %i", message_count))
-+
-+local msg
-+msg = zmq.zmq_msg_t()
-+
-+local cnt = 0
-+
-+poller:add(s, zmq.POLLIN, function(sock)
-+ while s:recv_msg(msg, z_NOBLOCK) do
-+ --assert(msg:size() == message_size, "Invalid message size")
-+ cnt = cnt + 1
-+ if cnt == message_count then
-+ poller:stop()
-+ end
-+ end
-+end)
-+
-+-- wait for first message
-+assert(s:recv_msg(msg))
-+cnt = 1
-+
-+local timer = zmq.stopwatch_start()
-+poller:start()
-+local elapsed = timer:stop()
-+
-+s:close()
-+ctx:term()
-+
-+if elapsed == 0 then elapsed = 1 end
-+
-+local throughput = message_count / (elapsed / 1000000)
-+local megabits = throughput * message_size * 8 / 1000000
-+
-+print(string.format("mean throughput: %i [msg/s]", throughput))
-+print(string.format("mean throughput: %.3f [Mb/s]", megabits))
-+
-diff --git a/perf/local_thr_push_pull.lua b/perf/local_thr_push_pull.lua
-new file mode 100644
-index 0000000..9b2dee2
---- /dev/null
-+++ b/perf/local_thr_push_pull.lua
-@@ -0,0 +1,62 @@
-+-- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
-+--
-+-- 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.
-+
-+if not arg[3] then
-+ print("usage: lua local_thr.lua <bind-to> <message-size> <message-count>")
-+ os.exit()
-+end
-+
-+local bind_to = arg[1]
-+local message_size = tonumber(arg[2])
-+local message_count = tonumber(arg[3])
-+
-+local zmq = require"zmq"
-+
-+local ctx = zmq.init(1)
-+local s = ctx:socket(zmq.PULL)
-+s:bind(bind_to)
-+
-+print(string.format("message size: %i [B]", message_size))
-+print(string.format("message count: %i", message_count))
-+
-+local msg
-+msg = zmq.zmq_msg_t()
-+assert(s:recv_msg(msg))
-+
-+local timer = zmq.stopwatch_start()
-+
-+for i = 1, message_count - 1 do
-+ assert(s:recv_msg(msg))
-+ assert(msg:size() == message_size, "Invalid message size")
-+end
-+
-+local elapsed = timer:stop()
-+
-+s:close()
-+ctx:term()
-+
-+if elapsed == 0 then elapsed = 1 end
-+
-+local throughput = message_count / (elapsed / 1000000)
-+local megabits = throughput * message_size * 8 / 1000000
-+
-+print(string.format("mean throughput: %i [msg/s]", throughput))
-+print(string.format("mean throughput: %.3f [Mb/s]", megabits))
-+
-diff --git a/perf/remote_lat.lua b/perf/remote_lat.lua
-index 4376f60..ebcc680 100644
---- a/perf/remote_lat.lua
-+++ b/perf/remote_lat.lua
-@@ -54,3 +54,4 @@ local latency = elapsed / roundtrip_count / 2
- print(string.format("message size: %i [B]", message_size))
- print(string.format("roundtrip count: %i", roundtrip_count))
- print(string.format("mean latency: %.3f [us]", latency))
-+
-diff --git a/perf/remote_thr.lua b/perf/remote_thr.lua
-index 967e08b..5890508 100644
---- a/perf/remote_thr.lua
-+++ b/perf/remote_thr.lua
-@@ -31,8 +31,12 @@ local zmq = require"zmq"
-
- local ctx = zmq.init(1)
- local s = ctx:socket(zmq.PUB)
-+-- for ZeroMQ 3.x need to change HWM option.
-+s:set_hwm(0)
- s:connect(connect_to)
-
-+zmq.sleep(1)
-+
- local data = ("0"):rep(message_size)
- local msg_data = zmq.zmq_msg_t.init_data(data)
- local msg = zmq.zmq_msg_t.init()
-@@ -42,7 +46,6 @@ for i = 1, message_count do
- assert(s:send_msg(msg))
- end
-
----os.execute("sleep " .. 10)
--
- s:close()
- ctx:term()
-+
-diff --git a/perf/remote_thr_push_pull.lua b/perf/remote_thr_push_pull.lua
-new file mode 100644
-index 0000000..11be905
---- /dev/null
-+++ b/perf/remote_thr_push_pull.lua
-@@ -0,0 +1,49 @@
-+-- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
-+--
-+-- 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.
-+
-+if not arg[3] then
-+ print("usage: lua remote_thr.lua <connect-to> <message-size> <message-count>")
-+ os.exit()
-+end
-+
-+local connect_to = arg[1]
-+local message_size = tonumber(arg[2])
-+local message_count = tonumber(arg[3])
-+
-+local zmq = require"zmq"
-+
-+local ctx = zmq.init(1)
-+local s = ctx:socket(zmq.PUSH)
-+s:connect(connect_to)
-+
-+zmq.sleep(1)
-+
-+local data = ("0"):rep(message_size)
-+local msg_data = zmq.zmq_msg_t.init_data(data)
-+local msg = zmq.zmq_msg_t.init()
-+
-+for i = 1, message_count do
-+ msg:copy(msg_data)
-+ assert(s:send_msg(msg))
-+end
-+
-+s:close()
-+ctx:term()
-+
-diff --git a/perf/thread_lat.lua b/perf/thread_lat.lua
-index 93ed691..f781e55 100644
---- a/perf/thread_lat.lua
-+++ b/perf/thread_lat.lua
-@@ -64,6 +64,8 @@ local msg = zmq.zmq_msg_t.init_size(message_size)
- print(string.format("message size: %i [B]", message_size))
- print(string.format("roundtrip count: %i", roundtrip_count))
-
-+zmq.sleep(2) -- wait for child thread to connect.
-+
- local timer = zmq.stopwatch_start()
-
- for i = 1, roundtrip_count do
-@@ -81,4 +83,7 @@ ctx:term()
- local latency = elapsed / roundtrip_count / 2
-
- print(string.format("mean latency: %.3f [us]", latency))
-+local secs = elapsed / (1000 * 1000)
-+print(string.format("elapsed = %f", secs))
-+print(string.format("msg/sec = %f", roundtrip_count / secs))
-
-diff --git a/perf/thread_push_pull.lua b/perf/thread_push_pull.lua
-index f69ff48..b3d96cb 100644
---- a/perf/thread_push_pull.lua
-+++ b/perf/thread_push_pull.lua
-@@ -42,12 +42,13 @@ local child_code = [[
- s:connect(connect_to)
-
- local data = ("0"):rep(message_size)
-- local msg = zmq.zmq_msg_t.init_size(message_size)
-+ local msg_data = zmq.zmq_msg_t.init_data(data)
-+ local msg = zmq.zmq_msg_t.init()
-
- local timer = zmq.stopwatch_start()
-
- for i = 1, message_count do
-- msg:set_data(data)
-+ msg:copy(msg_data)
- assert(s:send_msg(msg))
- end
-
-diff --git a/perf/thread_thr.lua b/perf/thread_thr.lua
-index 7b9183a..d3958e8 100644
---- a/perf/thread_thr.lua
-+++ b/perf/thread_thr.lua
-@@ -38,6 +38,8 @@ local child_code = [[
-
- local ctx = zthreads.get_parent_ctx()
- local s = ctx:socket(zmq.PUB)
-+ -- for ZeroMQ 3.x need to change HWM option.
-+ s:set_hwm(0)
- s:connect(connect_to)
-
- local data = ("0"):rep(message_size)
-diff --git a/rockspecs/lua-zmq-scm-1.rockspec b/rockspecs/lua-zmq-scm-1.rockspec
-index 10737b7..b3cd3c6 100644
---- a/rockspecs/lua-zmq-scm-1.rockspec
-+++ b/rockspecs/lua-zmq-scm-1.rockspec
-@@ -12,12 +12,28 @@ dependencies = {
- "lua >= 5.1",
- }
- external_dependencies = {
-+ platforms = {
-+ windows = {
-+ ZEROMQ = {
-+ library = "libzmq",
-+ }
-+ },
-+ },
- ZEROMQ = {
- header = "zmq.h",
- library = "zmq",
- }
- }
- build = {
-+ platforms = {
-+ windows = {
-+ modules = {
-+ zmq = {
-+ libraries = {"libzmq"},
-+ }
-+ }
-+ },
-+ },
- type = "builtin",
- modules = {
- zmq = {
-diff --git a/rockspecs/lua-zmq-wireshark-scm-0.rockspec b/rockspecs/lua-zmq-wireshark-scm-0.rockspec
-new file mode 100644
-index 0000000..5e3e0e1
---- /dev/null
-+++ b/rockspecs/lua-zmq-wireshark-scm-0.rockspec
-@@ -0,0 +1,22 @@
-+package = "lua-zmq-wireshark"
-+version = "scm-0"
-+source = {
-+ url = "git://github.com/Neopallium/lua-zmq.git",
-+}
-+description = {
-+ summary = "Lua Wireshark dissector for the ZeroMQ protocol.",
-+ homepage = "http://github.com/Neopallium/lua-zmq",
-+ -- Wireshark requires dissectors to be licensed under the GPL.
-+ license = "GPL",
-+}
-+dependencies = {}
-+build = {
-+ type = "none",
-+ install = {
-+ lua = {
-+ ['zmq.ws.dissector'] = "ws/dissector.lua",
-+ ['zmq.ws.tap'] = "ws/tap.lua",
-+ ['zmq.ws.stats_tap'] = "ws/stats_tap.lua",
-+ },
-+ },
-+}
-diff --git a/src/ctx.nobj.lua b/src/ctx.nobj.lua
-index adc0c42..246b653 100644
---- a/src/ctx.nobj.lua
-+++ b/src/ctx.nobj.lua
-@@ -19,6 +19,7 @@
- -- THE SOFTWARE.
-
- object "ZMQ_Ctx" {
-+ sys_include"string.h",
- error_on_null = "get_zmq_strerror()",
- c_source [[
- typedef struct ZMQ_Ctx ZMQ_Ctx;
-diff --git a/src/error.nobj.lua b/src/error.nobj.lua
-index 4e353f3..b5559c7 100644
---- a/src/error.nobj.lua
-+++ b/src/error.nobj.lua
-@@ -18,26 +18,295 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
-+-- E* error values.
-+meta_object "ZErrors" {
-+ export_definitions {
-+ -- Native 0MQ error codes.
-+ "EFSM",
-+ "ENOCOMPATPROTO",
-+ "ETERM",
-+ "EMTHREAD",
-+
-+ "EPERM", -- Operation not permitted
-+ "ENOENT", -- No such file or directory
-+ "ESRCH", -- No such process
-+ "EINTR", -- Interrupted system call
-+ "EIO", -- I/O error
-+ "ENXIO", -- No such device or address
-+ "E2BIG", -- Argument list too long
-+ "ENOEXEC", -- Exec format error
-+ "EBADF", -- Bad file number
-+ "ECHILD", -- No child processes
-+ "EAGAIN", -- Try again
-+ "ENOMEM", -- Out of memory
-+ "EACCES", -- Permission denied
-+ "EFAULT", -- Bad address
-+ "ENOTBLK", -- Block device required
-+ "EBUSY", -- Device or resource busy
-+ "EEXIST", -- File exists
-+ "EXDEV", -- Cross-device link
-+ "ENODEV", -- No such device
-+ "ENOTDIR", -- Not a directory
-+ "EISDIR", -- Is a directory
-+ "EINVAL", -- Invalid argument
-+ "ENFILE", -- File table overflow
-+ "EMFILE", -- Too many open files
-+ "ENOTTY", -- Not a typewriter
-+ "ETXTBSY", -- Text file busy
-+ "EFBIG", -- File too large
-+ "ENOSPC", -- No space left on device
-+ "ESPIPE", -- Illegal seek
-+ "EROFS", -- Read-only file system
-+ "EMLINK", -- Too many links
-+ "EPIPE", -- Broken pipe
-+ "EDOM", -- Math argument out of domain of func
-+ "ERANGE", -- Math result not representable
-+
-+ "EDEADLK", -- Resource deadlock would occur
-+ "EDEADLOCK", -- EDEADLK
-+ "ENAMETOOLONG", -- File name too long
-+ "ENOLCK", -- No record locks available
-+ "ENOSYS", -- Function not implemented
-+ "ENOTEMPTY", -- Directory not empty
-+ "ELOOP", -- Too many symbolic links encountered
-+ "EWOULDBLOCK", -- Operation would block
-+ "ENOMSG", -- No message of desired type
-+ "EIDRM", -- Identifier removed
-+ "ECHRNG", -- Channel number out of range
-+ "EL2NSYNC", -- Level 2 not synchronized
-+ "EL3HLT", -- Level 3 halted
-+ "EL3RST", -- Level 3 reset
-+ "ELNRNG", -- Link number out of range
-+ "EUNATCH", -- Protocol driver not attached
-+ "ENOCSI", -- No CSI structure available
-+ "EL2HLT", -- Level 2 halted
-+ "EBADE", -- Invalid exchange
-+ "EBADR", -- Invalid request descriptor
-+ "EXFULL", -- Exchange full
-+ "ENOANO", -- No anode
-+ "EBADRQC", -- Invalid request code
-+ "EBADSLT", -- Invalid slot
-+
-+ "EBFONT", -- Bad font file format
-+ "ENOSTR", -- Device not a stream
-+ "ENODATA", -- No data available
-+ "ETIME", -- Timer expired
-+ "ENOSR", -- Out of streams resources
-+ "ENONET", -- Machine is not on the network
-+ "ENOPKG", -- Package not installed
-+ "EREMOTE", -- Object is remote
-+ "ENOLINK", -- Link has been severed
-+ "EADV", -- Advertise error
-+ "ESRMNT", -- Srmount error
-+ "ECOMM", -- Communication error on send
-+ "EPROTO", -- Protocol error
-+ "EMULTIHOP", -- Multihop attempted
-+ "EDOTDOT", -- RFS specific error
-+ "EBADMSG", -- Not a data message
-+ "EOVERFLOW", -- Value too large for defined data type
-+ "ENOTUNIQ", -- Name not unique on network
-+ "EBADFD", -- File descriptor in bad state
-+ "EREMCHG", -- Remote address changed
-+ "ELIBACC", -- Can not access a needed shared library
-+ "ELIBBAD", -- Accessing a corrupted shared library
-+ "ELIBSCN", -- .lib section in a.out corrupted
-+ "ELIBMAX", -- Attempting to link in too many shared libraries
-+ "ELIBEXEC", -- Cannot exec a shared library directly
-+ "EILSEQ", -- Illegal byte sequence
-+ "ERESTART", -- Interrupted system call should be restarted
-+ "ESTRPIPE", -- Streams pipe error
-+ "EUSERS", -- Too many users
-+ "ENOTSOCK", -- Socket operation on non-socket
-+ "EDESTADDRREQ", -- Destination address required
-+ "EMSGSIZE", -- Message too long
-+ "EPROTOTYPE", -- Protocol wrong type for socket
-+ "ENOPROTOOPT", -- Protocol not available
-+ "EPROTONOSUPPORT", -- Protocol not supported
-+ "ESOCKTNOSUPPORT", -- Socket type not supported
-+ "EOPNOTSUPP", -- Operation not supported on transport endpoint
-+ "EPFNOSUPPORT", -- Protocol family not supported
-+ "EAFNOSUPPORT", -- Address family not supported by protocol
-+ "EADDRINUSE", -- Address already in use
-+ "EADDRNOTAVAIL", -- Cannot assign requested address
-+ "ENETDOWN", -- Network is down
-+ "ENETUNREACH", -- Network is unreachable
-+ "ENETRESET", -- Network dropped connection because of reset
-+ "ECONNABORTED", -- Software caused connection abort
-+ "ECONNRESET", -- Connection reset by peer
-+ "ENOBUFS", -- No buffer space available
-+ "EISCONN", -- Transport endpoint is already connected
-+ "ENOTCONN", -- Transport endpoint is not connected
-+ "ESHUTDOWN", -- Cannot send after transport endpoint shutdown
-+ "ETOOMANYREFS", -- Too many references: cannot splice
-+ "ETIMEDOUT", -- Connection timed out
-+ "ECONNREFUSED", -- Connection refused
-+ "EHOSTDOWN", -- Host is down
-+ "EHOSTUNREACH", -- No route to host
-+ "EALREADY", -- Operation already in progress
-+ "EINPROGRESS", -- Operation now in progress
-+ "ESTALE", -- Stale NFS file handle
-+ "EUCLEAN", -- Structure needs cleaning
-+ "ENOTNAM", -- Not a XENIX named type file
-+ "ENAVAIL", -- No XENIX semaphores available
-+ "EISNAM", -- Is a named type file
-+ "EREMOTEIO", -- Remote I/O error
-+ "EDQUOT", -- Quota exceeded
-+
-+ "ENOMEDIUM", -- No medium found
-+ "EMEDIUMTYPE", -- Wrong medium type
-+ "ECANCELED", -- Operation Canceled
-+ "ENOKEY", -- Required key not available
-+ "EKEYEXPIRED", -- Key has expired
-+ "EKEYREVOKED", -- Key has been revoked
-+ "EKEYREJECTED", -- Key was rejected by service
-+
-+ -- for robust mutexes
-+ "EOWNERDEAD", -- Owner died
-+ "ENOTRECOVERABLE", -- State not recoverable
-+
-+ "ERFKILL", -- Operation not possible due to RF-kill
-+ },
-+
-+ method "description" {
-+ var_in{ "<any>", "err" },
-+ var_out{ "const char *", "msg" },
-+ c_source "pre" [[
-+ int err_type;
-+ int err_num = -1;
-+]],
-+ c_source[[
-+ err_type = lua_type(L, ${err::idx});
-+ if(err_type == LUA_TSTRING) {
-+ lua_pushvalue(L, ${err::idx});
-+ lua_rawget(L, ${this::idx});
-+ if(lua_isnumber(L, -1)) {
-+ err_num = lua_tointeger(L, -1);
-+ }
-+ lua_pop(L, 1);
-+ } else if(err_type == LUA_TNUMBER) {
-+ err_num = lua_tointeger(L, ${err::idx});
-+ } else {
-+ return luaL_argerror(L, ${err::idx}, "expected string/number");
-+ }
-+ if(err_num < 0) {
-+ lua_pushnil(L);
-+ lua_pushliteral(L, "UNKNOWN ERROR");
-+ return 2;
-+ }
-+ ${msg} = strerror(err_num);
-+]],
-+ },
-+
-+ method "__index" {
-+ var_in{ "int", "err" },
-+ var_out{ "const char *", "msg" },
-+ c_source[[
-+ switch(${err}) {
-+ case EAGAIN:
-+ ${msg} = "timeout";
-+ break;
-+ case EINTR:
-+ ${msg} = "interrupted";
-+ break;
-+#if defined(ETERM)
-+ case ETERM:
-+ ${msg} = "closed";
-+ break;
-+#endif
-+ default:
-+ ${msg} = zmq_strerror(${err});
-+ break;
-+ }
-+ lua_pushvalue(L, ${err::idx});
-+ lua_pushstring(L, ${msg});
-+ lua_rawset(L, ${this::idx});
-+]],
-+ },
-+}
-+
-+ffi_cdef[[
-+int zmq_errno (void);
-+]]
-+
-+ffi_source "ffi_src" [[
-+-- get ZErrors table to map errno to error name.
-+local ZError_names = _M.ZErrors
-+
-+local function get_zmq_strerror()
-+ return ZError_names[C.zmq_errno()]
-+end
-+]]
-+
-+c_source "extra_code" [[
-+static char *zmq_ZErrors_key = "zmq_ZErrors_key";
-+/*
-+ * This wrapper function is to make the EAGAIN/ETERM error messages more like
-+ * what is returned by LuaSocket.
-+ */
-+static const char *get_zmq_strerror() {
-+ int err = zmq_errno();
-+ switch(err) {
-+ case EAGAIN:
-+ return "timeout";
-+ break;
-+ case EINTR:
-+ return "interrupted";
-+ break;
-+#if defined(ETERM)
-+ case ETERM:
-+ return "closed";
-+ break;
-+#endif
-+ default:
-+ break;
-+ }
-+ return zmq_strerror(err);
-+}
-+
-+]]
-+
-+c_source "module_init_src" [[
-+ /* Cache reference to zmq.ZErrors table for errno->string convertion. */
-+ lua_pushlightuserdata(L, zmq_ZErrors_key);
-+ lua_getfield(L, -2, "ZErrors");
-+ lua_rawset(L, LUA_REGISTRYINDEX);
-+]]
-+
- -- Convert ZMQ Error codes into strings.
- --
- -- This is an error code wrapper object, it converts C-style 'int' return error code
- -- into Lua-style 'nil, "Error message"' return values.
- --
- error_code "ZMQ_Error" "int" {
-- ffi_cdef[[
--typedef int ZMQ_Error;
--]],
-+ ffi_type = "int",
- is_error_check = function(rec) return "(-1 == ${" .. rec.name .. "})" end,
- ffi_is_error_check = function(rec) return "(-1 == ${" .. rec.name .. "})" end,
- default = "0",
- c_source [[
-+ int num;
- if(-1 == err) {
-- err_str = get_zmq_strerror();
-+ /* get ZErrors table. */
-+ lua_pushlightuserdata(L, zmq_ZErrors_key);
-+ lua_rawget(L, LUA_REGISTRYINDEX);
-+ /* convert zmq_errno to string. */
-+ num = zmq_errno();
-+ lua_pushinteger(L, num);
-+ lua_gettable(L, -2);
-+ /* remove ZErrors table. */
-+ lua_remove(L, -2);
-+ if(!lua_isnil(L, -1)) {
-+ /* found error. */
-+ return;
-+ }
-+ /* Unknown error. */
-+ lua_pop(L, 1);
-+ lua_pushfstring(L, "UNKNOWN ERROR(%d)", num);
-+ return;
- }
- ]],
- ffi_source [[
- if(-1 == err) then
-- err_str = get_zmq_strerror();
-+ err_str = ZError_names[C.zmq_errno()]
- end
- ]],
- }
-diff --git a/src/msg.nobj.lua b/src/msg.nobj.lua
-index 28e18ed..c46e189 100644
---- a/src/msg.nobj.lua
-+++ b/src/msg.nobj.lua
-@@ -21,6 +21,22 @@
- object "zmq_msg_t" {
- -- store the `zmq_msg_t` structure in Lua userdata object
- userdata_type = "embed",
-+ implements "Buffer" {
-+ implement_method "const_data" {
-+ c_function = "zmq_msg_data"
-+ },
-+ implement_method "get_size" {
-+ c_function = "zmq_msg_size"
-+ },
-+ },
-+ implements "MutableBuffer" {
-+ implement_method "data" {
-+ c_function = "zmq_msg_data"
-+ },
-+ implement_method "get_size" {
-+ c_function = "zmq_msg_size"
-+ },
-+ },
- --
- -- Define zmq_msq_t type & function API for FFI
- --
-@@ -34,42 +50,31 @@ struct zmq_msg_t
- unsigned char vsm_data [30]; /* that '30' is from 'MAX_VSM_SIZE' */
- };
-
--typedef void (zmq_free_fn) (void *data, void *hint);
--
- int zmq_msg_init (zmq_msg_t *msg);
- int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
--int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint);
-
- ]],
- constructor "init" {
-- var_out{ "ZMQ_Error", "err" },
-- c_source[[
-- zmq_msg_t tmp;
-- ${this} = &tmp;
-- ${err} = zmq_msg_init(${this});
--]],
-+ c_method_call "ZMQ_Error" "zmq_msg_init" {},
- },
- constructor "init_size" {
-- var_in{ "size_t", "size" },
-- var_out{ "ZMQ_Error", "err" },
-- c_source[[
-- zmq_msg_t tmp;
-- ${this} = &tmp;
-- ${err} = zmq_msg_init_size(${this}, ${size});
--]],
-+ c_method_call "ZMQ_Error" "zmq_msg_init_size" { "size_t", "size" },
- },
- constructor "init_data" {
- var_in{ "const char *", "data" },
-- var_out{ "ZMQ_Error", "err" },
-+ c_method_call { "ZMQ_Error", "err" } "zmq_msg_init_size" { "size_t", "#data" },
- c_source[[
-- zmq_msg_t tmp;
-- ${this} = &tmp;
-- ${err} = zmq_msg_init_size(${this}, ${data_len});
- if(0 == ${err}) {
- /* fill message */
- memcpy(zmq_msg_data(${this}), ${data}, ${data_len});
- }
- ]],
-+ ffi_source[[
-+ if(0 == ${err}) then
-+ -- fill message
-+ ffi.copy(C.zmq_msg_data(${this}), ${data}, ${data_len})
-+ end
-+]],
- },
- destructor {
- c_method_call "ZMQ_Error" "zmq_msg_close" {}
-@@ -143,7 +148,7 @@ int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn
- ]],
- },
- method "size" {
-- c_method_call "size_t" "zmq_msg_size" {}
-+ c_method_call { "size_t", "size", ffi_wrap = "tonumber"} "zmq_msg_size" {}
- },
- method "__tostring" {
- var_out{ "const char *", "data", has_length = true },
-diff --git a/src/poller.lua b/src/poller.lua
-index 8c77337..2ca40ea 100644
---- a/src/poller.lua
-+++ b/src/poller.lua
-@@ -34,43 +34,36 @@ local poller_mt = {}
- poller_mt.__index = poller_mt
-
- function poller_mt:add(sock, events, cb)
-- self.poller:add(sock, events)
-- self.callbacks[sock] = cb
-+ local id = self.poller:add(sock, events)
-+ self.callbacks[id] = function(revents) return cb(sock, revents) end
- end
-
- function poller_mt:modify(sock, events, cb)
-+ local id
- if events ~= 0 and cb then
-- self.callbacks[sock] = cb
-- self.poller:modify(sock, events)
-+ id = self.poller:modify(sock, events)
-+ self.callbacks[id] = function(revents) return cb(sock, revents) end
- else
-- self:remove(sock)
-+ id = self:remove(sock)
-+ self.callbacks[id] = nil
- end
- end
-
- function poller_mt:remove(sock)
-- self.poller:remove(sock)
-- self.callbacks[sock] = nil
-+ local id = self.poller:remove(sock)
-+ self.callbacks[id] = nil
- end
-
- function poller_mt:poll(timeout)
- local poller = self.poller
-- local status, err = poller:poll(timeout)
-- if not status then
-+ local count, err = poller:poll(timeout)
-+ if not count then
- return nil, err
- end
- local callbacks = self.callbacks
-- local count = 0
-- while true do
-- local sock, revents = poller:next_revents()
-- if not sock then
-- break
-- end
-- local cb = callbacks[sock]
-- if not cb then
-- error("Missing callback for sock:" .. tostring(sock))
-- end
-- cb(sock, revents)
-- count = count + 1
-+ for i=1,count do
-+ local id, revents = poller:next_revents_idx()
-+ callbacks[id](revents)
- end
- return count
- end
-@@ -78,7 +71,7 @@ end
- function poller_mt:start()
- self.is_running = true
- while self.is_running do
-- local status, err = self:poll(-1)
-+ status, err = self:poll(-1)
- if not status then
- return false, err
- end
-@@ -90,14 +83,15 @@ function poller_mt:stop()
- self.is_running = false
- end
-
--module(...)
-+local M = {}
-
--function new(pre_alloc)
-+function M.new(pre_alloc)
- return setmetatable({
- poller = zmq.ZMQ_Poller(pre_alloc),
-- callbacks = setmetatable({}, {__mode="k"}),
-+ callbacks = {},
- }, poller_mt)
- end
-
--setmetatable(_M, {__call = function(tab, ...) return new(...) end})
-+zmq.poller = M
-+return setmetatable(M, {__call = function(tab, ...) return M.new(...) end})
-
-diff --git a/src/poller.nobj.lua b/src/poller.nobj.lua
-index 66594d2..39b4938 100644
---- a/src/poller.nobj.lua
-+++ b/src/poller.nobj.lua
-@@ -58,7 +58,24 @@ static int poller_resize_items(ZMQ_Poller *poller, int len) {
- return len;
- }
-
--static int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock) {
-+void poller_init(ZMQ_Poller *poller, int length) {
-+ poller->items = (zmq_pollitem_t *)calloc(length, sizeof(zmq_pollitem_t));
-+ poller->next = -1;
-+ poller->count = 0;
-+ poller->len = length;
-+ poller->free_list = -1;
-+}
-+
-+void poller_cleanup(ZMQ_Poller *poller) {
-+ free(poller->items);
-+ poller->items = NULL;
-+ poller->next = -1;
-+ poller->count = 0;
-+ poller->len = 0;
-+ poller->free_list = -1;
-+}
-+
-+int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock) {
- zmq_pollitem_t *items;
- int count;
- int n;
-@@ -73,7 +90,7 @@ static int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock) {
- return -1;
- }
-
--static int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd) {
-+int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd) {
- zmq_pollitem_t *items;
- int count;
- int n;
-@@ -88,7 +105,7 @@ static int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd) {
- return -1;
- }
-
--static void poller_remove_item(ZMQ_Poller *poller, int idx) {
-+void poller_remove_item(ZMQ_Poller *poller, int idx) {
- zmq_pollitem_t *items;
- int free_list;
- int count;
-@@ -115,7 +132,7 @@ static void poller_remove_item(ZMQ_Poller *poller, int idx) {
- items[idx].revents = 0;
- }
-
--static int poller_get_free_item(ZMQ_Poller *poller) {
-+int poller_get_free_item(ZMQ_Poller *poller) {
- zmq_pollitem_t *curr;
- zmq_pollitem_t *next;
- int count;
-@@ -191,14 +208,46 @@ static int poller_compact_items(ZMQ_Poller *poller) {
- return count;
- }
-
--static int poller_poll(ZMQ_Poller *poller, long timeout) {
-+int poller_poll(ZMQ_Poller *poller, long timeout) {
- int count;
- /* remove free slots from items list. */
-- count = poller_compact_items(poller);
-+ if(poller->free_list >= 0) {
-+ count = poller_compact_items(poller);
-+ } else {
-+ count = poller->count;
-+ }
- /* poll for events. */
- return zmq_poll(poller->items, count, timeout);
- }
-
-+int poller_next_revents(ZMQ_Poller *poller, int *revents) {
-+ zmq_pollitem_t *items;
-+ int count;
-+ int idx;
-+ int next;
-+
-+ idx = poller->next;
-+ /* do we need to poll for more events? */
-+ if(idx < 0) {
-+ return idx;
-+ }
-+ items = poller->items;
-+ count = poller->count;
-+ /* find next item with pending events. */
-+ for(;idx < count; ++idx) {
-+ /* did we find a pending event? */
-+ if(items[idx].revents != 0) {
-+ *revents = items[idx].revents;
-+ poller->next = idx+1;
-+ return idx;
-+ }
-+ }
-+ /* processed all pending events. */
-+ poller->next = -1;
-+ *revents = 0;
-+ return -1;
-+}
-+
- ]],
- --
- -- Define ZMQ_Poller type & function API for FFI
-@@ -212,36 +261,21 @@ typedef struct zmq_pollitem_t {
- short revents;
- } zmq_pollitem_t;
-
--int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout);
-+int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock);
-+int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd);
-+int poller_get_free_item(ZMQ_Poller *poller);
-+int poller_poll(ZMQ_Poller *poller, long timeout);
-+void poller_remove_item(ZMQ_Poller *poller, int idx);
-+
- ]],
- ffi_cdef(ZMQ_Poller_type),
-- ffi_export_function "int" "poller_find_sock_item" "(ZMQ_Poller *poller, ZMQ_Socket *sock)",
-- ffi_export_function "int" "poller_find_fd_item" "(ZMQ_Poller *poller, socket_t fd)",
-- ffi_export_function "int" "poller_get_free_item" "(ZMQ_Poller *poller)",
-- ffi_export_function "int" "poller_poll" "(ZMQ_Poller *poller, long timeout)",
-- ffi_export_function "void" "poller_remove_item" "(ZMQ_Poller *poller, int idx)",
-
- constructor "new" {
- var_in{ "unsigned int", "length", is_optional = true, default = 10 },
-- c_source[[
-- ZMQ_Poller poller;
-- ${this} = &poller;
-- ${this}->items = (zmq_pollitem_t *)calloc(${length}, sizeof(zmq_pollitem_t));
-- ${this}->next = -1;
-- ${this}->count = 0;
-- ${this}->len = ${length};
-- ${this}->free_list = -1;
--]],
-+ c_export_method_call "void" "poller_init" { "unsigned int", "length" },
- },
- destructor "close" {
-- c_source[[
-- free(${this}->items);
-- ${this}->items = NULL;
-- ${this}->next = -1;
-- ${this}->count = 0;
-- ${this}->len = 0;
-- ${this}->free_list = -1;
--]],
-+ c_export_method_call "void" "poller_cleanup" {},
- },
- method "add" {
- var_in{ "<any>", "sock" },
-@@ -266,6 +300,22 @@ int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout);
- item->fd = fd;
- item->events = ${events};
- ]],
-+ ffi_source[[
-+ local fd = 0
-+ local sock_type = type(${sock})
-+ if sock_type == 'cdata' then
-+ sock = obj_type_ZMQ_Socket_check(${sock})
-+ elseif sock_type == 'number' then
-+ fd = ${sock}
-+ else
-+ error("expected number or ZMQ_Socket")
-+ end
-+ ${idx} = Cmod.poller_get_free_item(${this})
-+ local item = ${this}.items[${idx}]
-+ item.socket = sock
-+ item.fd = fd
-+ item.events = ${events}
-+]],
- },
- method "modify" {
- var_in{ "<any>", "sock" },
-@@ -302,123 +352,99 @@ int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout);
- poller_remove_item(${this}, ${idx});
- }
- ]],
-+ ffi_source[[
-+ local fd = 0
-+ local sock_type = type(${sock})
-+ if sock_type == 'cdata' then
-+ sock = obj_type_ZMQ_Socket_check(${sock})
-+ -- find sock in items list.
-+ ${idx} = Cmod.poller_find_sock_item(${this}, sock)
-+ elseif sock_type == 'number' then
-+ fd = ${sock}
-+ -- find fd in items list.
-+ ${idx} = Cmod.poller_find_fd_item(${this}, fd);
-+ else
-+ error("expected number or ZMQ_Socket")
-+ end
-+ if ${events} ~= 0 then
-+ local item = ${this}.items[${idx}]
-+ item.socket = sock
-+ item.fd = fd
-+ item.events = ${events}
-+ else
-+ Cmod.poller_remove_item(${this}, ${idx})
-+ end
-+]],
- },
- method "remove" {
- var_in{ "<any>", "sock" },
-+ var_out{ "int", "idx" },
- c_source "pre" [[
- ZMQ_Socket *sock;
- socket_t fd;
-- int idx;
- ]],
- c_source[[
- /* ZMQ_Socket or fd */
- if(lua_isuserdata(L, ${sock::idx})) {
- sock = obj_type_ZMQ_Socket_check(L, ${sock::idx});
- /* find sock in items list. */
-- idx = poller_find_sock_item(${this}, sock);
-+ ${idx} = poller_find_sock_item(${this}, sock);
- } else if(lua_isnumber(L, ${sock::idx})) {
- fd = lua_tonumber(L, ${sock::idx});
- /* find fd in items list. */
-- idx = poller_find_fd_item(${this}, fd);
-+ ${idx} = poller_find_fd_item(${this}, fd);
- } else {
- return luaL_typerror(L, ${sock::idx}, "number or ZMQ_Socket");
- }
- /* if sock/fd was found. */
-- if(idx >= 0) {
-- poller_remove_item(${this}, idx);
-+ if(${idx} >= 0) {
-+ poller_remove_item(${this}, ${idx});
- }
- ]],
-+ ffi_source[[
-+ local fd = 0
-+ local sock_type = type(${sock})
-+ if sock_type == 'cdata' then
-+ sock = obj_type_ZMQ_Socket_check(${sock})
-+ -- find sock in items list.
-+ ${idx} = Cmod.poller_find_sock_item(${this}, sock)
-+ elseif sock_type == 'number' then
-+ fd = ${sock}
-+ -- find fd in items list.
-+ ${idx} = Cmod.poller_find_fd_item(${this}, fd);
-+ else
-+ error("expected number or ZMQ_Socket")
-+ end
-+ if ${idx} >= 0 then
-+ Cmod.poller_remove_item(${this}, ${idx})
-+ end
-+]],
- },
- method "poll" {
-- var_in{ "long", "timeout" },
-- var_out{ "ZMQ_Error", "err" },
-+ var_out{ "int", "count" },
-+ -- poll for events
-+ c_export_method_call { "ZMQ_Error", "err>2" } "poller_poll" { "long", "timeout" },
- c_source[[
-- /* poll for events */
-- ${err} = poller_poll(${this}, ${timeout});
- if(${err} > 0) {
- ${this}->next = 0;
-+ ${count} = ${err};
- } else {
- ${this}->next = -1;
-+ ${count} = 0;
- }
- ]],
- ffi_source[[
-- -- poll for events
-- ${err} = poller_poll(${this}, ${timeout})
- if(${err} > 0) then
- ${this}.next = 0
-+ ${count} = ${err}
- else
- ${this}.next = -1
-+ ${count} = 0
- end
- ]],
- },
-- method "next_revents" {
-- var_out{ "<any>", "sock" },
-- var_out{ "short", "revents" },
-- c_source "pre" [[
-- zmq_pollitem_t *items;
-- int count;
-- int idx;
--]],
-- c_source[[
-- ${revents} = -1;
-- idx = ${this}->next;
-- if(idx >= 0) {
-- count = ${this}->count;
-- items = ${this}->items;
-- /* find next item with pending events. */
-- while(idx < count && items[idx].revents == 0) ++idx;
-- /* did we find a pending event? */
-- if(idx < count) {
-- /* push the event's sock/fd. */
-- if(items[idx].socket != NULL) {
-- obj_type_ZMQ_Socket_push(L, items[idx].socket, 0);
-- } else {
-- lua_pushnumber(L, items[idx].fd);
-- }
-- ${revents} = items[idx].revents;
-- /* is this the last event. */
-- ++idx;
-- ${this}->next = (idx < count) ? idx : -1;
-- }
-- }
-- if(${revents} < 0) {
-- /* no more pending events. */
-- lua_pushnil(L);
-- ${this}->next = -1;
-- }
--]],
-- ffi_source[[
-- local sock
-- local idx = ${this}.next
-- if (idx < 0) then return nil, -1 end
-- local count = ${this}.count
-- -- find next item with pending events.
-- while (idx < count and ${this}.items[idx].revents == 0) do
-- idx = idx + 1
-- if (idx >= count) then
-- idx = -1
-- break
-- end
-- end
-- -- did we find a pending event?
-- if(idx >= 0) then
-- -- push the event's sock/fd.
-- if(${this}.items[idx].socket ~= nil) then
-- sock = obj_type_ZMQ_Socket_push(${this}.items[idx].socket, 0)
-- else
-- sock = tonumber(${this}.items[idx].fd)
-- end
-- ${revents} = ${this}.items[idx].revents
-- -- is this the last event.
-- idx = idx + 1
-- if (idx >= count) then
-- idx = -1
-- end
-- ${this}.next = idx
-- return sock, ${revents}
-- end
-- ${this}.next = idx
--]],
-+ method "next_revents_idx" {
-+ c_export_method_call { "int", "idx>1" } "poller_next_revents" { "int", "&revents>2" },
- },
- method "count" {
- var_out{ "int", "count" },
-diff --git a/src/pre_generated-zmq.nobj.c b/src/pre_generated-zmq.nobj.c
-index a6d739d..7442736 100644
---- a/src/pre_generated-zmq.nobj.c
-+++ b/src/pre_generated-zmq.nobj.c
-@@ -10,16 +10,65 @@
- #include "lauxlib.h"
- #include "lualib.h"
-
--#include <string.h>
--#include "zmq.h"
--#include "zmq_utils.h"
-+/* some Lua 5.0 compatibility support. */
-+#if !defined(lua_pushliteral)
-+#define lua_pushliteral(L, s) lua_pushstring(L, "" s, (sizeof(s)/sizeof(char))-1)
-+#endif
-+
-+#if !defined(LUA_VERSION_NUM)
-+#define lua_pushinteger(L, n) lua_pushnumber(L, (lua_Number)n)
-+#define luaL_Reg luaL_reg
-+#endif
-+
-+/* some Lua 5.1 compatibility support. */
-+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM == 501)
-+/*
-+** Adapted from Lua 5.2.0
-+*/
-+static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
-+ luaL_checkstack(L, nup, "too many upvalues");
-+ for (; l->name != NULL; l++) { /* fill the table with given functions */
-+ int i;
-+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
-+ lua_pushvalue(L, -nup);
-+ lua_pushstring(L, l->name);
-+ lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
-+ lua_settable(L, -(nup + 3));
-+ }
-+ lua_pop(L, nup); /* remove upvalues */
-+}
-+
-+#define lua_load_no_mode(L, reader, data, source) \
-+ lua_load(L, reader, data, source)
-+
-+#define lua_rawlen(L, idx) lua_objlen(L, idx)
-+
-+#endif
-+
-+#if LUA_VERSION_NUM == 502
-+
-+#define lua_load_no_mode(L, reader, data, source) \
-+ lua_load(L, reader, data, source, NULL)
-
-+static int luaL_typerror (lua_State *L, int narg, const char *tname) {
-+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
-+ tname, luaL_typename(L, narg));
-+ return luaL_argerror(L, narg, msg);
-+}
-+
-+#endif
-
- #define REG_PACKAGE_IS_CONSTRUCTOR 0
-+#define REG_MODULES_AS_GLOBALS 1
- #define REG_OBJECTS_AS_GLOBALS 0
- #define OBJ_DATA_HIDDEN_METATABLE 1
--#define LUAJIT_FFI 1
- #define USE_FIELD_GET_SET_METHODS 0
-+#define LUAJIT_FFI 1
-+
-+
-+#include <string.h>
-+#include "zmq.h"
-+#include "zmq_utils.h"
-
-
-
-@@ -41,6 +90,7 @@
- /* for MinGW32 compiler need to include <stdint.h> */
- #ifdef __GNUC__
- #include <stdint.h>
-+#include <stdbool.h>
- #else
-
- /* define some standard types missing on Windows. */
-@@ -57,7 +107,7 @@ typedef int bool;
- #define true 1
- #endif
- #ifndef false
--#define false 1
-+#define false 0
- #endif
-
- #endif
-@@ -98,19 +148,26 @@ typedef int bool;
- #define assert_obj_type(type, obj)
- #endif
-
--#ifndef obj_type_free
-+void *nobj_realloc(void *ptr, size_t osize, size_t nsize);
-+
-+void *nobj_realloc(void *ptr, size_t osize, size_t nsize) {
-+ (void)osize;
-+ if(0 == nsize) {
-+ free(ptr);
-+ return NULL;
-+ }
-+ return realloc(ptr, nsize);
-+}
-+
- #define obj_type_free(type, obj) do { \
- assert_obj_type(type, obj); \
-- free((obj)); \
-+ nobj_realloc((obj), sizeof(type), 0); \
- } while(0)
--#endif
-
--#ifndef obj_type_new
- #define obj_type_new(type, obj) do { \
- assert_obj_type(type, obj); \
-- (obj) = malloc(sizeof(type)); \
-+ (obj) = nobj_realloc(NULL, 0, sizeof(type)); \
- } while(0)
--#endif
-
- typedef struct obj_type obj_type;
-
-@@ -120,6 +177,7 @@ typedef void (*dyn_caster_t)(void **obj, obj_type **type);
-
- #define OBJ_TYPE_FLAG_WEAK_REF (1<<0)
- #define OBJ_TYPE_SIMPLE (1<<1)
-+#define OBJ_TYPE_IMPORT (1<<2)
- struct obj_type {
- dyn_caster_t dcaster; /**< caster to support casting to sub-objects. */
- int32_t id; /**< type's id. */
-@@ -168,15 +226,28 @@ typedef struct obj_field {
- uint32_t flags; /**< is_writable:1bit */
- } obj_field;
-
-+typedef enum {
-+ REG_OBJECT,
-+ REG_PACKAGE,
-+ REG_META,
-+} module_reg_type;
-+
-+typedef struct reg_impl {
-+ const char *if_name;
-+ const void *impl;
-+} reg_impl;
-+
- typedef struct reg_sub_module {
- obj_type *type;
-- int is_package;
-- const luaL_reg *pub_funcs;
-- const luaL_reg *methods;
-- const luaL_reg *metas;
-+ module_reg_type req_type;
-+ const luaL_Reg *pub_funcs;
-+ const luaL_Reg *methods;
-+ const luaL_Reg *metas;
- const obj_base *bases;
- const obj_field *fields;
- const obj_const *constants;
-+ const reg_impl *implements;
-+ int bidirectional_consts;
- } reg_sub_module;
-
- #define OBJ_UDATA_FLAG_OWN (1<<0)
-@@ -188,15 +259,78 @@ typedef struct obj_udata {
- } obj_udata;
-
- /* use static pointer as key to weak userdata table. */
--static char *obj_udata_weak_ref_key = "obj_udata_weak_ref_key";
-+static char obj_udata_weak_ref_key[] = "obj_udata_weak_ref_key";
-+
-+/* use static pointer as key to module's private table. */
-+static char obj_udata_private_key[] = "obj_udata_private_key";
-
- #if LUAJIT_FFI
-+typedef int (*ffi_export_func_t)(void);
- typedef struct ffi_export_symbol {
- const char *name;
-- void *sym;
-+ union {
-+ void *data;
-+ ffi_export_func_t func;
-+ } sym;
- } ffi_export_symbol;
- #endif
-
-+/* detect zmq version */
-+#define VERSION_2_0 1
-+#define VERSION_2_1 0
-+#define VERSION_2_2 0
-+#define VERSION_3_0 0
-+#if defined(ZMQ_VERSION_MAJOR)
-+# if (ZMQ_VERSION_MAJOR == 2) && (ZMQ_VERSION_MINOR == 2)
-+# undef VERSION_2_2
-+# define VERSION_2_2 1
-+# undef VERSION_2_1
-+# define VERSION_2_1 1
-+# endif
-+# if (ZMQ_VERSION_MAJOR == 2) && (ZMQ_VERSION_MINOR == 1)
-+# undef VERSION_2_1
-+# define VERSION_2_1 1
-+# endif
-+# if (ZMQ_VERSION_MAJOR == 3)
-+# undef VERSION_2_0
-+# define VERSION_2_0 0
-+# undef VERSION_3_0
-+# define VERSION_3_0 1
-+# endif
-+#endif
-+
-+/* make sure ZMQ_DONTWAIT & ZMQ_NOBLOCK are both defined. */
-+#ifndef ZMQ_DONTWAIT
-+# define ZMQ_DONTWAIT ZMQ_NOBLOCK
-+#endif
-+#ifndef ZMQ_NOBLOCK
-+# define ZMQ_NOBLOCK ZMQ_DONTWAIT
-+#endif
-+
-+/* make sure DEALER/ROUTER & XREQ/XREP are all defined. */
-+#ifndef ZMQ_DEALER
-+# define ZMQ_DEALER ZMQ_XREQ
-+#endif
-+#ifndef ZMQ_ROUTER
-+# define ZMQ_ROUTER ZMQ_XREP
-+#endif
-+#ifndef ZMQ_XREQ
-+# define ZMQ_XREQ ZMQ_DEALER
-+#endif
-+#ifndef ZMQ_XREP
-+# define ZMQ_XREP ZMQ_ROUTER
-+#endif
-+
-+#if VERSION_2_0
-+# define ZMQ_POLL_MSEC 1000 // zmq_poll is usec
-+#elif VERSION_3_0
-+# define ZMQ_POLL_MSEC 1 // zmq_poll is msec
-+# ifndef ZMQ_HWM
-+# define ZMQ_HWM 1 // backwards compatibility
-+# endif
-+#endif
-+
-+
-
- typedef int ZMQ_Error;
-
-@@ -204,29 +338,329 @@ static void error_code__ZMQ_Error__push(lua_State *L, ZMQ_Error err);
-
-
- static obj_type obj_types[] = {
--#define obj_type_id_zmq_msg_t 0
-+#define obj_type_id_ZErrors 0
-+#define obj_type_ZErrors (obj_types[obj_type_id_ZErrors])
-+ { NULL, 0, OBJ_TYPE_FLAG_WEAK_REF, "ZErrors" },
-+#define obj_type_id_zmq_msg_t 1
- #define obj_type_zmq_msg_t (obj_types[obj_type_id_zmq_msg_t])
-- { NULL, 0, OBJ_TYPE_SIMPLE, "zmq_msg_t" },
--#define obj_type_id_ZMQ_Socket 1
-+ { NULL, 1, OBJ_TYPE_SIMPLE, "zmq_msg_t" },
-+#define obj_type_id_ZMQ_Socket 2
- #define obj_type_ZMQ_Socket (obj_types[obj_type_id_ZMQ_Socket])
-- { NULL, 1, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_Socket" },
--#define obj_type_id_ZMQ_Poller 2
-+ { NULL, 2, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_Socket" },
-+#define obj_type_id_ZMQ_Poller 3
- #define obj_type_ZMQ_Poller (obj_types[obj_type_id_ZMQ_Poller])
-- { NULL, 2, OBJ_TYPE_SIMPLE, "ZMQ_Poller" },
--#define obj_type_id_ZMQ_Ctx 3
-+ { NULL, 3, OBJ_TYPE_SIMPLE, "ZMQ_Poller" },
-+#define obj_type_id_ZMQ_Ctx 4
- #define obj_type_ZMQ_Ctx (obj_types[obj_type_id_ZMQ_Ctx])
-- { NULL, 3, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_Ctx" },
--#define obj_type_id_ZMQ_StopWatch 4
-+ { NULL, 4, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_Ctx" },
-+#define obj_type_id_ZMQ_StopWatch 5
- #define obj_type_ZMQ_StopWatch (obj_types[obj_type_id_ZMQ_StopWatch])
-- { NULL, 4, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_StopWatch" },
-+ { NULL, 5, OBJ_TYPE_FLAG_WEAK_REF, "ZMQ_StopWatch" },
- {NULL, -1, 0, NULL},
- };
-
-
-+#if LUAJIT_FFI
-+
-+/* nobj_ffi_support_enabled_hint should be set to 1 when FFI support is enabled in at-least one
-+ * instance of a LuaJIT state. It should never be set back to 0. */
-+static int nobj_ffi_support_enabled_hint = 0;
-+static const char nobj_ffi_support_key[] = "LuaNativeObject_FFI_SUPPORT";
-+static const char nobj_check_ffi_support_code[] =
-+"local stat, ffi=pcall(require,\"ffi\")\n" /* try loading LuaJIT`s FFI module. */
-+"if not stat then return false end\n"
-+"return true\n";
-+
-+static int nobj_check_ffi_support(lua_State *L) {
-+ int rc;
-+ int err;
-+
-+ /* check if ffi test has already been done. */
-+ lua_pushstring(L, nobj_ffi_support_key);
-+ lua_rawget(L, LUA_REGISTRYINDEX);
-+ if(!lua_isnil(L, -1)) {
-+ rc = lua_toboolean(L, -1);
-+ lua_pop(L, 1);
-+ /* use results of previous check. */
-+ goto finished;
-+ }
-+ lua_pop(L, 1); /* pop nil. */
-+
-+ err = luaL_loadbuffer(L, nobj_check_ffi_support_code,
-+ sizeof(nobj_check_ffi_support_code) - 1, nobj_ffi_support_key);
-+ if(0 == err) {
-+ err = lua_pcall(L, 0, 1, 0);
-+ }
-+ if(err) {
-+ const char *msg = "<err not a string>";
-+ if(lua_isstring(L, -1)) {
-+ msg = lua_tostring(L, -1);
-+ }
-+ printf("Error when checking for FFI-support: %s\n", msg);
-+ lua_pop(L, 1); /* pop error message. */
-+ return 0;
-+ }
-+ /* check results of test. */
-+ rc = lua_toboolean(L, -1);
-+ lua_pop(L, 1); /* pop results. */
-+ /* cache results. */
-+ lua_pushstring(L, nobj_ffi_support_key);
-+ lua_pushboolean(L, rc);
-+ lua_rawset(L, LUA_REGISTRYINDEX);
-+
-+finished:
-+ /* turn-on hint that there is FFI code enabled. */
-+ if(rc) {
-+ nobj_ffi_support_enabled_hint = 1;
-+ }
-+
-+ return rc;
-+}
-+
-+typedef struct {
-+ const char **ffi_init_code;
-+ int offset;
-+} nobj_reader_state;
-+
-+static const char *nobj_lua_Reader(lua_State *L, void *data, size_t *size) {
-+ nobj_reader_state *state = (nobj_reader_state *)data;
-+ const char *ptr;
-+
-+ (void)L;
-+ ptr = state->ffi_init_code[state->offset];
-+ if(ptr != NULL) {
-+ *size = strlen(ptr);
-+ state->offset++;
-+ } else {
-+ *size = 0;
-+ }
-+ return ptr;
-+}
-+
-+static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
-+ const char *ffi_init_code[], const ffi_export_symbol *ffi_exports, int priv_table)
-+{
-+ nobj_reader_state state = { ffi_init_code, 0 };
-+ int err;
-+
-+ /* export symbols to priv_table. */
-+ while(ffi_exports->name != NULL) {
-+ lua_pushstring(L, ffi_exports->name);
-+ lua_pushlightuserdata(L, ffi_exports->sym.data);
-+ lua_settable(L, priv_table);
-+ ffi_exports++;
-+ }
-+ err = lua_load_no_mode(L, nobj_lua_Reader, &state, ffi_mod_name);
-+ if(0 == err) {
-+ lua_pushvalue(L, -2); /* dup C module's table. */
-+ lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */
-+ lua_remove(L, priv_table);
-+ lua_pushvalue(L, LUA_REGISTRYINDEX);
-+ err = lua_pcall(L, 3, 0, 0);
-+ }
-+ if(err) {
-+ const char *msg = "<err not a string>";
-+ if(lua_isstring(L, -1)) {
-+ msg = lua_tostring(L, -1);
-+ }
-+ printf("Failed to install FFI-based bindings: %s\n", msg);
-+ lua_pop(L, 1); /* pop error message. */
-+ }
-+ return err;
-+}
-+#endif
-+
-+
-+typedef struct {
-+ void *impl;
-+ void *obj;
-+} obj_implement;
-+
-+static FUNC_UNUSED void *obj_implement_luaoptional(lua_State *L, int _index, void **impl, char *if_name) {
-+ void *ud;
-+ if(lua_isnoneornil(L, _index)) {
-+ return NULL;
-+ }
-+ /* get the implements table for this interface. */
-+ lua_pushlightuserdata(L, if_name);
-+ lua_rawget(L, LUA_REGISTRYINDEX);
-+
-+ /* get pointer to userdata value & check if it is a userdata value. */
-+ ud = (obj_implement *)lua_touserdata(L, _index);
-+ if(ud != NULL) {
-+ /* get the userdata's metatable */
-+ if(lua_getmetatable(L, _index)) {
-+ /* lookup metatable in interface table for this object's implementation of the interface. */
-+ lua_gettable(L, -2);
-+ } else {
-+ /* no metatable. */
-+ goto no_interface;
-+ }
-+#if LUAJIT_FFI
-+ } else if(nobj_ffi_support_enabled_hint) { /* handle cdata. */
-+ /* get cdata interface check function from interface table. */
-+ lua_getfield(L, -1, "cdata");
-+ if(lua_isfunction(L, -1)) {
-+ /* pass cdata to function, return value should be an implmentation. */
-+ lua_pushvalue(L, _index);
-+ lua_call(L, 1, 1);
-+ /* get pointer to cdata. */
-+ ud = (void *)lua_topointer(L, _index);
-+ } else {
-+ lua_pop(L, 1); /* pop non-function. */
-+ goto no_interface;
-+ }
-+#endif
-+ } else {
-+ goto no_interface;
-+ }
-+
-+ if(!lua_isnil(L, -1)) {
-+ *impl = lua_touserdata(L, -1);
-+ lua_pop(L, 2); /* pop interface table & implementation. */
-+ /* object implements interface. */
-+ return ud;
-+ } else {
-+ lua_pop(L, 1); /* pop nil. */
-+ }
-+no_interface:
-+ lua_pop(L, 1); /* pop interface table. */
-+ return NULL;
-+}
-+
-+static FUNC_UNUSED void *obj_implement_luacheck(lua_State *L, int _index, void **impl, char *type) {
-+ void *ud = obj_implement_luaoptional(L, _index, impl, type);
-+ if(ud == NULL) {
-+#define ERROR_BUFFER_SIZE 256
-+ char buf[ERROR_BUFFER_SIZE];
-+ snprintf(buf, ERROR_BUFFER_SIZE-1,"Expected object with %s interface", type);
-+ /* value doesn't implement this interface. */
-+ luaL_argerror(L, _index, buf);
-+ }
-+ return ud;
-+}
-+
-+/* use static pointer as key to interfaces table. (version 1.0) */
-+static char obj_interfaces_table_key[] = "obj_interfaces<1.0>_table_key";
-+
-+static void obj_get_global_interfaces_table(lua_State *L) {
-+ /* get global interfaces table. */
-+ lua_getfield(L, LUA_REGISTRYINDEX, obj_interfaces_table_key);
-+ if(lua_isnil(L, -1)) {
-+ /* Need to create global interfaces table. */
-+ lua_pop(L, 1); /* pop nil */
-+ lua_createtable(L, 0, 4); /* 0 size array part, small hash part. */
-+ lua_pushvalue(L, -1); /* dup table. */
-+ /* store interfaces table in Lua registery. */
-+ lua_setfield(L, LUA_REGISTRYINDEX, obj_interfaces_table_key);
-+ }
-+}
-+
-+static void obj_get_interface(lua_State *L, const char *name, int global_if_tab) {
-+ /* get a interface's implementation table */
-+ lua_getfield(L, global_if_tab, name);
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil */
-+ /* new interface. (i.e. no object implement it yet.)
-+ *
-+ * create an empty table for this interface that will be used when an
-+ * implementation is registered for this interface.
-+ */
-+ lua_createtable(L, 0, 2); /* 0 size array part, small hash part. */
-+ lua_pushvalue(L, -1); /* dup table. */
-+ lua_setfield(L, global_if_tab, name); /* store interface in global interfaces table. */
-+ }
-+}
-+
-+static int obj_get_userdata_interface(lua_State *L) {
-+ /* get the userdata's metatable */
-+ if(lua_getmetatable(L, 2)) {
-+ /* lookup metatable in interface table for the userdata's implementation of the interface. */
-+ lua_gettable(L, 1);
-+ if(!lua_isnil(L, -1)) {
-+ /* return the implementation. */
-+ return 1;
-+ }
-+ }
-+ /* no metatable or no implementation. */
-+ return 0;
-+}
-+
-+static void obj_interface_register(lua_State *L, char *name, int global_if_tab) {
-+ /* get the table of implementations for this interface. */
-+ obj_get_interface(L, name, global_if_tab);
-+
-+ /* check for 'userdata' function. */
-+ lua_getfield(L, -1, "userdata");
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. */
-+ /* add C function for getting a userdata's implementation. */
-+ lua_pushcfunction(L, obj_get_userdata_interface);
-+ lua_setfield(L, -2, "userdata");
-+ } else {
-+ /* already have function. */
-+ lua_pop(L, 1); /* pop C function. */
-+ }
-+ /* we are going to use a lightuserdata pointer for fast lookup of the interface's impl. table. */
-+ lua_pushlightuserdata(L, name);
-+ lua_insert(L, -2);
-+ lua_settable(L, LUA_REGISTRYINDEX);
-+}
-+
-+static void obj_register_interfaces(lua_State *L, char *interfaces[]) {
-+ int i;
-+ int if_tab;
-+ /* get global interfaces table. */
-+ obj_get_global_interfaces_table(L);
-+ if_tab = lua_gettop(L);
-+
-+ for(i = 0; interfaces[i] != NULL ; i++) {
-+ obj_interface_register(L, interfaces[i], if_tab);
-+ }
-+ lua_pop(L, 1); /* pop global interfaces table. */
-+}
-+
-+static void obj_type_register_implement(lua_State *L, const reg_impl *impl, int global_if_tab, int mt_tab) {
-+ /* get the table of implementations for this interface. */
-+ obj_get_interface(L, impl->if_name, global_if_tab);
-+
-+ /* register object's implement in the interface table. */
-+ lua_pushvalue(L, mt_tab);
-+ lua_pushlightuserdata(L, (void *)impl->impl);
-+ lua_settable(L, -3);
-+
-+ lua_pop(L, 1); /* pop inteface table. */
-+}
-+
-+static void obj_type_register_implements(lua_State *L, const reg_impl *impls) {
-+ int if_tab;
-+ int mt_tab;
-+ /* get absolute position of object's metatable. */
-+ mt_tab = lua_gettop(L);
-+ /* get global interfaces table. */
-+ obj_get_global_interfaces_table(L);
-+ if_tab = lua_gettop(L);
-+
-+ for(; impls->if_name != NULL ; impls++) {
-+ obj_type_register_implement(L, impls, if_tab, mt_tab);
-+ }
-+ lua_pop(L, 1); /* pop global interfaces table. */
-+}
-+
- #ifndef REG_PACKAGE_IS_CONSTRUCTOR
- #define REG_PACKAGE_IS_CONSTRUCTOR 1
- #endif
-
-+#ifndef REG_MODULES_AS_GLOBALS
-+#define REG_MODULES_AS_GLOBALS 0
-+#endif
-+
-+/* For Lua 5.2 don't register modules as globals. */
-+#if LUA_VERSION_NUM == 502
-+#undef REG_MODULES_AS_GLOBALS
-+#define REG_MODULES_AS_GLOBALS 0
-+#endif
-+
- #ifndef REG_OBJECTS_AS_GLOBALS
- #define REG_OBJECTS_AS_GLOBALS 0
- #endif
-@@ -235,6 +669,48 @@ static obj_type obj_types[] = {
- #define OBJ_DATA_HIDDEN_METATABLE 1
- #endif
-
-+static FUNC_UNUSED int obj_import_external_type(lua_State *L, obj_type *type) {
-+ /* find the external type's metatable using it's name. */
-+ lua_pushstring(L, type->name);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* external type's metatable. */
-+ if(!lua_isnil(L, -1)) {
-+ /* found it. Now we will map our 'type' pointer to the metatable. */
-+ /* REGISTERY[lightuserdata<type>] = REGISTERY[type->name] */
-+ lua_pushlightuserdata(L, type); /* use our 'type' pointer as lookup key. */
-+ lua_pushvalue(L, -2); /* dup. type's metatable. */
-+ lua_rawset(L, LUA_REGISTRYINDEX); /* save external type's metatable. */
-+ /* NOTE: top of Lua stack still has the type's metatable. */
-+ return 1;
-+ } else {
-+ lua_pop(L, 1); /* pop nil. */
-+ }
-+ return 0;
-+}
-+
-+static FUNC_UNUSED int obj_import_external_ffi_type(lua_State *L, obj_type *type) {
-+ /* find the external type's metatable using it's name. */
-+ lua_pushstring(L, type->name);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* external type's metatable. */
-+ if(!lua_isnil(L, -1)) {
-+ /* found it. Now we will map our 'type' pointer to the C check function. */
-+ /* _priv_table[lightuserdata<type>] = REGISTERY[type->name].c_check */
-+ lua_getfield(L, -1, "c_check");
-+ lua_remove(L, -2); /* remove metatable. */
-+ if(lua_isfunction(L, -1)) {
-+ lua_pushlightuserdata(L, type); /* use our 'type' pointer as lookup key. */
-+ lua_pushvalue(L, -2); /* dup. check function */
-+ lua_rawset(L, -4); /* save check function to module's private table. */
-+ /* NOTE: top of Lua stack still has the type's C check function. */
-+ return 1;
-+ } else {
-+ lua_pop(L, 1); /* pop non function value. */
-+ }
-+ } else {
-+ lua_pop(L, 1); /* pop nil. */
-+ }
-+ return 0;
-+}
-+
- static FUNC_UNUSED obj_udata *obj_udata_toobj(lua_State *L, int _index) {
- obj_udata *ud;
- size_t len;
-@@ -245,7 +721,7 @@ static FUNC_UNUSED obj_udata *obj_udata_toobj(lua_State *L, int _index) {
- luaL_typerror(L, _index, "userdata"); /* is not a userdata value. */
- }
- /* verify userdata size. */
-- len = lua_objlen(L, _index);
-+ len = lua_rawlen(L, _index);
- if(len != sizeof(obj_udata)) {
- /* This shouldn't be possible */
- luaL_error(L, "invalid userdata size: size=%d, expected=%d", len, sizeof(obj_udata));
-@@ -258,10 +734,23 @@ static FUNC_UNUSED int obj_udata_is_compatible(lua_State *L, obj_udata *ud, void
- obj_type *ud_type;
- lua_pushlightuserdata(L, type);
- lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+recheck_metatable:
- if(lua_rawequal(L, -1, -2)) {
- *obj = ud->obj;
- /* same type no casting needed. */
- return 1;
-+ } else if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. */
-+ if((type->flags & OBJ_TYPE_IMPORT) == 0) {
-+ /* can't resolve internal type. */
-+ luaL_error(L, "Unknown object type(id=%d, name=%s)", type->id, type->name);
-+ }
-+ /* try to import external type. */
-+ if(obj_import_external_type(L, type)) {
-+ /* imported type, re-try metatable check. */
-+ goto recheck_metatable;
-+ }
-+ /* External type not yet available, so the object can't be compatible. */
- } else {
- /* Different types see if we can cast to the required type. */
- lua_rawgeti(L, -2, type->id);
-@@ -314,6 +803,39 @@ static FUNC_UNUSED obj_udata *obj_udata_luacheck_internal(lua_State *L, int _ind
- return ud;
- }
- }
-+ } else if(!lua_isnoneornil(L, _index)) {
-+ /* handle cdata. */
-+ /* get private table. */
-+ lua_pushlightuserdata(L, obj_udata_private_key);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* private table. */
-+ /* get cdata type check function from private table. */
-+ lua_pushlightuserdata(L, type);
-+ lua_rawget(L, -2);
-+
-+ /* check for function. */
-+ if(!lua_isnil(L, -1)) {
-+got_check_func:
-+ /* pass cdata value to type checking function. */
-+ lua_pushvalue(L, _index);
-+ lua_call(L, 1, 1);
-+ if(!lua_isnil(L, -1)) {
-+ /* valid type get pointer from cdata. */
-+ lua_pop(L, 2);
-+ *obj = *(void **)lua_topointer(L, _index);
-+ return ud;
-+ }
-+ lua_pop(L, 2);
-+ } else {
-+ lua_pop(L, 1); /* pop nil. */
-+ if(type->flags & OBJ_TYPE_IMPORT) {
-+ /* try to import external ffi type. */
-+ if(obj_import_external_ffi_type(L, type)) {
-+ /* imported type. */
-+ goto got_check_func;
-+ }
-+ /* External type not yet available, so the object can't be compatible. */
-+ }
-+ }
- }
- if(not_delete) {
- luaL_typerror(L, _index, type->name); /* is not a userdata value. */
-@@ -327,6 +849,15 @@ static FUNC_UNUSED void *obj_udata_luacheck(lua_State *L, int _index, obj_type *
- return obj;
- }
-
-+static FUNC_UNUSED void *obj_udata_luaoptional(lua_State *L, int _index, obj_type *type) {
-+ void *obj = NULL;
-+ if(lua_isnoneornil(L, _index)) {
-+ return obj;
-+ }
-+ obj_udata_luacheck_internal(L, _index, &(obj), type, 1);
-+ return obj;
-+}
-+
- static FUNC_UNUSED void *obj_udata_luadelete(lua_State *L, int _index, obj_type *type, int *flags) {
- void *obj;
- obj_udata *ud = obj_udata_luacheck_internal(L, _index, &(obj), type, 0);
-@@ -335,6 +866,9 @@ static FUNC_UNUSED void *obj_udata_luadelete(lua_State *L, int _index, obj_type
- /* null userdata. */
- ud->obj = NULL;
- ud->flags = 0;
-+ /* clear the metatable in invalidate userdata. */
-+ lua_pushnil(L);
-+ lua_setmetatable(L, _index);
- return obj;
- }
-
-@@ -345,6 +879,17 @@ static FUNC_UNUSED void obj_udata_luapush(lua_State *L, void *obj, obj_type *typ
- lua_pushnil(L);
- return;
- }
-+#if LUAJIT_FFI
-+ lua_pushlightuserdata(L, type);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+ if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) {
-+ /* call special FFI "void *" to FFI object convertion function. */
-+ lua_pushlightuserdata(L, obj);
-+ lua_pushinteger(L, flags);
-+ lua_call(L, 2, 1);
-+ return;
-+ }
-+#endif
- /* check for type caster. */
- if(type->dcaster) {
- (type->dcaster)(&obj, &type);
-@@ -354,8 +899,12 @@ static FUNC_UNUSED void obj_udata_luapush(lua_State *L, void *obj, obj_type *typ
- ud->obj = obj;
- ud->flags = flags;
- /* get obj_type metatable. */
-+#if LUAJIT_FFI
-+ lua_insert(L, -2); /* move userdata below metatable. */
-+#else
- lua_pushlightuserdata(L, type);
- lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+#endif
- lua_setmetatable(L, -2);
- }
-
-@@ -367,6 +916,9 @@ static FUNC_UNUSED void *obj_udata_luadelete_weak(lua_State *L, int _index, obj_
- /* null userdata. */
- ud->obj = NULL;
- ud->flags = 0;
-+ /* clear the metatable in invalidate userdata. */
-+ lua_pushnil(L);
-+ lua_setmetatable(L, _index);
- /* get objects weak table. */
- lua_pushlightuserdata(L, obj_udata_weak_ref_key);
- lua_rawget(L, LUA_REGISTRYINDEX); /* weak ref table. */
-@@ -401,6 +953,18 @@ static FUNC_UNUSED void obj_udata_luapush_weak(lua_State *L, void *obj, obj_type
- }
- lua_pop(L, 1); /* pop nil. */
-
-+#if LUAJIT_FFI
-+ lua_pushlightuserdata(L, type);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+ if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) {
-+ lua_remove(L, -2);
-+ /* call special FFI "void *" to FFI object convertion function. */
-+ lua_pushlightuserdata(L, obj);
-+ lua_pushinteger(L, flags);
-+ lua_call(L, 2, 1);
-+ return;
-+ }
-+#endif
- /* create new userdata. */
- ud = (obj_udata *)lua_newuserdata(L, sizeof(obj_udata));
-
-@@ -408,8 +972,12 @@ static FUNC_UNUSED void obj_udata_luapush_weak(lua_State *L, void *obj, obj_type
- ud->obj = obj;
- ud->flags = flags;
- /* get obj_type metatable. */
-+#if LUAJIT_FFI
-+ lua_insert(L, -2); /* move userdata below metatable. */
-+#else
- lua_pushlightuserdata(L, type);
- lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+#endif
- lua_setmetatable(L, -2);
-
- /* add weak reference to object. */
-@@ -468,9 +1036,53 @@ static FUNC_UNUSED void * obj_simple_udata_luacheck(lua_State *L, int _index, ob
- if(lua_getmetatable(L, _index)) {
- lua_pushlightuserdata(L, type);
- lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+recheck_metatable:
- if(lua_rawequal(L, -1, -2)) {
- lua_pop(L, 2); /* pop both metatables. */
- return ud;
-+ } else if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. */
-+ if((type->flags & OBJ_TYPE_IMPORT) == 0) {
-+ /* can't resolve internal type. */
-+ luaL_error(L, "Unknown object type(id=%d, name=%s)", type->id, type->name);
-+ }
-+ /* try to import external type. */
-+ if(obj_import_external_type(L, type)) {
-+ /* imported type, re-try metatable check. */
-+ goto recheck_metatable;
-+ }
-+ /* External type not yet available, so the object can't be compatible. */
-+ return 0;
-+ }
-+ }
-+ } else if(!lua_isnoneornil(L, _index)) {
-+ /* handle cdata. */
-+ /* get private table. */
-+ lua_pushlightuserdata(L, obj_udata_private_key);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* private table. */
-+ /* get cdata type check function from private table. */
-+ lua_pushlightuserdata(L, type);
-+ lua_rawget(L, -2);
-+
-+ /* check for function. */
-+ if(!lua_isnil(L, -1)) {
-+got_check_func:
-+ /* pass cdata value to type checking function. */
-+ lua_pushvalue(L, _index);
-+ lua_call(L, 1, 1);
-+ if(!lua_isnil(L, -1)) {
-+ /* valid type get pointer from cdata. */
-+ lua_pop(L, 2);
-+ return (void *)lua_topointer(L, _index);
-+ }
-+ } else {
-+ if(type->flags & OBJ_TYPE_IMPORT) {
-+ /* try to import external ffi type. */
-+ if(obj_import_external_ffi_type(L, type)) {
-+ /* imported type. */
-+ goto got_check_func;
-+ }
-+ /* External type not yet available, so the object can't be compatible. */
- }
- }
- }
-@@ -478,10 +1090,16 @@ static FUNC_UNUSED void * obj_simple_udata_luacheck(lua_State *L, int _index, ob
- return NULL;
- }
-
--static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, obj_type *type, int *flags) {
-+static FUNC_UNUSED void * obj_simple_udata_luaoptional(lua_State *L, int _index, obj_type *type) {
-+ if(lua_isnoneornil(L, _index)) {
-+ return NULL;
-+ }
-+ return obj_simple_udata_luacheck(L, _index, type);
-+}
-+
-+static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, obj_type *type) {
- void *obj;
- obj = obj_simple_udata_luacheck(L, _index, type);
-- *flags = OBJ_UDATA_FLAG_OWN;
- /* clear the metatable to invalidate userdata. */
- lua_pushnil(L);
- lua_setmetatable(L, _index);
-@@ -490,12 +1108,27 @@ static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, o
-
- static FUNC_UNUSED void *obj_simple_udata_luapush(lua_State *L, void *obj, int size, obj_type *type)
- {
-+ void *ud;
-+#if LUAJIT_FFI
-+ lua_pushlightuserdata(L, type);
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+ if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) {
-+ /* call special FFI "void *" to FFI object convertion function. */
-+ lua_pushlightuserdata(L, obj);
-+ lua_call(L, 1, 1);
-+ return obj;
-+ }
-+#endif
- /* create new userdata. */
-- void *ud = lua_newuserdata(L, size);
-+ ud = lua_newuserdata(L, size);
- memcpy(ud, obj, size);
- /* get obj_type metatable. */
-+#if LUAJIT_FFI
-+ lua_insert(L, -2); /* move userdata below metatable. */
-+#else
- lua_pushlightuserdata(L, type);
- lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */
-+#endif
- lua_setmetatable(L, -2);
-
- return ud;
-@@ -504,9 +1137,9 @@ static FUNC_UNUSED void *obj_simple_udata_luapush(lua_State *L, void *obj, int s
- /* default simple object equal method. */
- static FUNC_UNUSED int obj_simple_udata_default_equal(lua_State *L) {
- void *ud1 = obj_simple_udata_toobj(L, 1);
-- size_t len1 = lua_objlen(L, 1);
-+ size_t len1 = lua_rawlen(L, 1);
- void *ud2 = obj_simple_udata_toobj(L, 2);
-- size_t len2 = lua_objlen(L, 2);
-+ size_t len2 = lua_rawlen(L, 2);
-
- if(len1 == len2) {
- lua_pushboolean(L, (memcmp(ud1, ud2, len1) == 0));
-@@ -544,7 +1177,8 @@ static int obj_constructor_call_wrapper(lua_State *L) {
- return lua_gettop(L);
- }
-
--static void obj_type_register_constants(lua_State *L, const obj_const *constants, int tab_idx) {
-+static void obj_type_register_constants(lua_State *L, const obj_const *constants, int tab_idx,
-+ int bidirectional) {
- /* register constants. */
- while(constants->name != NULL) {
- lua_pushstring(L, constants->name);
-@@ -562,40 +1196,84 @@ static void obj_type_register_constants(lua_State *L, const obj_const *constants
- lua_pushnil(L);
- break;
- }
-+ /* map values back to keys. */
-+ if(bidirectional) {
-+ /* check if value already exists. */
-+ lua_pushvalue(L, -1);
-+ lua_rawget(L, tab_idx - 3);
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1);
-+ /* add value->key mapping. */
-+ lua_pushvalue(L, -1);
-+ lua_pushvalue(L, -3);
-+ lua_rawset(L, tab_idx - 4);
-+ } else {
-+ /* value already exists. */
-+ lua_pop(L, 1);
-+ }
-+ }
- lua_rawset(L, tab_idx - 2);
- constants++;
- }
- }
-
- static void obj_type_register_package(lua_State *L, const reg_sub_module *type_reg) {
-- const luaL_reg *reg_list = type_reg->pub_funcs;
-+ const luaL_Reg *reg_list = type_reg->pub_funcs;
-
- /* create public functions table. */
- if(reg_list != NULL && reg_list[0].name != NULL) {
- /* register functions */
-- luaL_register(L, NULL, reg_list);
-+ luaL_setfuncs(L, reg_list, 0);
- }
-
-- obj_type_register_constants(L, type_reg->constants, -1);
-+ obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts);
-
- lua_pop(L, 1); /* drop package table */
- }
-
-+static void obj_type_register_meta(lua_State *L, const reg_sub_module *type_reg) {
-+ const luaL_Reg *reg_list;
-+
-+ /* create public functions table. */
-+ reg_list = type_reg->pub_funcs;
-+ if(reg_list != NULL && reg_list[0].name != NULL) {
-+ /* register functions */
-+ luaL_setfuncs(L, reg_list, 0);
-+ }
-+
-+ obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts);
-+
-+ /* register methods. */
-+ luaL_setfuncs(L, type_reg->methods, 0);
-+
-+ /* create metatable table. */
-+ lua_newtable(L);
-+ luaL_setfuncs(L, type_reg->metas, 0); /* fill metatable */
-+ /* setmetatable on meta-object. */
-+ lua_setmetatable(L, -2);
-+
-+ lua_pop(L, 1); /* drop meta-object */
-+}
-+
- static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int priv_table) {
-- const luaL_reg *reg_list;
-+ const luaL_Reg *reg_list;
- obj_type *type = type_reg->type;
- const obj_base *base = type_reg->bases;
-
-- if(type_reg->is_package == 1) {
-+ if(type_reg->req_type == REG_PACKAGE) {
- obj_type_register_package(L, type_reg);
- return;
- }
-+ if(type_reg->req_type == REG_META) {
-+ obj_type_register_meta(L, type_reg);
-+ return;
-+ }
-
- /* create public functions table. */
- reg_list = type_reg->pub_funcs;
- if(reg_list != NULL && reg_list[0].name != NULL) {
- /* register "constructors" as to object's public API */
-- luaL_register(L, NULL, reg_list); /* fill public API table. */
-+ luaL_setfuncs(L, reg_list, 0); /* fill public API table. */
-
- /* make public API table callable as the default constructor. */
- lua_newtable(L); /* create metatable */
-@@ -625,7 +1303,7 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
- #endif
- }
-
-- luaL_register(L, NULL, type_reg->methods); /* fill methods table. */
-+ luaL_setfuncs(L, type_reg->methods, 0); /* fill methods table. */
-
- luaL_newmetatable(L, type->name); /* create metatable */
- lua_pushliteral(L, ".name");
-@@ -638,16 +1316,12 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
- lua_pushvalue(L, -2); /* dup metatable. */
- lua_rawset(L, LUA_REGISTRYINDEX); /* REGISTRY[type] = metatable */
-
--#if LUAJIT_FFI
- /* add metatable to 'priv_table' */
- lua_pushstring(L, type->name);
- lua_pushvalue(L, -2); /* dup metatable. */
- lua_rawset(L, priv_table); /* priv_table["<object_name>"] = metatable */
--#else
-- (void)priv_table;
--#endif
-
-- luaL_register(L, NULL, type_reg->metas); /* fill metatable */
-+ luaL_setfuncs(L, type_reg->metas, 0); /* fill metatable */
-
- /* add obj_bases to metatable. */
- while(base->id >= 0) {
-@@ -656,7 +1330,9 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int
- base++;
- }
-
-- obj_type_register_constants(L, type_reg->constants, -2);
-+ obj_type_register_constants(L, type_reg->constants, -2, type_reg->bidirectional_consts);
-+
-+ obj_type_register_implements(L, type_reg->implements);
-
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, -3); /* dup methods table */
-@@ -676,62 +1352,193 @@ static FUNC_UNUSED int lua_checktype_ref(lua_State *L, int _index, int _type) {
- return luaL_ref(L, LUA_REGISTRYINDEX);
- }
-
--#if LUAJIT_FFI
--static int nobj_udata_new_ffi(lua_State *L) {
-- size_t size = luaL_checkinteger(L, 1);
-- void *ud;
-- luaL_checktype(L, 2, LUA_TTABLE);
-- lua_settop(L, 2);
-- /* create userdata. */
-- ud = lua_newuserdata(L, size);
-- lua_replace(L, 1);
-- /* set userdata's metatable. */
-- lua_setmetatable(L, 1);
-- return 1;
--}
-+/* use static pointer as key to weak callback_state table. */
-+static char obj_callback_state_weak_ref_key[] = "obj_callback_state_weak_ref_key";
-
--static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
-- const char *ffi_init_code, const ffi_export_symbol *ffi_exports, int priv_table)
--{
-- int err;
-+static FUNC_UNUSED void *nobj_get_callback_state(lua_State *L, int owner_idx, int size) {
-+ void *cb_state;
-
-- /* export symbols to priv_table. */
-- while(ffi_exports->name != NULL) {
-- lua_pushstring(L, ffi_exports->name);
-- lua_pushlightuserdata(L, ffi_exports->sym);
-- lua_settable(L, priv_table);
-- ffi_exports++;
-+ lua_pushlightuserdata(L, obj_callback_state_weak_ref_key); /* key for weak table. */
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* check if weak table exists already. */
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. */
-+ /* create weak table for callback_state */
-+ lua_newtable(L); /* weak table. */
-+ lua_newtable(L); /* metatable for weak table. */
-+ lua_pushliteral(L, "__mode");
-+ lua_pushliteral(L, "k");
-+ lua_rawset(L, -3); /* metatable.__mode = 'k' weak keys. */
-+ lua_setmetatable(L, -2); /* add metatable to weak table. */
-+ lua_pushlightuserdata(L, obj_callback_state_weak_ref_key); /* key for weak table. */
-+ lua_pushvalue(L, -2); /* dup weak table. */
-+ lua_rawset(L, LUA_REGISTRYINDEX); /* add weak table to registry. */
- }
-- err = luaL_loadbuffer(L, ffi_init_code, strlen(ffi_init_code), ffi_mod_name);
-- if(0 == err) {
-- lua_pushvalue(L, -2); /* dup C module's table. */
-- lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */
-- lua_remove(L, priv_table);
-- lua_pushcfunction(L, nobj_udata_new_ffi);
-- err = lua_pcall(L, 3, 0, 0);
-+
-+ /* check weak table for callback_state. */
-+ lua_pushvalue(L, owner_idx); /* dup. owner as lookup key. */
-+ lua_rawget(L, -2);
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. */
-+ lua_pushvalue(L, owner_idx); /* dup. owner as lookup key. */
-+ /* create new callback state. */
-+ cb_state = lua_newuserdata(L, size);
-+ lua_rawset(L, -3);
-+ lua_pop(L, 1); /* pop <weak table> */
-+ } else {
-+ /* got existing callback state. */
-+ cb_state = lua_touserdata(L, -1);
-+ lua_pop(L, 2); /* pop <weak table>, <callback_state> */
- }
-- if(err) {
-- const char *msg = "<err not a string>";
-- if(lua_isstring(L, -1)) {
-- msg = lua_tostring(L, -1);
-- }
-- printf("Failed to install FFI-based bindings: %s\n", msg);
-- lua_pop(L, 1); /* pop error message. */
-+
-+ return cb_state;
-+}
-+
-+static FUNC_UNUSED void *nobj_delete_callback_state(lua_State *L, int owner_idx) {
-+ void *cb_state = NULL;
-+
-+ lua_pushlightuserdata(L, obj_callback_state_weak_ref_key); /* key for weak table. */
-+ lua_rawget(L, LUA_REGISTRYINDEX); /* check if weak table exists already. */
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop nil. no weak table, so there is no callback state. */
-+ return NULL;
- }
-- return err;
-+ /* get callback state. */
-+ lua_pushvalue(L, owner_idx); /* dup. owner */
-+ lua_rawget(L, -2);
-+ if(lua_isnil(L, -1)) {
-+ lua_pop(L, 2); /* pop <weak table>, nil. No callback state for the owner. */
-+ } else {
-+ cb_state = lua_touserdata(L, -1);
-+ lua_pop(L, 1); /* pop <state> */
-+ /* remove callback state. */
-+ lua_pushvalue(L, owner_idx); /* dup. owner */
-+ lua_pushnil(L);
-+ lua_rawset(L, -3);
-+ lua_pop(L, 1); /* pop <weak table> */
-+ }
-+
-+ return cb_state;
- }
--#endif
-+
-+
-+
-+
-+
-+typedef struct MutableBuffer_if {
-+ uint8_t * (* const data)(void *this_v);
-+ size_t (* const get_size)(void *this_v);
-+} MutableBufferIF;
-+
-+/* a per-module unique pointer for fast lookup of an interface's implementation table. */
-+static char obj_interface_MutableBufferIF[] = "MutableBufferIF";
-+
-+#define MutableBufferIF_VAR(var_name) \
-+ MutableBufferIF *var_name ## _if; \
-+ void *var_name;
-+
-+#define MutableBufferIF_LUA_OPTIONAL(L, _index, var_name) \
-+ var_name = obj_implement_luaoptional(L, _index, (void **)&(var_name ## _if), \
-+ obj_interface_MutableBufferIF)
-+
-+#define MutableBufferIF_LUA_CHECK(L, _index, var_name) \
-+ var_name = obj_implement_luacheck(L, _index, (void **)&(var_name ## _if), \
-+ obj_interface_MutableBufferIF)
-+
-+
-+
-+
-+
-+
-+typedef struct Buffer_if {
-+ const uint8_t * (* const const_data)(void *this_v);
-+ size_t (* const get_size)(void *this_v);
-+} BufferIF;
-+
-+/* a per-module unique pointer for fast lookup of an interface's implementation table. */
-+static char obj_interface_BufferIF[] = "BufferIF";
-+
-+#define BufferIF_VAR(var_name) \
-+ BufferIF *var_name ## _if; \
-+ void *var_name;
-+
-+#define BufferIF_LUA_OPTIONAL(L, _index, var_name) \
-+ var_name = obj_implement_luaoptional(L, _index, (void **)&(var_name ## _if), \
-+ obj_interface_BufferIF)
-+
-+#define BufferIF_LUA_CHECK(L, _index, var_name) \
-+ var_name = obj_implement_luacheck(L, _index, (void **)&(var_name ## _if), \
-+ obj_interface_BufferIF)
-+
-+
-+
-+
-+static char *obj_interfaces[] = {
-+ obj_interface_MutableBufferIF,
-+ obj_interface_BufferIF,
-+ NULL,
-+};
-+
-+/**
-+ * zmq_msg_t implements Buffer interface
-+ */
-+/**
-+ * Buffer interface method const_data
-+ */
-+static const uint8_t * zmq_msg_t_Buffer_const_data(void *this_v) {
-+ zmq_msg_t * this_p = this_v;
-+ return zmq_msg_data(this_p);
-+}
-+/**
-+ * Buffer interface method get_size
-+ */
-+static size_t zmq_msg_t_Buffer_get_size(void *this_v) {
-+ zmq_msg_t * this_p = this_v;
-+ return zmq_msg_size(this_p);
-+}
-+
-+static const BufferIF zmq_msg_t_Buffer = {
-+ zmq_msg_t_Buffer_const_data,
-+ zmq_msg_t_Buffer_get_size
-+};
-+
-+/**
-+ * zmq_msg_t implements MutableBuffer interface
-+ */
-+/**
-+ * MutableBuffer interface method data
-+ */
-+static uint8_t * zmq_msg_t_MutableBuffer_data(void *this_v) {
-+ zmq_msg_t * this_p = this_v;
-+ return zmq_msg_data(this_p);
-+}
-+/**
-+ * MutableBuffer interface method get_size
-+ */
-+static size_t zmq_msg_t_MutableBuffer_get_size(void *this_v) {
-+ zmq_msg_t * this_p = this_v;
-+ return zmq_msg_size(this_p);
-+}
-+
-+static const MutableBufferIF zmq_msg_t_MutableBuffer = {
-+ zmq_msg_t_MutableBuffer_data,
-+ zmq_msg_t_MutableBuffer_get_size
-+};
-+
-
-
- #define obj_type_zmq_msg_t_check(L, _index) \
- (zmq_msg_t *)obj_simple_udata_luacheck(L, _index, &(obj_type_zmq_msg_t))
--#define obj_type_zmq_msg_t_delete(L, _index, flags) \
-- (zmq_msg_t *)obj_simple_udata_luadelete(L, _index, &(obj_type_zmq_msg_t), flags)
--#define obj_type_zmq_msg_t_push(L, obj, flags) \
-+#define obj_type_zmq_msg_t_optional(L, _index) \
-+ (zmq_msg_t *)obj_simple_udata_luaoptional(L, _index, &(obj_type_zmq_msg_t))
-+#define obj_type_zmq_msg_t_delete(L, _index) \
-+ (zmq_msg_t *)obj_simple_udata_luadelete(L, _index, &(obj_type_zmq_msg_t))
-+#define obj_type_zmq_msg_t_push(L, obj) \
- obj_simple_udata_luapush(L, obj, sizeof(zmq_msg_t), &(obj_type_zmq_msg_t))
-
- #define obj_type_ZMQ_Socket_check(L, _index) \
- obj_udata_luacheck(L, _index, &(obj_type_ZMQ_Socket))
-+#define obj_type_ZMQ_Socket_optional(L, _index) \
-+ obj_udata_luaoptional(L, _index, &(obj_type_ZMQ_Socket))
- #define obj_type_ZMQ_Socket_delete(L, _index, flags) \
- obj_udata_luadelete_weak(L, _index, &(obj_type_ZMQ_Socket), flags)
- #define obj_type_ZMQ_Socket_push(L, obj, flags) \
-@@ -739,13 +1546,17 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
-
- #define obj_type_ZMQ_Poller_check(L, _index) \
- (ZMQ_Poller *)obj_simple_udata_luacheck(L, _index, &(obj_type_ZMQ_Poller))
--#define obj_type_ZMQ_Poller_delete(L, _index, flags) \
-- (ZMQ_Poller *)obj_simple_udata_luadelete(L, _index, &(obj_type_ZMQ_Poller), flags)
--#define obj_type_ZMQ_Poller_push(L, obj, flags) \
-+#define obj_type_ZMQ_Poller_optional(L, _index) \
-+ (ZMQ_Poller *)obj_simple_udata_luaoptional(L, _index, &(obj_type_ZMQ_Poller))
-+#define obj_type_ZMQ_Poller_delete(L, _index) \
-+ (ZMQ_Poller *)obj_simple_udata_luadelete(L, _index, &(obj_type_ZMQ_Poller))
-+#define obj_type_ZMQ_Poller_push(L, obj) \
- obj_simple_udata_luapush(L, obj, sizeof(ZMQ_Poller), &(obj_type_ZMQ_Poller))
-
- #define obj_type_ZMQ_Ctx_check(L, _index) \
- obj_udata_luacheck(L, _index, &(obj_type_ZMQ_Ctx))
-+#define obj_type_ZMQ_Ctx_optional(L, _index) \
-+ obj_udata_luaoptional(L, _index, &(obj_type_ZMQ_Ctx))
- #define obj_type_ZMQ_Ctx_delete(L, _index, flags) \
- obj_udata_luadelete_weak(L, _index, &(obj_type_ZMQ_Ctx), flags)
- #define obj_type_ZMQ_Ctx_push(L, obj, flags) \
-@@ -753,6 +1564,8 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
-
- #define obj_type_ZMQ_StopWatch_check(L, _index) \
- obj_udata_luacheck(L, _index, &(obj_type_ZMQ_StopWatch))
-+#define obj_type_ZMQ_StopWatch_optional(L, _index) \
-+ obj_udata_luaoptional(L, _index, &(obj_type_ZMQ_StopWatch))
- #define obj_type_ZMQ_StopWatch_delete(L, _index, flags) \
- obj_udata_luadelete_weak(L, _index, &(obj_type_ZMQ_StopWatch), flags)
- #define obj_type_ZMQ_StopWatch_push(L, obj, flags) \
-@@ -761,30 +1574,83 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name,
-
-
-
--static const char zmq_ffi_lua_code[] = "local error = error\n"
-+static const char *zmq_ffi_lua_code[] = { "local ffi=require\"ffi\"\n"
-+"local function ffi_safe_load(name, global)\n"
-+" local stat, C = pcall(ffi.load, name, global)\n"
-+" if not stat then return nil, C end\n"
-+" if global then return ffi.C end\n"
-+" return C\n"
-+"end\n"
-+"local function ffi_load(name, global)\n"
-+" return assert(ffi_safe_load(name, global))\n"
-+"end\n"
-+"\n"
-+"local function ffi_string(ptr)\n"
-+" if ptr ~= nil then\n"
-+" return ffi.string(ptr)\n"
-+" end\n"
-+" return nil\n"
-+"end\n"
-+"\n"
-+"local function ffi_string_len(ptr, len)\n"
-+" if ptr ~= nil then\n"
-+" return ffi.string(ptr, len)\n"
-+" end\n"
-+" return nil\n"
-+"end\n"
-+"\n"
-+"local f_cast = ffi.cast\n"
-+"local pcall = pcall\n"
-+"local error = error\n"
- "local type = type\n"
- "local tonumber = tonumber\n"
- "local tostring = tostring\n"
-+"local sformat = require\"string\".format\n"
- "local rawset = rawset\n"
--"\n"
--"-- try loading luajit's ffi\n"
--"local stat, ffi=pcall(require,\"ffi\")\n"
--"if not stat then\n"
--" return\n"
-+"local setmetatable = setmetatable\n"
-+"local package = (require\"package\") or {}\n"
-+"local p_config = package.config\n"
-+"local p_cpath = package.cpath\n"
-+"\n"
-+"\n"
-+"local ffi_load_cmodule\n"
-+"\n"
-+"-- try to detect luvit.\n"
-+"if p_config == nil and p_cpath == nil then\n"
-+" ffi_load_cmodule = function(name, global)\n"
-+" for path,module in pairs(package.loaded) do\n"
-+" if module == name then\n"
-+" local C, err = ffi_safe_load(path, global)\n"
-+" -- return opened library\n"
-+" if C then return C end\n"
-+" end\n"
-+" end\n"
-+" error(\"Failed to find: \" .. name)\n"
-+" end\n"
-+"else\n"
-+" ffi_load_cmodule = function(name, global)\n"
-+" local dir_sep = p_config:sub(1,1)\n"
-+" local path_sep = p_config:sub(3,3)\n"
-+" local path_mark = p_config:sub(5,5)\n"
-+" local path_match = \"([^\" .. path_sep .. \"]*)\" .. path_sep\n"
-+" -- convert dotted name to directory path.\n"
-+" name = name:gsub('%.', dir_sep)\n"
-+" -- try each path in search path.\n"
-+" for path in p_cpath:gmatch(path_match) do\n"
-+" local fname = path:gsub(path_mark, name)\n"
-+" local C, err = ffi_safe_load(fname, global)\n"
-+" -- return opened library\n"
-+" if C then return C end\n"
-+" end\n"
-+" error(\"Failed to find: \" .. name)\n"
-+" end\n"
- "end\n"
- "\n"
--"local _M, _priv, udata_new = ...\n"
--"\n"
--"local band = bit.band\n"
--"local d_getmetatable = debug.getmetatable\n"
--"local d_setmetatable = debug.setmetatable\n"
-+"local _M, _priv, reg_table = ...\n"
-+"local REG_OBJECTS_AS_GLOBALS = false\n"
-+"local C = ffi.C\n"
- "\n"
- "local OBJ_UDATA_FLAG_OWN = 1\n"
--"local OBJ_UDATA_FLAG_LOOKUP = 2\n"
--"local OBJ_UDATA_LAST_FLAG = OBJ_UDATA_FLAG_LOOKUP\n"
--"\n"
--"local OBJ_TYPE_FLAG_WEAK_REF = 1\n"
--"local OBJ_TYPE_SIMPLE = 2\n"
- "\n"
- "local function ffi_safe_cdef(block_name, cdefs)\n"
- " local fake_type = \"struct sentinel_\" .. block_name .. \"_ty\"\n"
-@@ -822,151 +1688,94 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- " uint32_t flags; /**< lua_own:1bit */\n"
- "} obj_udata;\n"
- "\n"
--"]])\n"
--"\n"
--"-- cache mapping of cdata to userdata\n"
--"local weak_objects = setmetatable({}, { __mode = \"v\" })\n"
-+"int memcmp(const void *s1, const void *s2, size_t n);\n"
- "\n"
--"local function obj_udata_luacheck_internal(obj, type_mt, not_delete)\n"
--" local obj_mt = d_getmetatable(obj)\n"
--" if obj_mt == type_mt then\n"
--" -- convert userdata to cdata.\n"
--" return ffi.cast(\"obj_udata *\", obj)\n"
--" end\n"
--" if not_delete then\n"
--" error(\"(expected `\" .. type_mt['.name'] .. \"`, got \" .. type(obj) .. \")\", 3)\n"
--" end\n"
--"end\n"
-+"]])\n"
- "\n"
--"local function obj_udata_luacheck(obj, type_mt)\n"
--" local ud = obj_udata_luacheck_internal(obj, type_mt, true)\n"
--" return ud.obj\n"
--"end\n"
-+"local nobj_callback_states = {}\n"
-+"local nobj_weak_objects = setmetatable({}, {__mode = \"v\"})\n"
-+"local nobj_obj_flags = {}\n"
- "\n"
--"local function obj_udata_to_cdata(objects, ud_obj, c_type, ud_mt)\n"
--" -- convert userdata to cdata.\n"
--" local c_obj = ffi.cast(c_type, obj_udata_luacheck(ud_obj, ud_mt))\n"
--" -- cache converted cdata\n"
--" rawset(objects, ud_obj, c_obj)\n"
--" return c_obj\n"
-+"local function obj_ptr_to_id(ptr)\n"
-+" return tonumber(f_cast('uintptr_t', ptr))\n"
- "end\n"
- "\n"
--"local function obj_udata_luadelete(ud_obj, type_mt)\n"
--" local ud = obj_udata_luacheck_internal(ud_obj, type_mt, false)\n"
--" if not ud then return nil, 0 end\n"
--" local obj, flags = ud.obj, ud.flags\n"
--" -- null userdata.\n"
--" ud.obj = nil\n"
--" ud.flags = 0\n"
--" -- invalid userdata, by setting the metatable to nil.\n"
--" d_setmetatable(ud_obj, nil)\n"
--" return obj, flags\n"
-+"local function obj_to_id(ptr)\n"
-+" return tonumber(f_cast('uintptr_t', f_cast('void *', ptr)))\n"
- "end\n"
- "\n"
--"local function obj_udata_luapush(obj, type_mt, obj_type, flags)\n"
--" if obj == nil then return end\n"
--"\n"
--" -- apply type's dynamic caster.\n"
--" if obj_type.dcaster ~= nil then\n"
--" local obj_ptr = ffi.new(\"void *[1]\", obj)\n"
--" local type_ptr = ffi.new(\"obj_type *[1]\", obj_type)\n"
--" obj_type.dcaster(obj_ptr, type_ptr)\n"
--" obj = obj_ptr[1]\n"
--" type = type_ptr[1]\n"
-+"local function register_default_constructor(_pub, obj_name, constructor)\n"
-+" local obj_pub = _pub[obj_name]\n"
-+" if type(obj_pub) == 'table' then\n"
-+" -- copy table since it might have a locked metatable\n"
-+" local new_pub = {}\n"
-+" for k,v in pairs(obj_pub) do\n"
-+" new_pub[k] = v\n"
-+" end\n"
-+" setmetatable(new_pub, { __call = function(t,...)\n"
-+" return constructor(...)\n"
-+" end,\n"
-+" __metatable = false,\n"
-+" })\n"
-+" obj_pub = new_pub\n"
-+" else\n"
-+" obj_pub = constructor\n"
- " end\n"
--"\n"
--" -- create new userdata\n"
--" local ud_obj = udata_new(ffi.sizeof\"obj_udata\", type_mt)\n"
--" local ud = ffi.cast(\"obj_udata *\", ud_obj)\n"
--" -- init. object\n"
--" ud.obj = obj\n"
--" ud.flags = flags\n"
--"\n"
--" return ud_obj\n"
--"end\n"
--"\n"
--"local function obj_udata_luadelete_weak(ud_obj, type_mt)\n"
--" local ud = obj_udata_luacheck_internal(ud_obj, type_mt, false)\n"
--" if not ud then return nil, 0 end\n"
--" local obj, flags = ud.obj, ud.flags\n"
--" -- null userdata.\n"
--" ud.obj = nil\n"
--" ud.flags = 0\n"
--" -- invalid userdata, by setting the metatable to nil.\n"
--" d_setmetatable(ud_obj, nil)\n"
--" -- remove object from weak ref. table.\n"
--" local obj_key = tonumber(ffi.cast('uintptr_t', obj))\n"
--" weak_objects[obj_key] = nil\n"
--" return obj, flags\n"
--"end\n"
--"\n"
--"local function obj_udata_luapush_weak(obj, type_mt, obj_type, flags)\n"
--" if obj == nil then return end\n"
--"\n"
--" -- apply type's dynamic caster.\n"
--" if obj_type.dcaster ~= nil then\n"
--" local obj_ptr = ffi.new(\"void *[1]\", obj)\n"
--" local type_ptr = ffi.new(\"obj_type *[1]\", obj_type)\n"
--" obj_type.dcaster(obj_ptr, type_ptr)\n"
--" obj = obj_ptr[1]\n"
--" type = type_ptr[1]\n"
-+" _pub[obj_name] = obj_pub\n"
-+" _M[obj_name] = obj_pub\n"
-+" if REG_OBJECTS_AS_GLOBALS then\n"
-+" _G[obj_name] = obj_pub\n"
- " end\n"
--"\n"
--" -- lookup object in weak ref. table.\n"
--" local obj_key = tonumber(ffi.cast('uintptr_t', obj))\n"
--" local ud_obj = weak_objects[obj_key]\n"
--" if ud_obj ~= nil then return ud_obj end\n"
--"\n"
--" -- create new userdata\n"
--" ud_obj = udata_new(ffi.sizeof\"obj_udata\", type_mt)\n"
--" local ud = ffi.cast(\"obj_udata *\", ud_obj)\n"
--" -- init. object\n"
--" ud.obj = obj\n"
--" ud.flags = flags\n"
--"\n"
--" -- cache weak reference to object.\n"
--" weak_objects[obj_key] = ud_obj\n"
--"\n"
--" return ud_obj\n"
- "end\n"
- "\n"
--"local function obj_simple_udata_luacheck(ud_obj, type_mt)\n"
--" local obj_mt = d_getmetatable(ud_obj)\n"
--" if obj_mt == type_mt then\n"
--" -- convert userdata to cdata.\n"
--" return ffi.cast(\"void *\", ud_obj)\n"
--" end\n"
--" error(\"(expected `\" .. type_mt['.name'] .. \"`, got \" .. type(ud_obj) .. \")\", 3)\n"
--"end\n"
- "\n"
--"local function obj_simple_udata_to_cdata(objects, ud_obj, c_type, ud_mt)\n"
--" -- convert userdata to cdata.\n"
--" local c_obj = ffi.cast(c_type, obj_simple_udata_luacheck(ud_obj, ud_mt))\n"
--" -- cache converted cdata\n"
--" rawset(objects, ud_obj, c_obj)\n"
--" return c_obj\n"
-+"-- detect zmq version\n"
-+"local VERSION_2_0 = true\n"
-+"local VERSION_2_1 = false\n"
-+"local VERSION_2_2 = false\n"
-+"local VERSION_3_0 = false\n"
-+"local zver = _M.version()\n"
-+"if zver[1] == 3 then\n"
-+" VERSION_2_0 = false\n"
-+" VERSION_3_0 = true\n"
-+"elseif zver[1] == 2 and zver[2] == 2 then\n"
-+" VERSION_2_2 = true\n"
-+" VERSION_2_1 = true\n"
-+"elseif zver[1] == 2 and zver[2] == 1 then\n"
-+" VERSION_2_1 = true\n"
- "end\n"
- "\n"
--"local function obj_simple_udata_luadelete(ud_obj, type_mt)\n"
--" local c_obj = obj_simple_udata_luacheck(ud_obj, type_mt)\n"
--" -- invalid userdata, by setting the metatable to nil.\n"
--" d_setmetatable(ud_obj, nil)\n"
--" return c_obj, OBJ_UDATA_FLAG_OWN\n"
-+"if VERSION_2_0 then\n"
-+" ffi.cdef[==[\n"
-+"typedef int ZMQ_Error;\n"
-+"typedef struct ZMQ_Socket ZMQ_Socket;\n"
-+"typedef struct zmq_msg_t zmq_msg_t;\n"
-+"\n"
-+"ZMQ_Error zmq_sendmsg(ZMQ_Socket *sock, zmq_msg_t *msg, int flags) __asm__(\"zmq_send\");\n"
-+"ZMQ_Error zmq_recvmsg(ZMQ_Socket *sock, zmq_msg_t *msg, int flags) __asm__(\"zmq_recv\");\n"
-+"]==]\n"
- "end\n"
- "\n"
--"local function obj_simple_udata_luapush(c_obj, size, type_mt)\n"
--" if c_obj == nil then return end\n"
-+"ffi_safe_cdef(\"MutableBufferIF\", [[\n"
-+"typedef struct MutableBuffer_if {\n"
-+" uint8_t * (* const data)(void *this_v);\n"
-+" size_t (* const get_size)(void *this_v);\n"
-+"} MutableBufferIF;\n"
-+"]])\n"
- "\n"
--" -- create new userdata\n"
--" local ud_obj = udata_new(size, type_mt)\n"
--" local cdata = ffi.cast(\"void *\", ud_obj)\n"
--" -- init. object\n"
--" ffi.copy(cdata, c_obj, size)\n"
-+"ffi_safe_cdef(\"BufferIF\", [[\n"
-+"typedef struct Buffer_if {\n"
-+" const uint8_t * (* const const_data)(void *this_v);\n"
-+" size_t (* const get_size)(void *this_v);\n"
-+"} BufferIF;\n"
-+"]])\n"
- "\n"
--" return ud_obj, cdata\n"
--"end\n"
-+"local Cmod = ffi_load_cmodule(\"zmq\", false)\n"
-+"local C = Cmod\n"
- "\n"
- "ffi.cdef[[\n"
-+"typedef int ZMQ_Error;\n"
-+"\n"
- "typedef struct zmq_msg_t zmq_msg_t;\n"
- "typedef struct ZMQ_Socket ZMQ_Socket;\n"
- "typedef struct ZMQ_Poller ZMQ_Poller;\n"
-@@ -976,9 +1785,7 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- "]]\n"
- "\n"
- "ffi.cdef[[\n"
--"typedef const char * (*get_zmq_strerror_func)();\n"
--"\n"
--"typedef int ZMQ_Error;\n"
-+"int zmq_errno (void);\n"
- "\n"
- "\n"
- "struct zmq_msg_t\n"
-@@ -989,39 +1796,134 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- " unsigned char vsm_data [30]; /* that '30' is from 'MAX_VSM_SIZE' */\n"
- "};\n"
- "\n"
--"typedef void (zmq_free_fn) (void *data, void *hint);\n"
--"\n"
- "int zmq_msg_init (zmq_msg_t *msg);\n"
- "int zmq_msg_init_size (zmq_msg_t *msg, size_t size);\n"
--"int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint);\n"
- "\n"
- "\n"
--"ZMQ_Error zmq_msg_close(zmq_msg_t * this1);\n"
-+"ZMQ_Error zmq_msg_init(zmq_msg_t *);\n"
- "\n"
--"ZMQ_Error zmq_msg_close(zmq_msg_t * this1);\n"
-+"ZMQ_Error zmq_msg_init_size(zmq_msg_t *, size_t);\n"
- "\n"
--"ZMQ_Error zmq_msg_move(zmq_msg_t * this1, zmq_msg_t * src2);\n"
-+"ZMQ_Error zmq_msg_close(zmq_msg_t *);\n"
- "\n"
--"ZMQ_Error zmq_msg_copy(zmq_msg_t * this1, zmq_msg_t * src2);\n"
-+"ZMQ_Error zmq_msg_move(zmq_msg_t *, zmq_msg_t *);\n"
- "\n"
--"void * zmq_msg_data(zmq_msg_t * this1);\n"
-+"ZMQ_Error zmq_msg_copy(zmq_msg_t *, zmq_msg_t *);\n"
- "\n"
--"size_t zmq_msg_size(zmq_msg_t * this1);\n"
-+"void * zmq_msg_data(zmq_msg_t *);\n"
- "\n"
--"ZMQ_Error zmq_close(ZMQ_Socket * this1);\n"
-+"size_t zmq_msg_size(zmq_msg_t *);\n"
- "\n"
--"ZMQ_Error zmq_bind(ZMQ_Socket * this1, const char * addr2);\n"
-+"ZMQ_Error zmq_close(ZMQ_Socket *);\n"
- "\n"
--"ZMQ_Error zmq_connect(ZMQ_Socket * this1, const char * addr2);\n"
-+"ZMQ_Error zmq_bind(ZMQ_Socket *, const char *);\n"
-+"\n"
-+"ZMQ_Error zmq_connect(ZMQ_Socket *, const char *);\n"
- "\n"
- "int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen);\n"
- "int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen);\n"
- "\n"
--"ZMQ_Error zmq_send(ZMQ_Socket * this1, zmq_msg_t * msg2, int flags3);\n"
-+"ZMQ_Error zmq_sendmsg(ZMQ_Socket *, zmq_msg_t *, int);\n"
-+"\n"
-+"ZMQ_Error simple_zmq_send(ZMQ_Socket *, const char *, size_t, int);\n"
-+"\n"
-+"ZMQ_Error zmq_recvmsg(ZMQ_Socket *, zmq_msg_t *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_hwm(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_hwm(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_swap(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_swap(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_affinity(ZMQ_Socket *, uint64_t*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_affinity(ZMQ_Socket *, uint64_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_identity(ZMQ_Socket *, char *, size_t*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_identity(ZMQ_Socket *, const char *, size_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_subscribe(ZMQ_Socket *, const char *, size_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_unsubscribe(ZMQ_Socket *, const char *, size_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_rate(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_rate(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_recovery_ivl(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_recovery_ivl(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_mcast_loop(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_mcast_loop(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_sndbuf(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_sndbuf(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_rcvbuf(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_rcvbuf(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_rcvmore(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_fd(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_events(ZMQ_Socket *, int*);\n"
- "\n"
--"typedef ZMQ_Error (*simple_zmq_send_func)(ZMQ_Socket *sock, const char *data, size_t data_len, int flags);\n"
-+"ZMQ_Error lzmq_socket_type(ZMQ_Socket *, int*);\n"
- "\n"
--"ZMQ_Error zmq_recv(ZMQ_Socket * this1, zmq_msg_t * msg2, int flags3);\n"
-+"ZMQ_Error lzmq_socket_linger(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_linger(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_reconnect_ivl(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_reconnect_ivl(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_backlog(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_backlog(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_recovery_ivl_msec(ZMQ_Socket *, int64_t*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_recovery_ivl_msec(ZMQ_Socket *, int64_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_reconnect_ivl_max(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_reconnect_ivl_max(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_maxmsgsize(ZMQ_Socket *, int64_t*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_maxmsgsize(ZMQ_Socket *, int64_t);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_sndhwm(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_sndhwm(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_rcvhwm(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_rcvhwm(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_multicast_hops(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_multicast_hops(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_rcvtimeo(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_rcvtimeo(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_sndtimeo(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_sndtimeo(ZMQ_Socket *, int);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_ipv4only(ZMQ_Socket *, int*);\n"
-+"\n"
-+"ZMQ_Error lzmq_socket_set_ipv4only(ZMQ_Socket *, int);\n"
- "\n"
- "typedef int socket_t;\n"
- "typedef struct zmq_pollitem_t {\n"
-@@ -1031,7 +1933,12 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- " short revents;\n"
- "} zmq_pollitem_t;\n"
- "\n"
--"int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout);\n"
-+"int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock);\n"
-+"int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd);\n"
-+"int poller_get_free_item(ZMQ_Poller *poller);\n"
-+"int poller_poll(ZMQ_Poller *poller, long timeout);\n"
-+"void poller_remove_item(ZMQ_Poller *poller, int idx);\n"
-+"\n"
- "\n"
- "struct ZMQ_Poller {\n"
- " zmq_pollitem_t *items;\n"
-@@ -1041,616 +1948,823 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- " int len;\n"
- "};\n"
- "\n"
--"typedef int (*poller_find_sock_item_func)(ZMQ_Poller *poller, ZMQ_Socket *sock);\n"
-+"void poller_init(ZMQ_Poller *, unsigned int);\n"
- "\n"
--"typedef int (*poller_find_fd_item_func)(ZMQ_Poller *poller, socket_t fd);\n"
-+"void poller_cleanup(ZMQ_Poller *);\n"
- "\n"
--"typedef int (*poller_get_free_item_func)(ZMQ_Poller *poller);\n"
-+"ZMQ_Error poller_poll(ZMQ_Poller *, long);\n"
- "\n"
--"typedef int (*poller_poll_func)(ZMQ_Poller *poller, long timeout);\n"
-+"int poller_next_revents(ZMQ_Poller *, int*);\n"
- "\n"
--"typedef void (*poller_remove_item_func)(ZMQ_Poller *poller, int idx);\n"
-+"ZMQ_Error zmq_term(ZMQ_Ctx *);\n"
- "\n"
--"ZMQ_Error zmq_term(ZMQ_Ctx * this1);\n"
--"\n"
--"ZMQ_Socket * zmq_socket(ZMQ_Ctx * this1, int type2);\n"
-+"ZMQ_Socket * zmq_socket(ZMQ_Ctx *, int);\n"
- "\n"
- "ZMQ_StopWatch * zmq_stopwatch_start();\n"
- "\n"
--"unsigned long zmq_stopwatch_stop(ZMQ_StopWatch * this1);\n"
--"\n"
--"ZMQ_Ctx * zmq_init(int io_threads1);\n"
-+"unsigned long zmq_stopwatch_stop(ZMQ_StopWatch *);\n"
- "\n"
--"ZMQ_Error zmq_device(int device1, ZMQ_Socket * insock2, ZMQ_Socket * outsock3);\n"
-+"ZMQ_Ctx * zmq_init(int);\n"
- "\n"
--"ZMQ_StopWatch * zmq_stopwatch_start();\n"
-+"ZMQ_Error zmq_device(int, ZMQ_Socket *, ZMQ_Socket *);\n"
- "\n"
--"void zmq_sleep(int seconds_1);\n"
-+"void zmq_sleep(int);\n"
- "\n"
- "\n"
- "]]\n"
- "\n"
-+"REG_OBJECTS_AS_GLOBALS = false\n"
-+"local _obj_interfaces_ffi = {}\n"
- "local _pub = {}\n"
- "local _meth = {}\n"
-+"local _push = {}\n"
-+"local _obj_subs = {}\n"
- "for obj_name,mt in pairs(_priv) do\n"
--" if type(mt) == 'table' and mt.__index then\n"
--" _meth[obj_name] = mt.__index\n"
-+" if type(mt) == 'table' then\n"
-+" _obj_subs[obj_name] = {}\n"
-+" if mt.__index then\n"
-+" _meth[obj_name] = mt.__index\n"
-+" end\n"
- " end\n"
- "end\n"
--"_pub.zmq = _M\n"
- "for obj_name,pub in pairs(_M) do\n"
- " _pub[obj_name] = pub\n"
- "end\n"
- "\n"
--"\n"
--"local obj_type_zmq_msg_t_check\n"
--"local obj_type_zmq_msg_t_delete\n"
--"local obj_type_zmq_msg_t_push\n"
--"\n"
--"(function()\n"
--"local zmq_msg_t_mt = _priv.zmq_msg_t\n"
--"local zmq_msg_t_objects = setmetatable({}, { __mode = \"k\",\n"
--"__index = function(objects, ud_obj)\n"
--" return obj_simple_udata_to_cdata(objects, ud_obj, \"zmq_msg_t *\", zmq_msg_t_mt)\n"
--"end,\n"
--"})\n"
--"function obj_type_zmq_msg_t_check(ud_obj)\n"
--" return zmq_msg_t_objects[ud_obj]\n"
-+"--\n"
-+"-- CData Metatable access\n"
-+"--\n"
-+"local _ctypes = {}\n"
-+"local _type_names = {}\n"
-+"local _get_mt_key = {}\n"
-+"local _ctype_meta_map = {}\n"
-+"\n"
-+"local f_typeof = ffi.typeof\n"
-+"local function get_cdata_type_id(cdata)\n"
-+" return tonumber(f_typeof(cdata))\n"
- "end\n"
--"\n"
--"function obj_type_zmq_msg_t_delete(ud_obj)\n"
--" zmq_msg_t_objects[ud_obj] = nil\n"
--" return obj_simple_udata_luadelete(ud_obj, zmq_msg_t_mt)\n"
-+"local function get_cdata_mt(cdata)\n"
-+" return _ctype_meta_map[tonumber(f_typeof(cdata))]\n"
- "end\n"
- "\n"
--"local zmq_msg_t_sizeof = ffi.sizeof\"zmq_msg_t\"\n"
--"function obj_type_zmq_msg_t_push(c_obj)\n"
--" local ud_obj, cdata = obj_simple_udata_luapush(c_obj, zmq_msg_t_sizeof, zmq_msg_t_mt)\n"
--" zmq_msg_t_objects[ud_obj] = cdata\n"
--" return ud_obj\n"
-+"local function obj_register_ctype(name, ctype)\n"
-+" local obj_mt = _priv[name]\n"
-+" local obj_type = obj_mt['.type']\n"
-+" local obj_ctype = ffi.typeof(ctype)\n"
-+" local obj_type_id = tonumber(obj_ctype)\n"
-+" _ctypes[name] = obj_ctype\n"
-+" _type_names[name] = tostring(obj_ctype)\n"
-+" _ctype_meta_map[obj_type_id] = obj_mt\n"
-+" _ctype_meta_map[obj_mt] = obj_type_id\n"
-+" return obj_mt, obj_type, obj_ctype\n"
- "end\n"
--"end)()\n"
--"\n"
--"\n"
--"local obj_type_ZMQ_Socket_check\n"
--"local obj_type_ZMQ_Socket_delete\n"
--"local obj_type_ZMQ_Socket_push\n"
- "\n"
--"(function()\n"
--"local ZMQ_Socket_mt = _priv.ZMQ_Socket\n"
--"local ZMQ_Socket_objects = setmetatable({}, { __mode = \"k\",\n"
--"__index = function(objects, ud_obj)\n"
--" return obj_udata_to_cdata(objects, ud_obj, \"ZMQ_Socket *\", ZMQ_Socket_mt)\n"
--"end,\n"
--"})\n"
--"function obj_type_ZMQ_Socket_check(ud_obj)\n"
--" return ZMQ_Socket_objects[ud_obj]\n"
-+"--\n"
-+"-- Interfaces helper code.\n"
-+"--\n"
-+"local _obj_interfaces_key = \"obj_interfaces<1.0>_table_key\"\n"
-+"local _obj_interfaces_ud = reg_table[_obj_interfaces_key]\n"
-+"local _obj_interfaces_key_ffi = _obj_interfaces_key .. \"_LJ2_FFI\"\n"
-+"_obj_interfaces_ffi = reg_table[_obj_interfaces_key_ffi]\n"
-+"if not _obj_interfaces_ffi then\n"
-+" -- create missing interfaces table for FFI bindings.\n"
-+" _obj_interfaces_ffi = {}\n"
-+" reg_table[_obj_interfaces_key_ffi] = _obj_interfaces_ffi\n"
- "end\n"
- "\n"
--"function obj_type_ZMQ_Socket_delete(ud_obj)\n"
--" ZMQ_Socket_objects[ud_obj] = nil\n"
--" return obj_udata_luadelete_weak(ud_obj, ZMQ_Socket_mt)\n"
-+"local function obj_get_userdata_interface(if_name, expected_err)\n"
-+" local impls_ud = _obj_interfaces_ud[if_name]\n"
-+" if not impls_ud then\n"
-+" impls_ud = {}\n"
-+" _obj_interfaces_ud[if_name] = impls_ud\n"
-+" end\n"
-+" -- create cdata check function to be used by non-ffi bindings.\n"
-+" if not impls_ud.cdata then\n"
-+" function impls_ud.cdata(obj)\n"
-+" return assert(impls_ud[get_cdata_mt(obj)], expected_err)\n"
-+" end\n"
-+" end\n"
-+" return impls_ud\n"
- "end\n"
- "\n"
--"local ZMQ_Socket_type = ffi.cast(\"obj_type *\", ZMQ_Socket_mt[\".type\"])\n"
--"function obj_type_ZMQ_Socket_push(c_obj, flags)\n"
--" local ud_obj = obj_udata_luapush_weak(c_obj, ZMQ_Socket_mt, ZMQ_Socket_type, flags)\n"
--" ZMQ_Socket_objects[ud_obj] = c_obj\n"
--" return ud_obj\n"
-+"local function obj_get_interface_check(if_name, expected_err)\n"
-+" local impls_ffi = _obj_interfaces_ffi[if_name]\n"
-+" if not impls_ffi then\n"
-+" local if_type = ffi.typeof(if_name .. \" *\")\n"
-+" local impls_ud = obj_get_userdata_interface(if_name, expected_err)\n"
-+" -- create table for FFI-based interface implementations.\n"
-+" impls_ffi = setmetatable({}, {\n"
-+" __index = function(impls_ffi, mt)\n"
-+" local impl = impls_ud[mt]\n"
-+" if impl then\n"
-+" -- cast to cdata\n"
-+" impl = if_type(impl)\n"
-+" rawset(impls_ffi, mt, impl)\n"
-+" end\n"
-+" return impl\n"
-+" end})\n"
-+" _obj_interfaces_ffi[if_name] = impls_ffi\n"
-+"\n"
-+" -- create check function for this interface.\n"
-+" function impls_ffi.check(obj)\n"
-+" local impl\n"
-+" if type(obj) == 'cdata' then\n"
-+" impl = impls_ffi[get_cdata_type_id(obj)]\n"
-+" else\n"
-+" impl = impls_ud.userdata(impls_ffi, obj)\n"
-+" end\n"
-+" return assert(impl, expected_err)\n"
-+" end\n"
-+" end\n"
-+" return impls_ffi.check\n"
- "end\n"
--"end)()\n"
--"\n"
--"\n"
--"local obj_type_ZMQ_Poller_check\n"
--"local obj_type_ZMQ_Poller_delete\n"
--"local obj_type_ZMQ_Poller_push\n"
- "\n"
--"(function()\n"
--"local ZMQ_Poller_mt = _priv.ZMQ_Poller\n"
--"local ZMQ_Poller_objects = setmetatable({}, { __mode = \"k\",\n"
--"__index = function(objects, ud_obj)\n"
--" return obj_simple_udata_to_cdata(objects, ud_obj, \"ZMQ_Poller *\", ZMQ_Poller_mt)\n"
--"end,\n"
--"})\n"
--"function obj_type_ZMQ_Poller_check(ud_obj)\n"
--" return ZMQ_Poller_objects[ud_obj]\n"
-+"local function obj_register_interface(if_name, obj_name)\n"
-+" -- loopkup cdata id\n"
-+" local obj_mt = _priv[obj_name]\n"
-+" local obj_type_id = _ctype_meta_map[obj_mt]\n"
-+" local impl_meths = {}\n"
-+" local ffi_impls = _obj_interfaces_ffi[if_name]\n"
-+" ffi_impls[obj_type_id] = impl_meths\n"
-+" _meth[obj_name]['NOBJ_get_' .. if_name] = impl_meths\n"
-+" return impl_meths\n"
- "end\n"
- "\n"
--"function obj_type_ZMQ_Poller_delete(ud_obj)\n"
--" ZMQ_Poller_objects[ud_obj] = nil\n"
--" return obj_simple_udata_luadelete(ud_obj, ZMQ_Poller_mt)\n"
--"end\n"
- "\n"
--"local ZMQ_Poller_sizeof = ffi.sizeof\"ZMQ_Poller\"\n"
--"function obj_type_ZMQ_Poller_push(c_obj)\n"
--" local ud_obj, cdata = obj_simple_udata_luapush(c_obj, ZMQ_Poller_sizeof, ZMQ_Poller_mt)\n"
--" ZMQ_Poller_objects[ud_obj] = cdata\n"
--" return ud_obj\n"
--"end\n"
--"end)()\n"
-+"local obj_type_zmq_msg_t_check\n"
-+"local obj_type_zmq_msg_t_delete\n"
-+"local obj_type_zmq_msg_t_push\n"
- "\n"
-+"do\n"
-+" local obj_mt, obj_type, obj_ctype = obj_register_ctype(\"zmq_msg_t\", \"zmq_msg_t\")\n"
-+" local zmq_msg_t_sizeof = ffi.sizeof\"zmq_msg_t\"\n"
- "\n"
--"local obj_type_ZMQ_Ctx_check\n"
--"local obj_type_ZMQ_Ctx_delete\n"
--"local obj_type_ZMQ_Ctx_push\n"
-+" function obj_type_zmq_msg_t_check(obj)\n"
-+" return obj\n"
-+" end\n"
- "\n"
--"(function()\n"
--"local ZMQ_Ctx_mt = _priv.ZMQ_Ctx\n"
--"local ZMQ_Ctx_objects = setmetatable({}, { __mode = \"k\",\n"
--"__index = function(objects, ud_obj)\n"
--" return obj_udata_to_cdata(objects, ud_obj, \"ZMQ_Ctx *\", ZMQ_Ctx_mt)\n"
--"end,\n"
--"})\n"
--"function obj_type_ZMQ_Ctx_check(ud_obj)\n"
--" return ZMQ_Ctx_objects[ud_obj]\n"
--"end\n"
-+" function obj_type_zmq_msg_t_delete(obj)\n"
-+" return obj\n"
-+" end\n"
- "\n"
--"function obj_type_ZMQ_Ctx_delete(ud_obj)\n"
--" ZMQ_Ctx_objects[ud_obj] = nil\n"
--" return obj_udata_luadelete_weak(ud_obj, ZMQ_Ctx_mt)\n"
--"end\n"
-+" function obj_type_zmq_msg_t_push(obj)\n"
-+" return obj\n"
-+" end\n"
- "\n"
--"local ZMQ_Ctx_type = ffi.cast(\"obj_type *\", ZMQ_Ctx_mt[\".type\"])\n"
--"function obj_type_ZMQ_Ctx_push(c_obj, flags)\n"
--" local ud_obj = obj_udata_luapush_weak(c_obj, ZMQ_Ctx_mt, ZMQ_Ctx_type, flags)\n"
--" ZMQ_Ctx_objects[ud_obj] = c_obj\n"
--" return ud_obj\n"
--"end\n"
--"end)()\n"
-+" function obj_mt:__tostring()\n"
-+" return sformat(\"zmq_msg_t: %p\", self)\n"
-+" end\n"
- "\n"
-+" function obj_mt.__eq(val1, val2)\n"
-+" if not ffi.istype(obj_type, val2) then return false end\n"
-+" assert(ffi.istype(obj_type, val1), \"expected zmq_msg_t\")\n"
-+" return (C.memcmp(val1, val2, zmq_msg_t_sizeof) == 0)\n"
-+" end\n"
- "\n"
--"local obj_type_ZMQ_StopWatch_check\n"
--"local obj_type_ZMQ_StopWatch_delete\n"
--"local obj_type_ZMQ_StopWatch_push\n"
-+" -- type checking function for C API.\n"
-+" local function c_check(obj)\n"
-+" if ffi.istype(obj_type, obj) then return obj end\n"
-+" return nil\n"
-+" end\n"
-+" _priv[obj_type] = c_check\n"
-+" -- push function for C API.\n"
-+" reg_table[obj_type] = function(ptr)\n"
-+" local obj = obj_ctype()\n"
-+" ffi.copy(obj, ptr, zmq_msg_t_sizeof);\n"
-+" return obj\n"
-+" end\n"
- "\n"
--"(function()\n"
--"local ZMQ_StopWatch_mt = _priv.ZMQ_StopWatch\n"
--"local ZMQ_StopWatch_objects = setmetatable({}, { __mode = \"k\",\n"
--"__index = function(objects, ud_obj)\n"
--" return obj_udata_to_cdata(objects, ud_obj, \"ZMQ_StopWatch *\", ZMQ_StopWatch_mt)\n"
--"end,\n"
--"})\n"
--"function obj_type_ZMQ_StopWatch_check(ud_obj)\n"
--" return ZMQ_StopWatch_objects[ud_obj]\n"
-+" -- export check functions for use in other modules.\n"
-+" obj_mt.c_check = c_check\n"
-+" obj_mt.ffi_check = obj_type_zmq_msg_t_check\n"
- "end\n"
- "\n"
--"function obj_type_ZMQ_StopWatch_delete(ud_obj)\n"
--" ZMQ_StopWatch_objects[ud_obj] = nil\n"
--" return obj_udata_luadelete_weak(ud_obj, ZMQ_StopWatch_mt)\n"
--"end\n"
-+"\n", /* ----- CUT ----- */
-+"local obj_type_ZMQ_Socket_check\n"
-+"local obj_type_ZMQ_Socket_delete\n"
-+"local obj_type_ZMQ_Socket_push\n"
- "\n"
--"local ZMQ_StopWatch_type = ffi.cast(\"obj_type *\", ZMQ_StopWatch_mt[\".type\"])\n"
--"function obj_type_ZMQ_StopWatch_push(c_obj, flags)\n"
--" local ud_obj = obj_udata_luapush_weak(c_obj, ZMQ_StopWatch_mt, ZMQ_StopWatch_type, flags)\n"
--" ZMQ_StopWatch_objects[ud_obj] = c_obj\n"
--" return ud_obj\n"
--"end\n"
--"end)()\n"
-+"do\n"
-+" local obj_mt, obj_type, obj_ctype = obj_register_ctype(\"ZMQ_Socket\", \"ZMQ_Socket *\")\n"
-+"\n"
-+" function obj_type_ZMQ_Socket_check(ptr)\n"
-+" -- if ptr is nil or is the correct type, then just return it.\n"
-+" if not ptr or ffi.istype(obj_ctype, ptr) then return ptr end\n"
-+" -- check if it is a compatible type.\n"
-+" local ctype = tostring(ffi.typeof(ptr))\n"
-+" local bcaster = _obj_subs.ZMQ_Socket[ctype]\n"
-+" if bcaster then\n"
-+" return bcaster(ptr)\n"
-+" end\n"
-+" return error(\"Expected 'ZMQ_Socket *'\", 2)\n"
-+" end\n"
- "\n"
-+" function obj_type_ZMQ_Socket_delete(ptr)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" local flags = nobj_obj_flags[id]\n"
-+" if not flags then return nil, 0 end\n"
-+" ffi.gc(ptr, nil)\n"
-+" nobj_obj_flags[id] = nil\n"
-+" return ptr, flags\n"
-+" end\n"
- "\n"
--"local get_zmq_strerror = ffi.new(\"get_zmq_strerror_func\", _priv[\"get_zmq_strerror\"])\n"
-+" function obj_type_ZMQ_Socket_push(ptr, flags)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" -- check weak refs\n"
-+" if nobj_obj_flags[id] then return nobj_weak_objects[id] end\n"
- "\n"
--"local simple_zmq_send = ffi.new(\"simple_zmq_send_func\", _priv[\"simple_zmq_send\"])\n"
-+" if flags ~= 0 then\n"
-+" nobj_obj_flags[id] = flags\n"
-+" ffi.gc(ptr, obj_mt.__gc)\n"
-+" end\n"
-+" nobj_weak_objects[id] = ptr\n"
-+" return ptr\n"
-+" end\n"
- "\n"
--"local poller_find_sock_item = ffi.new(\"poller_find_sock_item_func\", _priv[\"poller_find_sock_item\"])\n"
-+" function obj_mt:__tostring()\n"
-+" return sformat(\"ZMQ_Socket: %p, flags=%d\", self, nobj_obj_flags[obj_ptr_to_id(self)] or 0)\n"
-+" end\n"
- "\n"
--"local poller_find_fd_item = ffi.new(\"poller_find_fd_item_func\", _priv[\"poller_find_fd_item\"])\n"
-+" -- type checking function for C API.\n"
-+" _priv[obj_type] = obj_type_ZMQ_Socket_check\n"
-+" -- push function for C API.\n"
-+" reg_table[obj_type] = function(ptr, flags)\n"
-+" return obj_type_ZMQ_Socket_push(ffi.cast(obj_ctype,ptr), flags)\n"
-+" end\n"
- "\n"
--"local poller_get_free_item = ffi.new(\"poller_get_free_item_func\", _priv[\"poller_get_free_item\"])\n"
-+" -- export check functions for use in other modules.\n"
-+" obj_mt.c_check = obj_type_ZMQ_Socket_check\n"
-+" obj_mt.ffi_check = obj_type_ZMQ_Socket_check\n"
-+"end\n"
- "\n"
--"local poller_poll = ffi.new(\"poller_poll_func\", _priv[\"poller_poll\"])\n"
- "\n"
--"local poller_remove_item = ffi.new(\"poller_remove_item_func\", _priv[\"poller_remove_item\"])\n"
-+"local obj_type_ZMQ_Poller_check\n"
-+"local obj_type_ZMQ_Poller_delete\n"
-+"local obj_type_ZMQ_Poller_push\n"
- "\n"
--"local os_lib_table = {\n"
--" [\"Windows\"] = \"libzmq\",\n"
--"}\n"
--"local C = ffi.load(os_lib_table[ffi.os] or \"zmq\")\n"
-+"do\n"
-+" local obj_mt, obj_type, obj_ctype = obj_register_ctype(\"ZMQ_Poller\", \"ZMQ_Poller\")\n"
-+" local ZMQ_Poller_sizeof = ffi.sizeof\"ZMQ_Poller\"\n"
- "\n"
--"local C_get_zmq_strerror = get_zmq_strerror\n"
--"-- make nicer wrapper for exported error function.\n"
--"local function get_zmq_strerror()\n"
--" return ffi.string(C_get_zmq_strerror())\n"
--"end\n"
-+" function obj_type_ZMQ_Poller_check(obj)\n"
-+" return obj\n"
-+" end\n"
- "\n"
--"local function error_code__ZMQ_Error__push(err)\n"
--" local err_str\n"
--" if(-1 == err) then\n"
--" err_str = get_zmq_strerror();\n"
-+" function obj_type_ZMQ_Poller_delete(obj)\n"
-+" return obj\n"
- " end\n"
- "\n"
--" return err_str\n"
-+" function obj_type_ZMQ_Poller_push(obj)\n"
-+" return obj\n"
-+" end\n"
-+"\n"
-+" function obj_mt:__tostring()\n"
-+" return sformat(\"ZMQ_Poller: %p\", self)\n"
-+" end\n"
-+"\n"
-+" function obj_mt.__eq(val1, val2)\n"
-+" if not ffi.istype(obj_type, val2) then return false end\n"
-+" assert(ffi.istype(obj_type, val1), \"expected ZMQ_Poller\")\n"
-+" return (C.memcmp(val1, val2, ZMQ_Poller_sizeof) == 0)\n"
-+" end\n"
-+"\n"
-+" -- type checking function for C API.\n"
-+" local function c_check(obj)\n"
-+" if ffi.istype(obj_type, obj) then return obj end\n"
-+" return nil\n"
-+" end\n"
-+" _priv[obj_type] = c_check\n"
-+" -- push function for C API.\n"
-+" reg_table[obj_type] = function(ptr)\n"
-+" local obj = obj_ctype()\n"
-+" ffi.copy(obj, ptr, ZMQ_Poller_sizeof);\n"
-+" return obj\n"
-+" end\n"
-+"\n"
-+" -- export check functions for use in other modules.\n"
-+" obj_mt.c_check = c_check\n"
-+" obj_mt.ffi_check = obj_type_ZMQ_Poller_check\n"
-+"end\n"
-+"\n"
-+"\n"
-+"local obj_type_ZMQ_Ctx_check\n"
-+"local obj_type_ZMQ_Ctx_delete\n"
-+"local obj_type_ZMQ_Ctx_push\n"
-+"\n"
-+"do\n"
-+" local obj_mt, obj_type, obj_ctype = obj_register_ctype(\"ZMQ_Ctx\", \"ZMQ_Ctx *\")\n"
-+"\n"
-+" function obj_type_ZMQ_Ctx_check(ptr)\n"
-+" -- if ptr is nil or is the correct type, then just return it.\n"
-+" if not ptr or ffi.istype(obj_ctype, ptr) then return ptr end\n"
-+" -- check if it is a compatible type.\n"
-+" local ctype = tostring(ffi.typeof(ptr))\n"
-+" local bcaster = _obj_subs.ZMQ_Ctx[ctype]\n"
-+" if bcaster then\n"
-+" return bcaster(ptr)\n"
-+" end\n"
-+" return error(\"Expected 'ZMQ_Ctx *'\", 2)\n"
-+" end\n"
-+"\n"
-+" function obj_type_ZMQ_Ctx_delete(ptr)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" local flags = nobj_obj_flags[id]\n"
-+" if not flags then return nil, 0 end\n"
-+" ffi.gc(ptr, nil)\n"
-+" nobj_obj_flags[id] = nil\n"
-+" return ptr, flags\n"
-+" end\n"
-+"\n"
-+" function obj_type_ZMQ_Ctx_push(ptr, flags)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" -- check weak refs\n"
-+" if nobj_obj_flags[id] then return nobj_weak_objects[id] end\n"
-+"\n"
-+" if flags ~= 0 then\n"
-+" nobj_obj_flags[id] = flags\n"
-+" ffi.gc(ptr, obj_mt.__gc)\n"
-+" end\n"
-+" nobj_weak_objects[id] = ptr\n"
-+" return ptr\n"
-+" end\n"
-+"\n"
-+" function obj_mt:__tostring()\n"
-+" return sformat(\"ZMQ_Ctx: %p, flags=%d\", self, nobj_obj_flags[obj_ptr_to_id(self)] or 0)\n"
-+" end\n"
-+"\n"
-+" -- type checking function for C API.\n"
-+" _priv[obj_type] = obj_type_ZMQ_Ctx_check\n"
-+" -- push function for C API.\n"
-+" reg_table[obj_type] = function(ptr, flags)\n"
-+" return obj_type_ZMQ_Ctx_push(ffi.cast(obj_ctype,ptr), flags)\n"
-+" end\n"
-+"\n"
-+" -- export check functions for use in other modules.\n"
-+" obj_mt.c_check = obj_type_ZMQ_Ctx_check\n"
-+" obj_mt.ffi_check = obj_type_ZMQ_Ctx_check\n"
-+"end\n"
-+"\n"
-+"\n"
-+"local obj_type_ZMQ_StopWatch_check\n"
-+"local obj_type_ZMQ_StopWatch_delete\n"
-+"local obj_type_ZMQ_StopWatch_push\n"
-+"\n"
-+"do\n"
-+" local obj_mt, obj_type, obj_ctype = obj_register_ctype(\"ZMQ_StopWatch\", \"ZMQ_StopWatch *\")\n"
-+"\n"
-+" function obj_type_ZMQ_StopWatch_check(ptr)\n"
-+" -- if ptr is nil or is the correct type, then just return it.\n"
-+" if not ptr or ffi.istype(obj_ctype, ptr) then return ptr end\n"
-+" -- check if it is a compatible type.\n"
-+" local ctype = tostring(ffi.typeof(ptr))\n"
-+" local bcaster = _obj_subs.ZMQ_StopWatch[ctype]\n"
-+" if bcaster then\n"
-+" return bcaster(ptr)\n"
-+" end\n"
-+" return error(\"Expected 'ZMQ_StopWatch *'\", 2)\n"
-+" end\n"
-+"\n"
-+" function obj_type_ZMQ_StopWatch_delete(ptr)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" local flags = nobj_obj_flags[id]\n"
-+" if not flags then return nil, 0 end\n"
-+" ffi.gc(ptr, nil)\n"
-+" nobj_obj_flags[id] = nil\n"
-+" return ptr, flags\n"
-+" end\n"
-+"\n"
-+" function obj_type_ZMQ_StopWatch_push(ptr, flags)\n"
-+" local id = obj_ptr_to_id(ptr)\n"
-+" -- check weak refs\n"
-+" if nobj_obj_flags[id] then return nobj_weak_objects[id] end\n"
-+"\n"
-+" if flags ~= 0 then\n"
-+" nobj_obj_flags[id] = flags\n"
-+" ffi.gc(ptr, obj_mt.__gc)\n"
-+" end\n"
-+" nobj_weak_objects[id] = ptr\n"
-+" return ptr\n"
-+" end\n"
-+"\n"
-+" function obj_mt:__tostring()\n"
-+" return sformat(\"ZMQ_StopWatch: %p, flags=%d\", self, nobj_obj_flags[obj_ptr_to_id(self)] or 0)\n"
-+" end\n"
-+"\n"
-+" -- type checking function for C API.\n"
-+" _priv[obj_type] = obj_type_ZMQ_StopWatch_check\n"
-+" -- push function for C API.\n"
-+" reg_table[obj_type] = function(ptr, flags)\n"
-+" return obj_type_ZMQ_StopWatch_push(ffi.cast(obj_ctype,ptr), flags)\n"
-+" end\n"
-+"\n"
-+" -- export check functions for use in other modules.\n"
-+" obj_mt.c_check = obj_type_ZMQ_StopWatch_check\n"
-+" obj_mt.ffi_check = obj_type_ZMQ_StopWatch_check\n"
-+"end\n"
-+"\n"
-+"\n"
-+"local obj_type_MutableBuffer_check =\n"
-+" obj_get_interface_check(\"MutableBufferIF\", \"Expected object with MutableBuffer interface\")\n"
-+"\n"
-+"local obj_type_Buffer_check =\n"
-+" obj_get_interface_check(\"BufferIF\", \"Expected object with Buffer interface\")\n"
-+"\n"
-+"local os_lib_table = {\n"
-+" [\"Windows\"] = \"libzmq\",\n"
-+"}\n"
-+"C = ffi_load(os_lib_table[ffi.os] or \"zmq\")\n"
-+"\n"
-+"\n"
-+"-- Start \"ZErrors\" FFI interface\n"
-+"-- End \"ZErrors\" FFI interface\n"
-+"\n"
-+"-- get ZErrors table to map errno to error name.\n"
-+"local ZError_names = _M.ZErrors\n"
-+"\n"
-+"local function get_zmq_strerror()\n"
-+" return ZError_names[C.zmq_errno()]\n"
-+"end\n"
-+"\n"
-+"local function error_code__ZMQ_Error__push(err)\n"
-+" local err_str\n"
-+" if(-1 == err) then\n"
-+" err_str = ZError_names[C.zmq_errno()]\n"
-+" end\n"
-+"\n"
-+" return err_str\n"
- "end\n"
- "\n"
- "\n"
- "-- Start \"zmq_msg_t\" FFI interface\n"
-+"-- method: init\n"
-+"function _pub.zmq_msg_t.init()\n"
-+" local self = ffi.new(\"zmq_msg_t\")\n"
-+" local rc_zmq_msg_init2 = 0\n"
-+" rc_zmq_msg_init2 = C.zmq_msg_init(self)\n"
-+" if (-1 == rc_zmq_msg_init2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_zmq_msg_init2)\n"
-+" end\n"
-+" return obj_type_zmq_msg_t_push(self)\n"
-+"end\n"
-+"register_default_constructor(_pub,\"zmq_msg_t\",_pub.zmq_msg_t.init)\n"
-+"\n"
-+"-- method: init_size\n"
-+"function _pub.zmq_msg_t.init_size(size1)\n"
-+" \n"
-+" local self = ffi.new(\"zmq_msg_t\")\n"
-+" local rc_zmq_msg_init_size2 = 0\n"
-+" rc_zmq_msg_init_size2 = C.zmq_msg_init_size(self, size1)\n"
-+" if (-1 == rc_zmq_msg_init_size2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_zmq_msg_init_size2)\n"
-+" end\n"
-+" return obj_type_zmq_msg_t_push(self)\n"
-+"end\n"
-+"\n"
-+"-- method: init_data\n"
-+"function _pub.zmq_msg_t.init_data(data1)\n"
-+" local data_len1 = #data1\n"
-+" local self = ffi.new(\"zmq_msg_t\")\n"
-+" local err2 = 0\n"
-+" err2 = C.zmq_msg_init_size(self, data_len1)\n"
-+" if(0 == err2) then\n"
-+" -- fill message\n"
-+" ffi.copy(C.zmq_msg_data(self), data1, data_len1)\n"
-+" end\n"
-+"\n"
-+" if (-1 == err2) then\n"
-+" return nil,error_code__ZMQ_Error__push(err2)\n"
-+" end\n"
-+" return obj_type_zmq_msg_t_push(self)\n"
-+"end\n"
-+"\n"
- "-- method: __gc\n"
- "function _priv.zmq_msg_t.__gc(self)\n"
--" local this1,this_flags1 = obj_type_zmq_msg_t_delete(self)\n"
--" if(band(this_flags1,OBJ_UDATA_FLAG_OWN) == 0) then return end\n"
--" local rc_zmq_msg_close1\n"
--" rc_zmq_msg_close1 = C.zmq_msg_close(this1)\n"
-+" local self = obj_type_zmq_msg_t_delete(self)\n"
-+" if not self then return end\n"
-+" local rc_zmq_msg_close1 = 0\n"
-+" rc_zmq_msg_close1 = C.zmq_msg_close(self)\n"
- " -- check for error.\n"
--" local rc_zmq_msg_close1_err\n"
- " if (-1 == rc_zmq_msg_close1) then\n"
--" rc_zmq_msg_close1_err = error_code__ZMQ_Error__push(rc_zmq_msg_close1)\n"
--" rc_zmq_msg_close1 = nil\n"
--" else\n"
--" rc_zmq_msg_close1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_msg_close1)\n"
- " end\n"
--" return rc_zmq_msg_close1, rc_zmq_msg_close1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: close\n"
- "function _meth.zmq_msg_t.close(self)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
--" local rc_zmq_msg_close1\n"
--" rc_zmq_msg_close1 = C.zmq_msg_close(this1)\n"
-+" \n"
-+" local rc_zmq_msg_close1 = 0\n"
-+" rc_zmq_msg_close1 = C.zmq_msg_close(self)\n"
- " -- check for error.\n"
--" local rc_zmq_msg_close1_err\n"
- " if (-1 == rc_zmq_msg_close1) then\n"
--" rc_zmq_msg_close1_err = error_code__ZMQ_Error__push(rc_zmq_msg_close1)\n"
--" rc_zmq_msg_close1 = nil\n"
--" else\n"
--" rc_zmq_msg_close1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_msg_close1)\n"
- " end\n"
--" return rc_zmq_msg_close1, rc_zmq_msg_close1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: move\n"
- "function _meth.zmq_msg_t.move(self, src2)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
--" src2 = obj_type_zmq_msg_t_check(src2)\n"
--" local rc_zmq_msg_move1\n"
--" rc_zmq_msg_move1 = C.zmq_msg_move(this1, src2)\n"
-+" \n"
-+" \n"
-+" local rc_zmq_msg_move1 = 0\n"
-+" rc_zmq_msg_move1 = C.zmq_msg_move(self, src2)\n"
- " -- check for error.\n"
--" local rc_zmq_msg_move1_err\n"
- " if (-1 == rc_zmq_msg_move1) then\n"
--" rc_zmq_msg_move1_err = error_code__ZMQ_Error__push(rc_zmq_msg_move1)\n"
--" rc_zmq_msg_move1 = nil\n"
--" else\n"
--" rc_zmq_msg_move1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_msg_move1)\n"
- " end\n"
--" return rc_zmq_msg_move1, rc_zmq_msg_move1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: copy\n"
- "function _meth.zmq_msg_t.copy(self, src2)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
--" src2 = obj_type_zmq_msg_t_check(src2)\n"
--" local rc_zmq_msg_copy1\n"
--" rc_zmq_msg_copy1 = C.zmq_msg_copy(this1, src2)\n"
-+" \n"
-+" \n"
-+" local rc_zmq_msg_copy1 = 0\n"
-+" rc_zmq_msg_copy1 = C.zmq_msg_copy(self, src2)\n"
- " -- check for error.\n"
--" local rc_zmq_msg_copy1_err\n"
- " if (-1 == rc_zmq_msg_copy1) then\n"
--" rc_zmq_msg_copy1_err = error_code__ZMQ_Error__push(rc_zmq_msg_copy1)\n"
--" rc_zmq_msg_copy1 = nil\n"
--" else\n"
--" rc_zmq_msg_copy1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_msg_copy1)\n"
- " end\n"
--" return rc_zmq_msg_copy1, rc_zmq_msg_copy1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: set_data\n"
- "function _meth.zmq_msg_t.set_data(self, data2)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
-+" \n"
- " local data_len2 = #data2\n"
--" local err1\n"
-+" local err1 = 0\n"
- " -- check message data size.\n"
--" if (C.zmq_msg_size(this1) ~= data_len2) then\n"
-+" if (C.zmq_msg_size(self) ~= data_len2) then\n"
- " -- need to resize message.\n"
--" C.zmq_msg_close(this1); -- close old message, to free old data.\n"
--" err1 = C.zmq_msg_init_size(this1, data_len2); -- re-initialize message.\n"
-+" C.zmq_msg_close(self); -- close old message, to free old data.\n"
-+" err1 = C.zmq_msg_init_size(self, data_len2); -- re-initialize message.\n"
- " if (0 ~= err1) then\n"
- " error(\"set_data() failed: \" .. get_zmq_strerror());\n"
- " end\n"
- " end\n"
- " -- copy data into message\n"
--" ffi.copy(C.zmq_msg_data(this1), data2, data_len2);\n"
-+" ffi.copy(C.zmq_msg_data(self), data2, data_len2);\n"
- "\n"
- " -- check for error.\n"
--" local err1_err\n"
- " if (-1 == err1) then\n"
--" err1_err = error_code__ZMQ_Error__push(err1)\n"
--" err1 = nil\n"
--" else\n"
--" err1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(err1)\n"
- " end\n"
--" return err1, err1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: data\n"
- "function _meth.zmq_msg_t.data(self)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
-+" \n"
- " local rc_zmq_msg_data1\n"
--" rc_zmq_msg_data1 = C.zmq_msg_data(this1)\n"
--" rc_zmq_msg_data1 = rc_zmq_msg_data1\n"
-+" rc_zmq_msg_data1 = C.zmq_msg_data(self)\n"
- " return rc_zmq_msg_data1\n"
- "end\n"
- "\n"
- "-- method: set_size\n"
- "function _meth.zmq_msg_t.set_size(self, size2)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
- " \n"
--" local err1\n"
-+" \n"
-+" local err1 = 0\n"
- " -- check message data size.\n"
--" if (C.zmq_msg_size(this1) ~= size2) then\n"
-+" if (C.zmq_msg_size(self) ~= size2) then\n"
- " -- need to resize message.\n"
--" C.zmq_msg_close(this1); -- close old message, to free old data.\n"
--" err1 = C.zmq_msg_init_size(this1, size2); -- re-initialize message.\n"
-+" C.zmq_msg_close(self); -- close old message, to free old data.\n"
-+" err1 = C.zmq_msg_init_size(self, size2); -- re-initialize message.\n"
- " if (0 ~= err1) then\n"
- " error(\"set_size() failed: \" .. get_zmq_strerror());\n"
- " end\n"
- " end\n"
- "\n"
- " -- check for error.\n"
--" local err1_err\n"
- " if (-1 == err1) then\n"
--" err1_err = error_code__ZMQ_Error__push(err1)\n"
--" err1 = nil\n"
--" else\n"
--" err1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(err1)\n"
- " end\n"
--" return err1, err1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: size\n"
- "function _meth.zmq_msg_t.size(self)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
--" local rc_zmq_msg_size1\n"
--" rc_zmq_msg_size1 = C.zmq_msg_size(this1)\n"
--" rc_zmq_msg_size1 = rc_zmq_msg_size1\n"
--" return rc_zmq_msg_size1\n"
-+" \n"
-+" local size1 = 0\n"
-+" size1 = C.zmq_msg_size(self)\n"
-+" return tonumber(size1)\n"
- "end\n"
- "\n"
- "-- method: __tostring\n"
- "function _priv.zmq_msg_t.__tostring(self)\n"
--" local this1 = obj_type_zmq_msg_t_check(self)\n"
-+" \n"
- " local data_len1 = 0\n"
- " local data1\n"
--" data1 = C.zmq_msg_data(this1);\n"
--" data_len1 = C.zmq_msg_size(this1);\n"
-+" data1 = C.zmq_msg_data(self);\n"
-+" data_len1 = C.zmq_msg_size(self);\n"
-+"\n"
-+" return ffi_string_len(data1,data_len1)\n"
-+"end\n"
-+"\n"
-+"-- zmq_msg_t implements Buffer interface\n"
-+"do\n"
-+" local impl_meths = obj_register_interface(\"BufferIF\", \"zmq_msg_t\")\n"
-+"-- Buffer interface method const_data\n"
-+"impl_meths.const_data = C.zmq_msg_data\n"
-+"-- Buffer interface method get_size\n"
-+"impl_meths.get_size = C.zmq_msg_size\n"
-+"end\n"
- "\n"
--" data1 = ((nil ~= data1) and ffi.string(data1,data_len1))\n"
--" return data1\n"
-+"-- zmq_msg_t implements MutableBuffer interface\n"
-+"do\n"
-+" local impl_meths = obj_register_interface(\"MutableBufferIF\", \"zmq_msg_t\")\n"
-+"-- MutableBuffer interface method data\n"
-+"impl_meths.data = C.zmq_msg_data\n"
-+"-- MutableBuffer interface method get_size\n"
-+"impl_meths.get_size = C.zmq_msg_size\n"
- "end\n"
- "\n"
-+"_push.zmq_msg_t = obj_type_zmq_msg_t_push\n"
-+"ffi.metatype(\"zmq_msg_t\", _priv.zmq_msg_t)\n"
- "-- End \"zmq_msg_t\" FFI interface\n"
- "\n"
- "\n"
- "-- Start \"ZMQ_Socket\" FFI interface\n"
- "-- method: close\n"
- "function _meth.ZMQ_Socket.close(self)\n"
--" local this1,this_flags1 = obj_type_ZMQ_Socket_delete(self)\n"
--" if(band(this_flags1,OBJ_UDATA_FLAG_OWN) == 0) then return end\n"
--" local rc_zmq_close1\n"
--" rc_zmq_close1 = C.zmq_close(this1)\n"
-+" local self,this_flags1 = obj_type_ZMQ_Socket_delete(self)\n"
-+" if not self then return end\n"
-+" local rc_zmq_close1 = 0\n"
-+" rc_zmq_close1 = C.zmq_close(self)\n"
- " -- check for error.\n"
--" local rc_zmq_close1_err\n"
- " if (-1 == rc_zmq_close1) then\n"
--" rc_zmq_close1_err = error_code__ZMQ_Error__push(rc_zmq_close1)\n"
--" rc_zmq_close1 = nil\n"
--" else\n"
--" rc_zmq_close1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_close1)\n"
- " end\n"
--" return rc_zmq_close1, rc_zmq_close1_err\n"
-+" return true\n"
- "end\n"
-+"_priv.ZMQ_Socket.__gc = _meth.ZMQ_Socket.close\n"
- "\n"
- "-- method: bind\n"
- "function _meth.ZMQ_Socket.bind(self, addr2)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
-+" \n"
- " local addr_len2 = #addr2\n"
--" local rc_zmq_bind1\n"
--" rc_zmq_bind1 = C.zmq_bind(this1, addr2)\n"
-+" local rc_zmq_bind1 = 0\n"
-+" rc_zmq_bind1 = C.zmq_bind(self, addr2)\n"
- " -- check for error.\n"
--" local rc_zmq_bind1_err\n"
- " if (-1 == rc_zmq_bind1) then\n"
--" rc_zmq_bind1_err = error_code__ZMQ_Error__push(rc_zmq_bind1)\n"
--" rc_zmq_bind1 = nil\n"
--" else\n"
--" rc_zmq_bind1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_bind1)\n"
- " end\n"
--" return rc_zmq_bind1, rc_zmq_bind1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: connect\n"
- "function _meth.ZMQ_Socket.connect(self, addr2)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
-+" \n"
- " local addr_len2 = #addr2\n"
--" local rc_zmq_connect1\n"
--" rc_zmq_connect1 = C.zmq_connect(this1, addr2)\n"
-+" local rc_zmq_connect1 = 0\n"
-+" rc_zmq_connect1 = C.zmq_connect(self, addr2)\n"
- " -- check for error.\n"
--" local rc_zmq_connect1_err\n"
- " if (-1 == rc_zmq_connect1) then\n"
--" rc_zmq_connect1_err = error_code__ZMQ_Error__push(rc_zmq_connect1)\n"
--" rc_zmq_connect1 = nil\n"
--" else\n"
--" rc_zmq_connect1 = true\n"
--" end\n"
--" return rc_zmq_connect1, rc_zmq_connect1_err\n"
--"end\n"
--"\n"
--"local option_types = {\n"
--"[zmq.HWM] = 'uint64_t[1]',\n"
--"[zmq.SWAP] = 'int64_t[1]',\n"
--"[zmq.AFFINITY] = 'uint64_t[1]',\n"
--"[zmq.IDENTITY] = 'string',\n"
--"[zmq.SUBSCRIBE] = 'string',\n"
--"[zmq.UNSUBSCRIBE] = 'string',\n"
--"[zmq.RATE] = 'int64_t[1]',\n"
--"[zmq.RECOVERY_IVL] = 'int64_t[1]',\n"
--"[zmq.MCAST_LOOP] = 'int64_t[1]',\n"
--"[zmq.SNDBUF] = 'uint64_t[1]',\n"
--"[zmq.RCVBUF] = 'uint64_t[1]',\n"
--"[zmq.RCVMORE] = 'int64_t[1]',\n"
--"[zmq.FD] = 'int[1]',\n"
--"[zmq.EVENTS] = 'uint32_t[1]',\n"
--"[zmq.TYPE] = 'int[1]',\n"
--"[zmq.LINGER] = 'int[1]',\n"
--"[zmq.RECONNECT_IVL] = 'int[1]',\n"
--"[zmq.BACKLOG] = 'int[1]',\n"
--"}\n"
--"local option_len = {}\n"
--"local option_tmps = {}\n"
--"for k,v in pairs(option_types) do\n"
--" if v ~= 'string' then\n"
--" option_len[k] = ffi.sizeof(v)\n"
--" option_tmps[k] = ffi.new(v, 0)\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_connect1)\n"
- " end\n"
-+" return true\n"
-+"end\n"
-+"\n"
-+"local option_gets = {}\n"
-+"local option_sets = {}\n"
-+"\n"
-+"do\n"
-+" local opt_name\n"
-+" local methods = _meth.ZMQ_Socket\n"
-+" setmetatable(option_gets,{__index = function(tab,opt)\n"
-+" local opt_name = opt_name[opt]\n"
-+" if not opt_name then return nil end\n"
-+" local method = methods[opt_name]\n"
-+" rawset(tab, opt, method)\n"
-+" return method\n"
-+" end})\n"
-+" setmetatable(option_sets,{__index = function(tab,opt)\n"
-+" local opt_name = opt_name[opt]\n"
-+" if not opt_name then return nil end\n"
-+" local method = methods['set_' .. opt_name] or methods[opt_name]\n"
-+" rawset(tab, opt, method)\n"
-+" return method\n"
-+" end})\n"
-+" opt_name = {\n"
-+" [1] = 'hwm',\n"
-+" [3] = 'swap',\n"
-+" [4] = 'affinity',\n"
-+" [5] = 'identity',\n"
-+" [6] = 'subscribe',\n"
-+" [7] = 'unsubscribe',\n"
-+" [8] = 'rate',\n"
-+" [9] = 'recovery_ivl',\n"
-+" [10] = 'mcast_loop',\n"
-+" [11] = 'sndbuf',\n"
-+" [12] = 'rcvbuf',\n"
-+" [13] = 'rcvmore',\n"
-+" [14] = 'fd',\n"
-+" [15] = 'events',\n"
-+" [16] = 'type',\n"
-+" [17] = 'linger',\n"
-+" [18] = 'reconnect_ivl',\n"
-+" [19] = 'backlog',\n"
-+" [20] = 'recovery_ivl_msec',\n"
-+" [21] = 'reconnect_ivl_max',\n"
-+" [27] = 'rcvtimeo',\n"
-+" [28] = 'sndtimeo',\n"
-+" [22] = 'maxmsgsize',\n"
-+" [23] = 'sndhwm',\n"
-+" [24] = 'rcvhwm',\n"
-+" [25] = 'multicast_hops',\n"
-+" [31] = 'ipv4only',\n"
-+"}\n"
- "end\n"
- "\n"
- "\n"
- "-- method: setopt\n"
- "function _meth.ZMQ_Socket.setopt(self, opt2, val3)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
--" \n"
--" local err1\n"
--" local ctype = option_types[opt2]\n"
--" local tval\n"
--" local tval_len = 0\n"
--" if ctype == 'string' then\n"
--" tval = tostring(val3)\n"
--" tval_len = #val3\n"
-+" \n"
-+" \n"
-+" local err1 = 0\n"
-+" local set = option_sets[opt2]\n"
-+" if set then\n"
-+" return set(self,val3)\n"
- " else\n"
--" tval = option_tmps[opt2]\n"
--" tval[0] = val3\n"
--" tval_len = option_len[opt2]\n"
-+" error(\"Invalid socket option.\")\n"
- " end\n"
--" err1 = C.zmq_setsockopt(this1, opt2, tval, tval_len)\n"
- "\n"
- " -- check for error.\n"
--" local err1_err\n"
- " if (-1 == err1) then\n"
--" err1_err = error_code__ZMQ_Error__push(err1)\n"
--" err1 = nil\n"
--" else\n"
--" err1 = true\n"
-+" return nil, error_code__ZMQ_Error__push(err1)\n"
- " end\n"
--" return err1, err1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "local tmp_val_len = ffi.new('size_t[1]', 4)\n"
- "\n"
- "-- method: getopt\n"
- "function _meth.ZMQ_Socket.getopt(self, opt2)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
-+" \n"
- " \n"
- " local val1\n"
--" local err2\n"
--" local ctype = option_types[opt2]\n"
--" local val\n"
--" local val_len = tmp_val_len\n"
--" if ctype == 'string' then\n"
--" val_len[0] = 255\n"
--" val = ffi.new('uint8_t[?]', val_len[0])\n"
--" ffi.fill(val, val_len[0])\n"
-+" local err2 = 0\n"
-+" local get = option_gets[opt2]\n"
-+" if get then\n", /* ----- CUT ----- */
-+" return get(self)\n"
- " else\n"
--" val = option_tmps[opt2]\n"
--" val[0] = 0\n"
--" val_len[0] = option_len[opt2]\n"
--" end\n"
--" err2 = C.zmq_getsockopt(this1, opt2, val, val_len)\n"
--" if err2 == 0 then\n"
--" if ctype == 'string' then\n"
--" val_len = val_len[0]\n"
--" return ffi.string(val, val_len)\n"
--" else\n"
--" return tonumber(val[0])\n"
--" end\n"
-+" error(\"Invalid socket option.\")\n"
- " end\n"
- "\n"
--" err2 = error_code__ZMQ_Error__push(err2)\n"
--" return val1, err2\n"
--"end\n"
--"\n"
--"-- temp. values for 'events' function.\n"
--"local events_tmp = ffi.new('uint32_t[1]', 0)\n"
--"local events_tmp_size = ffi.sizeof('uint32_t')\n"
--"local events_tmp_len = ffi.new('size_t[1]', events_tmp_size)\n"
--"local ZMQ_EVENTS = _M.EVENTS\n"
--"\n"
--"-- method: events\n"
--"function _meth.ZMQ_Socket.events(self)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
--" local events1\n"
--" local err2\n"
--" events_tmp_len[0] = events_tmp_size\n"
--" err2 = C.zmq_getsockopt(this1, ZMQ_EVENTS, events_tmp, events_tmp_len);\n"
--" events1 = events_tmp[0]\n"
--"\n"
--" if not (-1 == err2) then\n"
--" events1 = events1\n"
--" else\n"
--" events1 = nil\n"
--" end\n"
--" err2 = error_code__ZMQ_Error__push(err2)\n"
--" return events1, err2\n"
-+" return val1\n"
- "end\n"
- "\n"
- "-- method: send_msg\n"
- "function _meth.ZMQ_Socket.send_msg(self, msg2, flags3)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
--" msg2 = obj_type_zmq_msg_t_check(msg2)\n"
--" flags3 = flags3 or 0\n"
--" local rc_zmq_send1\n"
--" rc_zmq_send1 = C.zmq_send(this1, msg2, flags3)\n"
-+" \n"
-+" \n"
-+" flags3 = flags3 or 0\n"
-+" local rc_zmq_sendmsg1 = 0\n"
-+" rc_zmq_sendmsg1 = C.zmq_sendmsg(self, msg2, flags3)\n"
- " -- check for error.\n"
--" local rc_zmq_send1_err\n"
--" if (-1 == rc_zmq_send1) then\n"
--" rc_zmq_send1_err = error_code__ZMQ_Error__push(rc_zmq_send1)\n"
--" rc_zmq_send1 = nil\n"
--" else\n"
--" rc_zmq_send1 = true\n"
-+" if (-1 == rc_zmq_sendmsg1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_sendmsg1)\n"
- " end\n"
--" return rc_zmq_send1, rc_zmq_send1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: send\n"
- "function _meth.ZMQ_Socket.send(self, data2, flags3)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
-+" \n"
- " local data_len2 = #data2\n"
--" flags3 = flags3 or 0\n"
--" local err1\n"
--" err1 = simple_zmq_send(this1, data2, data_len2, flags3);\n"
--"\n"
-+" flags3 = flags3 or 0\n"
-+" local rc_simple_zmq_send1 = 0\n"
-+" rc_simple_zmq_send1 = Cmod.simple_zmq_send(self, data2, data_len2, flags3)\n"
- " -- check for error.\n"
--" local err1_err\n"
--" if (-1 == err1) then\n"
--" err1_err = error_code__ZMQ_Error__push(err1)\n"
--" err1 = nil\n"
--" else\n"
--" err1 = true\n"
-+" if (-1 == rc_simple_zmq_send1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_simple_zmq_send1)\n"
- " end\n"
--" return err1, err1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "-- method: recv_msg\n"
- "function _meth.ZMQ_Socket.recv_msg(self, msg2, flags3)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
--" msg2 = obj_type_zmq_msg_t_check(msg2)\n"
--" flags3 = flags3 or 0\n"
--" local rc_zmq_recv1\n"
--" rc_zmq_recv1 = C.zmq_recv(this1, msg2, flags3)\n"
-+" \n"
-+" \n"
-+" flags3 = flags3 or 0\n"
-+" local rc_zmq_recvmsg1 = 0\n"
-+" rc_zmq_recvmsg1 = C.zmq_recvmsg(self, msg2, flags3)\n"
- " -- check for error.\n"
--" local rc_zmq_recv1_err\n"
--" if (-1 == rc_zmq_recv1) then\n"
--" rc_zmq_recv1_err = error_code__ZMQ_Error__push(rc_zmq_recv1)\n"
--" rc_zmq_recv1 = nil\n"
--" else\n"
--" rc_zmq_recv1 = true\n"
-+" if (-1 == rc_zmq_recvmsg1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_recvmsg1)\n"
- " end\n"
--" return rc_zmq_recv1, rc_zmq_recv1_err\n"
-+" return true\n"
- "end\n"
- "\n"
- "local tmp_msg = ffi.new('zmq_msg_t')\n"
- "\n"
- "-- method: recv\n"
- "function _meth.ZMQ_Socket.recv(self, flags2)\n"
--" local this1 = obj_type_ZMQ_Socket_check(self)\n"
--" flags2 = flags2 or 0\n"
-+" \n"
-+" flags2 = flags2 or 0\n"
- " local data_len1 = 0\n"
- " local data1\n"
--" local err2\n"
-+" local err2 = 0\n"
- " local msg = tmp_msg\n"
- " -- initialize blank message.\n"
- " if C.zmq_msg_init(msg) < 0 then\n"
-@@ -1658,1106 +2772,3462 @@ static const char zmq_ffi_lua_code[] = "local error = error\n"
- " end\n"
- "\n"
- " -- receive message\n"
--" err2 = C.zmq_recv(this1, msg, flags2)\n"
--" if 0 == err2 then\n"
-+" err2 = C.zmq_recvmsg(self, msg, flags2)\n"
-+" if err2 >= 0 then\n"
- " local data = ffi.string(C.zmq_msg_data(msg), C.zmq_msg_size(msg))\n"
- " -- close message\n"
- " C.zmq_msg_close(msg)\n"
- " return data\n"
- " end\n"
- "\n"
--" if not (-1 == err2) then\n"
--" data1 = ((nil ~= data1) and ffi.string(data1,data_len1))\n"
--" else\n"
--" data1 = nil\n"
-+" if (-1 == err2) then\n"
-+" return nil,error_code__ZMQ_Error__push(err2)\n"
- " end\n"
--" err2 = error_code__ZMQ_Error__push(err2)\n"
- " -- close message\n"
- " C.zmq_msg_close(msg)\n"
- "\n"
--" return data1, err2\n"
-+" return ffi_string_len(data1,data_len1)\n"
- "end\n"
- "\n"
--"-- End \"ZMQ_Socket\" FFI interface\n"
--"\n"
--"\n"
--"-- Start \"ZMQ_Poller\" FFI interface\n"
--"-- method: poll\n"
--"function _meth.ZMQ_Poller.poll(self, timeout2)\n"
--" local this1 = obj_type_ZMQ_Poller_check(self)\n"
-+"do\n"
-+" local hwm_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: hwm\n"
-+"if (_meth.ZMQ_Socket.hwm) then\n"
-+"function _meth.ZMQ_Socket.hwm(self)\n"
- " \n"
--" local err1\n"
--" -- poll for events\n"
--" err1 = poller_poll(this1, timeout2)\n"
--" if(err1 > 0) then\n"
--" this1.next = 0\n"
--" else\n"
--" this1.next = -1\n"
--" end\n"
-+" local value1 = hwm_value_tmp\n"
-+" local rc_lzmq_socket_hwm2 = 0\n"
-+" rc_lzmq_socket_hwm2 = Cmod.lzmq_socket_hwm(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_hwm2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_hwm2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
- "\n"
-+"-- method: set_hwm\n"
-+"if (_meth.ZMQ_Socket.set_hwm) then\n"
-+"function _meth.ZMQ_Socket.set_hwm(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_hwm1 = 0\n"
-+" rc_lzmq_socket_set_hwm1 = Cmod.lzmq_socket_set_hwm(self, value2)\n"
- " -- check for error.\n"
--" local err1_err\n"
--" if (-1 == err1) then\n"
--" err1_err = error_code__ZMQ_Error__push(err1)\n"
--" err1 = nil\n"
--" else\n"
--" err1 = true\n"
--" end\n"
--" return err1, err1_err\n"
--"end\n"
--"\n"
--"-- method: next_revents\n"
--"function _meth.ZMQ_Poller.next_revents(self)\n"
--" local this1 = obj_type_ZMQ_Poller_check(self)\n"
--" local sock1\n"
--" local revents2\n"
--" local sock\n"
--" local idx = this1.next\n"
--" if (idx < 0) then return nil, -1 end\n"
--" local count = this1.count\n"
--" -- find next item with pending events.\n"
--" while (idx < count and this1.items[idx].revents == 0) do\n"
--" idx = idx + 1\n"
--" if (idx >= count) then\n"
--" idx = -1\n"
--" break\n"
--" end\n"
--" end\n"
--" -- did we find a pending event?\n"
--" if(idx >= 0) then\n"
--" -- push the event's sock/fd.\n"
--" if(this1.items[idx].socket ~= nil) then\n"
--" sock = obj_type_ZMQ_Socket_push(this1.items[idx].socket, 0)\n"
--" else\n"
--" sock = tonumber(this1.items[idx].fd)\n"
--" end\n"
--" revents2 = this1.items[idx].revents\n"
--" -- is this the last event.\n"
--" idx = idx + 1\n"
--" if (idx >= count) then\n"
--" idx = -1\n"
--" end\n"
--" this1.next = idx\n"
--" return sock, revents2\n"
--" end\n"
--" this1.next = idx\n"
--"\n"
--" revents2 = revents2\n"
--" return sock1, revents2\n"
-+" if (-1 == rc_lzmq_socket_set_hwm1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_hwm1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: count\n"
--"function _meth.ZMQ_Poller.count(self)\n"
--" local this1 = obj_type_ZMQ_Poller_check(self)\n"
--" local count1\n"
--" count1 = this1.count;\n"
--"\n"
--" count1 = count1\n"
--" return count1\n"
-+"do\n"
-+" local swap_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: swap\n"
-+"if (_meth.ZMQ_Socket.swap) then\n"
-+"function _meth.ZMQ_Socket.swap(self)\n"
-+" \n"
-+" local value1 = swap_value_tmp\n"
-+" local rc_lzmq_socket_swap2 = 0\n"
-+" rc_lzmq_socket_swap2 = Cmod.lzmq_socket_swap(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_swap2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_swap2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
- "end\n"
- "\n"
--"-- End \"ZMQ_Poller\" FFI interface\n"
-+"-- method: set_swap\n"
-+"if (_meth.ZMQ_Socket.set_swap) then\n"
-+"function _meth.ZMQ_Socket.set_swap(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_swap1 = 0\n"
-+" rc_lzmq_socket_set_swap1 = Cmod.lzmq_socket_set_swap(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_swap1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_swap1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
- "\n"
-+"do\n"
-+" local affinity_value_tmp = ffi.new(\"uint64_t[1]\")\n"
-+"-- method: affinity\n"
-+"if (_meth.ZMQ_Socket.affinity) then\n"
-+"function _meth.ZMQ_Socket.affinity(self)\n"
-+" \n"
-+" local value1 = affinity_value_tmp\n"
-+" local rc_lzmq_socket_affinity2 = 0\n"
-+" rc_lzmq_socket_affinity2 = Cmod.lzmq_socket_affinity(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_affinity2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_affinity2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
- "\n"
--"-- Start \"ZMQ_Ctx\" FFI interface\n"
--"-- method: term\n"
--"function _meth.ZMQ_Ctx.term(self)\n"
--" local this1,this_flags1 = obj_type_ZMQ_Ctx_delete(self)\n"
--" if(band(this_flags1,OBJ_UDATA_FLAG_OWN) == 0) then return end\n"
--" local rc_zmq_term1\n"
--" rc_zmq_term1 = C.zmq_term(this1)\n"
-+"-- method: set_affinity\n"
-+"if (_meth.ZMQ_Socket.set_affinity) then\n"
-+"function _meth.ZMQ_Socket.set_affinity(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_affinity1 = 0\n"
-+" rc_lzmq_socket_set_affinity1 = Cmod.lzmq_socket_set_affinity(self, value2)\n"
- " -- check for error.\n"
--" local rc_zmq_term1_err\n"
--" if (-1 == rc_zmq_term1) then\n"
--" rc_zmq_term1_err = error_code__ZMQ_Error__push(rc_zmq_term1)\n"
--" rc_zmq_term1 = nil\n"
--" else\n"
--" rc_zmq_term1 = true\n"
-+" if (-1 == rc_lzmq_socket_set_affinity1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_affinity1)\n"
- " end\n"
--" return rc_zmq_term1, rc_zmq_term1_err\n"
-+" return true\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: socket\n"
--"function _meth.ZMQ_Ctx.socket(self, type2)\n"
--" local this1 = obj_type_ZMQ_Ctx_check(self)\n"
-+"-- method: identity\n"
-+"if (_meth.ZMQ_Socket.identity) then\n"
-+"function _meth.ZMQ_Socket.identity(self)\n"
- " \n"
--" local rc_zmq_socket_flags1 = OBJ_UDATA_FLAG_OWN\n"
--" local rc_zmq_socket1\n"
--" rc_zmq_socket1 = C.zmq_socket(this1, type2)\n"
--" local rc_zmq_socket1_err\n"
--" if (nil == rc_zmq_socket1) then\n"
--" rc_zmq_socket1_err = get_zmq_strerror()\n"
--" else\n"
--" rc_zmq_socket1 = obj_type_ZMQ_Socket_push(rc_zmq_socket1, rc_zmq_socket_flags1)\n"
-+" local value_len1 = 0\n"
-+" local value1\n"
-+" local rc_lzmq_socket_identity2 = 0\n"
-+" rc_lzmq_socket_identity2 = Cmod.lzmq_socket_identity(self, value1, value_len1)\n"
-+" if (-1 == rc_lzmq_socket_identity2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_identity2)\n"
- " end\n"
--" return rc_zmq_socket1, rc_zmq_socket1_err\n"
-+" return ffi_string_len(value1,value_len1)\n"
-+"end\n"
- "end\n"
- "\n"
--"-- End \"ZMQ_Ctx\" FFI interface\n"
-+"-- method: set_identity\n"
-+"if (_meth.ZMQ_Socket.set_identity) then\n"
-+"function _meth.ZMQ_Socket.set_identity(self, value2)\n"
-+" \n"
-+" local value_len2 = #value2\n"
-+" local rc_lzmq_socket_set_identity1 = 0\n"
-+" rc_lzmq_socket_set_identity1 = Cmod.lzmq_socket_set_identity(self, value2, value_len2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_identity1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_identity1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
- "\n"
-+"-- method: subscribe\n"
-+"if (_meth.ZMQ_Socket.subscribe) then\n"
-+"function _meth.ZMQ_Socket.subscribe(self, value2)\n"
-+" \n"
-+" local value_len2 = #value2\n"
-+" local rc_lzmq_socket_subscribe1 = 0\n"
-+" rc_lzmq_socket_subscribe1 = Cmod.lzmq_socket_subscribe(self, value2, value_len2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_subscribe1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_subscribe1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
- "\n"
--"-- Start \"ZMQ_StopWatch\" FFI interface\n"
--"-- method: start\n"
--"function _pub.ZMQ_StopWatch.start()\n"
--" local this_flags1 = OBJ_UDATA_FLAG_OWN\n"
--" local this1\n"
--" this1 = C.zmq_stopwatch_start()\n"
--" this1 = obj_type_ZMQ_StopWatch_push(this1, this_flags1)\n"
--" return this1\n"
-+"-- method: unsubscribe\n"
-+"if (_meth.ZMQ_Socket.unsubscribe) then\n"
-+"function _meth.ZMQ_Socket.unsubscribe(self, value2)\n"
-+" \n"
-+" local value_len2 = #value2\n"
-+" local rc_lzmq_socket_unsubscribe1 = 0\n"
-+" rc_lzmq_socket_unsubscribe1 = Cmod.lzmq_socket_unsubscribe(self, value2, value_len2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_unsubscribe1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_unsubscribe1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: stop\n"
--"function _meth.ZMQ_StopWatch.stop(self)\n"
--" local this1,this_flags1 = obj_type_ZMQ_StopWatch_delete(self)\n"
--" if(band(this_flags1,OBJ_UDATA_FLAG_OWN) == 0) then return end\n"
--" local usecs1\n"
--" usecs1 = C.zmq_stopwatch_stop(this1)\n"
--" usecs1 = tonumber(usecs1)\n"
--" return usecs1\n"
-+"do\n"
-+" local rate_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: rate\n"
-+"if (_meth.ZMQ_Socket.rate) then\n"
-+"function _meth.ZMQ_Socket.rate(self)\n"
-+" \n"
-+" local value1 = rate_value_tmp\n"
-+" local rc_lzmq_socket_rate2 = 0\n"
-+" rc_lzmq_socket_rate2 = Cmod.lzmq_socket_rate(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_rate2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_rate2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
- "end\n"
- "\n"
--"-- End \"ZMQ_StopWatch\" FFI interface\n"
-+"-- method: set_rate\n"
-+"if (_meth.ZMQ_Socket.set_rate) then\n"
-+"function _meth.ZMQ_Socket.set_rate(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_rate1 = 0\n"
-+" rc_lzmq_socket_set_rate1 = Cmod.lzmq_socket_set_rate(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_rate1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_rate1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
- "\n"
--"-- method: init\n"
--"function _pub.zmq.init(io_threads1)\n"
-+"do\n"
-+" local recovery_ivl_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: recovery_ivl\n"
-+"if (_meth.ZMQ_Socket.recovery_ivl) then\n"
-+"function _meth.ZMQ_Socket.recovery_ivl(self)\n"
- " \n"
--" local rc_zmq_init_flags1 = OBJ_UDATA_FLAG_OWN\n"
--" local rc_zmq_init1\n"
--" rc_zmq_init1 = C.zmq_init(io_threads1)\n"
--" local rc_zmq_init1_err\n"
--" if (nil == rc_zmq_init1) then\n"
--" rc_zmq_init1_err = get_zmq_strerror()\n"
--" else\n"
--" rc_zmq_init1 = obj_type_ZMQ_Ctx_push(rc_zmq_init1, rc_zmq_init_flags1)\n"
-+" local value1 = recovery_ivl_value_tmp\n"
-+" local rc_lzmq_socket_recovery_ivl2 = 0\n"
-+" rc_lzmq_socket_recovery_ivl2 = Cmod.lzmq_socket_recovery_ivl(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_recovery_ivl2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_recovery_ivl2)\n"
- " end\n"
--" return rc_zmq_init1, rc_zmq_init1_err\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: init_ctx\n"
--"function _pub.zmq.init_ctx(ptr1)\n"
--" local ctx1\n"
--" local p_type = type(ptr1)\n"
--" if p_type == 'userdata' then\n"
--" ctx1 = ffi.cast('void *', ptr1);\n"
--" elseif p_type == 'cdata' then\n"
--" ctx1 = ptr1;\n"
--" else\n"
--" return error(\"expected lightuserdata/cdata<void *>\");\n"
--" end\n"
-+"-- method: set_recovery_ivl\n"
-+"if (_meth.ZMQ_Socket.set_recovery_ivl) then\n"
-+"function _meth.ZMQ_Socket.set_recovery_ivl(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_recovery_ivl1 = 0\n"
-+" rc_lzmq_socket_set_recovery_ivl1 = Cmod.lzmq_socket_set_recovery_ivl(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_recovery_ivl1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_recovery_ivl1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
- "\n"
--" local ctx1_err\n"
--" if (nil == ctx1) then\n"
--" ctx1_err = get_zmq_strerror()\n"
--" else\n"
--" ctx1 = obj_type_ZMQ_Ctx_push(ctx1, 0)\n"
-+"do\n"
-+" local mcast_loop_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: mcast_loop\n"
-+"if (_meth.ZMQ_Socket.mcast_loop) then\n"
-+"function _meth.ZMQ_Socket.mcast_loop(self)\n"
-+" \n"
-+" local value1 = mcast_loop_value_tmp\n"
-+" local rc_lzmq_socket_mcast_loop2 = 0\n"
-+" rc_lzmq_socket_mcast_loop2 = Cmod.lzmq_socket_mcast_loop(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_mcast_loop2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_mcast_loop2)\n"
- " end\n"
--" return ctx1, ctx1_err\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: device\n"
--"function _pub.zmq.device(device1, insock2, outsock3)\n"
-+"-- method: set_mcast_loop\n"
-+"if (_meth.ZMQ_Socket.set_mcast_loop) then\n"
-+"function _meth.ZMQ_Socket.set_mcast_loop(self, value2)\n"
- " \n"
--" insock2 = obj_type_ZMQ_Socket_check(insock2)\n"
--" outsock3 = obj_type_ZMQ_Socket_check(outsock3)\n"
--" local rc_zmq_device1\n"
--" rc_zmq_device1 = C.zmq_device(device1, insock2, outsock3)\n"
-+" \n"
-+" local rc_lzmq_socket_set_mcast_loop1 = 0\n"
-+" rc_lzmq_socket_set_mcast_loop1 = Cmod.lzmq_socket_set_mcast_loop(self, value2)\n"
- " -- check for error.\n"
--" local rc_zmq_device1_err\n"
--" if (-1 == rc_zmq_device1) then\n"
--" rc_zmq_device1_err = error_code__ZMQ_Error__push(rc_zmq_device1)\n"
--" rc_zmq_device1 = nil\n"
--" else\n"
--" rc_zmq_device1 = true\n"
-+" if (-1 == rc_lzmq_socket_set_mcast_loop1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_mcast_loop1)\n"
- " end\n"
--" return rc_zmq_device1, rc_zmq_device1_err\n"
-+" return true\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: stopwatch_start\n"
--"function _pub.zmq.stopwatch_start()\n"
--" local rc_zmq_stopwatch_start_flags1 = OBJ_UDATA_FLAG_OWN\n"
--" local rc_zmq_stopwatch_start1\n"
--" rc_zmq_stopwatch_start1 = C.zmq_stopwatch_start()\n"
--" rc_zmq_stopwatch_start1 = obj_type_ZMQ_StopWatch_push(rc_zmq_stopwatch_start1, rc_zmq_stopwatch_start_flags1)\n"
--" return rc_zmq_stopwatch_start1\n"
-+"do\n"
-+" local sndbuf_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: sndbuf\n"
-+"if (_meth.ZMQ_Socket.sndbuf) then\n"
-+"function _meth.ZMQ_Socket.sndbuf(self)\n"
-+" \n"
-+" local value1 = sndbuf_value_tmp\n"
-+" local rc_lzmq_socket_sndbuf2 = 0\n"
-+" rc_lzmq_socket_sndbuf2 = Cmod.lzmq_socket_sndbuf(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_sndbuf2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_sndbuf2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
- "end\n"
- "\n"
--"-- method: sleep\n"
--"function _pub.zmq.sleep(seconds_1)\n"
-+"-- method: set_sndbuf\n"
-+"if (_meth.ZMQ_Socket.set_sndbuf) then\n"
-+"function _meth.ZMQ_Socket.set_sndbuf(self, value2)\n"
- " \n"
--" C.zmq_sleep(seconds_1)\n"
--" return \n"
-+" \n"
-+" local rc_lzmq_socket_set_sndbuf1 = 0\n"
-+" rc_lzmq_socket_set_sndbuf1 = Cmod.lzmq_socket_set_sndbuf(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_sndbuf1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_sndbuf1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
- "end\n"
- "\n"
--"";
--
--/* detect zmq version >= 2.1.0 */
--#define VERSION_2_1 0
--#if defined(ZMQ_VERSION)
--#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0))
--#undef VERSION_2_1
--#define VERSION_2_1 1
-+"do\n"
-+" local rcvbuf_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: rcvbuf\n"
-+"if (_meth.ZMQ_Socket.rcvbuf) then\n"
-+"function _meth.ZMQ_Socket.rcvbuf(self)\n"
-+" \n"
-+" local value1 = rcvbuf_value_tmp\n"
-+" local rc_lzmq_socket_rcvbuf2 = 0\n"
-+" rc_lzmq_socket_rcvbuf2 = Cmod.lzmq_socket_rcvbuf(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_rcvbuf2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_rcvbuf2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_rcvbuf\n"
-+"if (_meth.ZMQ_Socket.set_rcvbuf) then\n"
-+"function _meth.ZMQ_Socket.set_rcvbuf(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_rcvbuf1 = 0\n"
-+" rc_lzmq_socket_set_rcvbuf1 = Cmod.lzmq_socket_set_rcvbuf(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_rcvbuf1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_rcvbuf1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local rcvmore_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: rcvmore\n"
-+"if (_meth.ZMQ_Socket.rcvmore) then\n"
-+"function _meth.ZMQ_Socket.rcvmore(self)\n"
-+" \n"
-+" local value1 = rcvmore_value_tmp\n"
-+" local rc_lzmq_socket_rcvmore2 = 0\n"
-+" rc_lzmq_socket_rcvmore2 = Cmod.lzmq_socket_rcvmore(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_rcvmore2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_rcvmore2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local fd_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: fd\n"
-+"if (_meth.ZMQ_Socket.fd) then\n"
-+"function _meth.ZMQ_Socket.fd(self)\n"
-+" \n"
-+" local value1 = fd_value_tmp\n"
-+" local rc_lzmq_socket_fd2 = 0\n"
-+" rc_lzmq_socket_fd2 = Cmod.lzmq_socket_fd(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_fd2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_fd2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local events_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: events\n"
-+"if (_meth.ZMQ_Socket.events) then\n"
-+"function _meth.ZMQ_Socket.events(self)\n"
-+" \n"
-+" local value1 = events_value_tmp\n"
-+" local rc_lzmq_socket_events2 = 0\n"
-+" rc_lzmq_socket_events2 = Cmod.lzmq_socket_events(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_events2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_events2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local type_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: type\n"
-+"if (_meth.ZMQ_Socket.type) then\n"
-+"function _meth.ZMQ_Socket.type(self)\n"
-+" \n"
-+" local value1 = type_value_tmp\n"
-+" local rc_lzmq_socket_type2 = 0\n"
-+" rc_lzmq_socket_type2 = Cmod.lzmq_socket_type(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_type2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_type2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local linger_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: linger\n"
-+"if (_meth.ZMQ_Socket.linger) then\n"
-+"function _meth.ZMQ_Socket.linger(self)\n"
-+" \n"
-+" local value1 = linger_value_tmp\n"
-+" local rc_lzmq_socket_linger2 = 0\n"
-+" rc_lzmq_socket_linger2 = Cmod.lzmq_socket_linger(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_linger2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_linger2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_linger\n"
-+"if (_meth.ZMQ_Socket.set_linger) then\n"
-+"function _meth.ZMQ_Socket.set_linger(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_linger1 = 0\n"
-+" rc_lzmq_socket_set_linger1 = Cmod.lzmq_socket_set_linger(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_linger1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_linger1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local reconnect_ivl_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: reconnect_ivl\n"
-+"if (_meth.ZMQ_Socket.reconnect_ivl) then\n"
-+"function _meth.ZMQ_Socket.reconnect_ivl(self)\n"
-+" \n"
-+" local value1 = reconnect_ivl_value_tmp\n"
-+" local rc_lzmq_socket_reconnect_ivl2 = 0\n"
-+" rc_lzmq_socket_reconnect_ivl2 = Cmod.lzmq_socket_reconnect_ivl(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_reconnect_ivl2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_reconnect_ivl2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_reconnect_ivl\n"
-+"if (_meth.ZMQ_Socket.set_reconnect_ivl) then\n"
-+"function _meth.ZMQ_Socket.set_reconnect_ivl(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_reconnect_ivl1 = 0\n"
-+" rc_lzmq_socket_set_reconnect_ivl1 = Cmod.lzmq_socket_set_reconnect_ivl(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_reconnect_ivl1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_reconnect_ivl1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local backlog_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: backlog\n"
-+"if (_meth.ZMQ_Socket.backlog) then\n"
-+"function _meth.ZMQ_Socket.backlog(self)\n"
-+" \n"
-+" local value1 = backlog_value_tmp\n"
-+" local rc_lzmq_socket_backlog2 = 0\n"
-+" rc_lzmq_socket_backlog2 = Cmod.lzmq_socket_backlog(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_backlog2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_backlog2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_backlog\n"
-+"if (_meth.ZMQ_Socket.set_backlog) then\n"
-+"function _meth.ZMQ_Socket.set_backlog(self, value2)\n"
-+" \n"
-+" \n", /* ----- CUT ----- */
-+" local rc_lzmq_socket_set_backlog1 = 0\n"
-+" rc_lzmq_socket_set_backlog1 = Cmod.lzmq_socket_set_backlog(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_backlog1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_backlog1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local recovery_ivl_msec_value_tmp = ffi.new(\"int64_t[1]\")\n"
-+"-- method: recovery_ivl_msec\n"
-+"if (_meth.ZMQ_Socket.recovery_ivl_msec) then\n"
-+"function _meth.ZMQ_Socket.recovery_ivl_msec(self)\n"
-+" \n"
-+" local value1 = recovery_ivl_msec_value_tmp\n"
-+" local rc_lzmq_socket_recovery_ivl_msec2 = 0\n"
-+" rc_lzmq_socket_recovery_ivl_msec2 = Cmod.lzmq_socket_recovery_ivl_msec(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_recovery_ivl_msec2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_recovery_ivl_msec2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_recovery_ivl_msec\n"
-+"if (_meth.ZMQ_Socket.set_recovery_ivl_msec) then\n"
-+"function _meth.ZMQ_Socket.set_recovery_ivl_msec(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_recovery_ivl_msec1 = 0\n"
-+" rc_lzmq_socket_set_recovery_ivl_msec1 = Cmod.lzmq_socket_set_recovery_ivl_msec(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_recovery_ivl_msec1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_recovery_ivl_msec1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local reconnect_ivl_max_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: reconnect_ivl_max\n"
-+"if (_meth.ZMQ_Socket.reconnect_ivl_max) then\n"
-+"function _meth.ZMQ_Socket.reconnect_ivl_max(self)\n"
-+" \n"
-+" local value1 = reconnect_ivl_max_value_tmp\n"
-+" local rc_lzmq_socket_reconnect_ivl_max2 = 0\n"
-+" rc_lzmq_socket_reconnect_ivl_max2 = Cmod.lzmq_socket_reconnect_ivl_max(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_reconnect_ivl_max2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_reconnect_ivl_max2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_reconnect_ivl_max\n"
-+"if (_meth.ZMQ_Socket.set_reconnect_ivl_max) then\n"
-+"function _meth.ZMQ_Socket.set_reconnect_ivl_max(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_reconnect_ivl_max1 = 0\n"
-+" rc_lzmq_socket_set_reconnect_ivl_max1 = Cmod.lzmq_socket_set_reconnect_ivl_max(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_reconnect_ivl_max1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_reconnect_ivl_max1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local maxmsgsize_value_tmp = ffi.new(\"int64_t[1]\")\n"
-+"-- method: maxmsgsize\n"
-+"if (_meth.ZMQ_Socket.maxmsgsize) then\n"
-+"function _meth.ZMQ_Socket.maxmsgsize(self)\n"
-+" \n"
-+" local value1 = maxmsgsize_value_tmp\n"
-+" local rc_lzmq_socket_maxmsgsize2 = 0\n"
-+" rc_lzmq_socket_maxmsgsize2 = Cmod.lzmq_socket_maxmsgsize(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_maxmsgsize2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_maxmsgsize2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_maxmsgsize\n"
-+"if (_meth.ZMQ_Socket.set_maxmsgsize) then\n"
-+"function _meth.ZMQ_Socket.set_maxmsgsize(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_maxmsgsize1 = 0\n"
-+" rc_lzmq_socket_set_maxmsgsize1 = Cmod.lzmq_socket_set_maxmsgsize(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_maxmsgsize1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_maxmsgsize1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local sndhwm_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: sndhwm\n"
-+"if (_meth.ZMQ_Socket.sndhwm) then\n"
-+"function _meth.ZMQ_Socket.sndhwm(self)\n"
-+" \n"
-+" local value1 = sndhwm_value_tmp\n"
-+" local rc_lzmq_socket_sndhwm2 = 0\n"
-+" rc_lzmq_socket_sndhwm2 = Cmod.lzmq_socket_sndhwm(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_sndhwm2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_sndhwm2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_sndhwm\n"
-+"if (_meth.ZMQ_Socket.set_sndhwm) then\n"
-+"function _meth.ZMQ_Socket.set_sndhwm(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_sndhwm1 = 0\n"
-+" rc_lzmq_socket_set_sndhwm1 = Cmod.lzmq_socket_set_sndhwm(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_sndhwm1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_sndhwm1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local rcvhwm_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: rcvhwm\n"
-+"if (_meth.ZMQ_Socket.rcvhwm) then\n"
-+"function _meth.ZMQ_Socket.rcvhwm(self)\n"
-+" \n"
-+" local value1 = rcvhwm_value_tmp\n"
-+" local rc_lzmq_socket_rcvhwm2 = 0\n"
-+" rc_lzmq_socket_rcvhwm2 = Cmod.lzmq_socket_rcvhwm(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_rcvhwm2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_rcvhwm2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_rcvhwm\n"
-+"if (_meth.ZMQ_Socket.set_rcvhwm) then\n"
-+"function _meth.ZMQ_Socket.set_rcvhwm(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_rcvhwm1 = 0\n"
-+" rc_lzmq_socket_set_rcvhwm1 = Cmod.lzmq_socket_set_rcvhwm(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_rcvhwm1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_rcvhwm1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local multicast_hops_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: multicast_hops\n"
-+"if (_meth.ZMQ_Socket.multicast_hops) then\n"
-+"function _meth.ZMQ_Socket.multicast_hops(self)\n"
-+" \n"
-+" local value1 = multicast_hops_value_tmp\n"
-+" local rc_lzmq_socket_multicast_hops2 = 0\n"
-+" rc_lzmq_socket_multicast_hops2 = Cmod.lzmq_socket_multicast_hops(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_multicast_hops2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_multicast_hops2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_multicast_hops\n"
-+"if (_meth.ZMQ_Socket.set_multicast_hops) then\n"
-+"function _meth.ZMQ_Socket.set_multicast_hops(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_multicast_hops1 = 0\n"
-+" rc_lzmq_socket_set_multicast_hops1 = Cmod.lzmq_socket_set_multicast_hops(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_multicast_hops1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_multicast_hops1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local rcvtimeo_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: rcvtimeo\n"
-+"if (_meth.ZMQ_Socket.rcvtimeo) then\n"
-+"function _meth.ZMQ_Socket.rcvtimeo(self)\n"
-+" \n"
-+" local value1 = rcvtimeo_value_tmp\n"
-+" local rc_lzmq_socket_rcvtimeo2 = 0\n"
-+" rc_lzmq_socket_rcvtimeo2 = Cmod.lzmq_socket_rcvtimeo(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_rcvtimeo2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_rcvtimeo2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_rcvtimeo\n"
-+"if (_meth.ZMQ_Socket.set_rcvtimeo) then\n"
-+"function _meth.ZMQ_Socket.set_rcvtimeo(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_rcvtimeo1 = 0\n"
-+" rc_lzmq_socket_set_rcvtimeo1 = Cmod.lzmq_socket_set_rcvtimeo(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_rcvtimeo1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_rcvtimeo1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local sndtimeo_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: sndtimeo\n"
-+"if (_meth.ZMQ_Socket.sndtimeo) then\n"
-+"function _meth.ZMQ_Socket.sndtimeo(self)\n"
-+" \n"
-+" local value1 = sndtimeo_value_tmp\n"
-+" local rc_lzmq_socket_sndtimeo2 = 0\n"
-+" rc_lzmq_socket_sndtimeo2 = Cmod.lzmq_socket_sndtimeo(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_sndtimeo2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_sndtimeo2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_sndtimeo\n"
-+"if (_meth.ZMQ_Socket.set_sndtimeo) then\n"
-+"function _meth.ZMQ_Socket.set_sndtimeo(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_sndtimeo1 = 0\n"
-+" rc_lzmq_socket_set_sndtimeo1 = Cmod.lzmq_socket_set_sndtimeo(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_sndtimeo1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_sndtimeo1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local ipv4only_value_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: ipv4only\n"
-+"if (_meth.ZMQ_Socket.ipv4only) then\n"
-+"function _meth.ZMQ_Socket.ipv4only(self)\n"
-+" \n"
-+" local value1 = ipv4only_value_tmp\n"
-+" local rc_lzmq_socket_ipv4only2 = 0\n"
-+" rc_lzmq_socket_ipv4only2 = Cmod.lzmq_socket_ipv4only(self, value1)\n"
-+" if (-1 == rc_lzmq_socket_ipv4only2) then\n"
-+" return nil,error_code__ZMQ_Error__push(rc_lzmq_socket_ipv4only2)\n"
-+" end\n"
-+" return value1[0]\n"
-+"end\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: set_ipv4only\n"
-+"if (_meth.ZMQ_Socket.set_ipv4only) then\n"
-+"function _meth.ZMQ_Socket.set_ipv4only(self, value2)\n"
-+" \n"
-+" \n"
-+" local rc_lzmq_socket_set_ipv4only1 = 0\n"
-+" rc_lzmq_socket_set_ipv4only1 = Cmod.lzmq_socket_set_ipv4only(self, value2)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_lzmq_socket_set_ipv4only1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_lzmq_socket_set_ipv4only1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"_push.ZMQ_Socket = obj_type_ZMQ_Socket_push\n"
-+"ffi.metatype(\"ZMQ_Socket\", _priv.ZMQ_Socket)\n"
-+"-- End \"ZMQ_Socket\" FFI interface\n"
-+"\n"
-+"\n"
-+"-- Start \"ZMQ_Poller\" FFI interface\n"
-+"-- method: new\n"
-+"function _pub.ZMQ_Poller.new(length1)\n"
-+" length1 = length1 or 10\n"
-+" local self = ffi.new(\"ZMQ_Poller\")\n"
-+" Cmod.poller_init(self, length1)\n"
-+" return obj_type_ZMQ_Poller_push(self)\n"
-+"end\n"
-+"register_default_constructor(_pub,\"ZMQ_Poller\",_pub.ZMQ_Poller.new)\n"
-+"\n"
-+"-- method: close\n"
-+"function _meth.ZMQ_Poller.close(self)\n"
-+" local self = obj_type_ZMQ_Poller_delete(self)\n"
-+" if not self then return end\n"
-+" Cmod.poller_cleanup(self)\n"
-+" return \n"
-+"end\n"
-+"_priv.ZMQ_Poller.__gc = _meth.ZMQ_Poller.close\n"
-+"\n"
-+"-- method: add\n"
-+"function _meth.ZMQ_Poller.add(self, sock2, events3)\n"
-+" \n"
-+" \n"
-+" local idx1 = 0\n"
-+" local fd = 0\n"
-+" local sock_type = type(sock2)\n"
-+" if sock_type == 'cdata' then\n"
-+" sock = obj_type_ZMQ_Socket_check(sock2)\n"
-+" elseif sock_type == 'number' then\n"
-+" fd = sock2\n"
-+" else\n"
-+" error(\"expected number or ZMQ_Socket\")\n"
-+" end\n"
-+" idx1 = Cmod.poller_get_free_item(self)\n"
-+" local item = self.items[idx1]\n"
-+" item.socket = sock\n"
-+" item.fd = fd\n"
-+" item.events = events3\n"
-+"\n"
-+" return idx1\n"
-+"end\n"
-+"\n"
-+"-- method: modify\n"
-+"function _meth.ZMQ_Poller.modify(self, sock2, events3)\n"
-+" \n"
-+" \n"
-+" local idx1 = 0\n"
-+" local fd = 0\n"
-+" local sock_type = type(sock2)\n"
-+" if sock_type == 'cdata' then\n"
-+" sock = obj_type_ZMQ_Socket_check(sock2)\n"
-+" -- find sock in items list.\n"
-+" idx1 = Cmod.poller_find_sock_item(self, sock)\n"
-+" elseif sock_type == 'number' then\n"
-+" fd = sock2\n"
-+" -- find fd in items list.\n"
-+" idx1 = Cmod.poller_find_fd_item(self, fd);\n"
-+" else\n"
-+" error(\"expected number or ZMQ_Socket\")\n"
-+" end\n"
-+" if events3 ~= 0 then\n"
-+" local item = self.items[idx1]\n"
-+" item.socket = sock\n"
-+" item.fd = fd\n"
-+" item.events = events3\n"
-+" else\n"
-+" Cmod.poller_remove_item(self, idx1)\n"
-+" end\n"
-+"\n"
-+" return idx1\n"
-+"end\n"
-+"\n"
-+"-- method: remove\n"
-+"function _meth.ZMQ_Poller.remove(self, sock2)\n"
-+" \n"
-+" local idx1 = 0\n"
-+" local fd = 0\n"
-+" local sock_type = type(sock2)\n"
-+" if sock_type == 'cdata' then\n"
-+" sock = obj_type_ZMQ_Socket_check(sock2)\n"
-+" -- find sock in items list.\n"
-+" idx1 = Cmod.poller_find_sock_item(self, sock)\n"
-+" elseif sock_type == 'number' then\n"
-+" fd = sock2\n"
-+" -- find fd in items list.\n"
-+" idx1 = Cmod.poller_find_fd_item(self, fd);\n"
-+" else\n"
-+" error(\"expected number or ZMQ_Socket\")\n"
-+" end\n"
-+" if idx1 >= 0 then\n"
-+" Cmod.poller_remove_item(self, idx1)\n"
-+" end\n"
-+"\n"
-+" return idx1\n"
-+"end\n"
-+"\n"
-+"-- method: poll\n"
-+"function _meth.ZMQ_Poller.poll(self, timeout2)\n"
-+" \n"
-+" \n"
-+" local count1 = 0\n"
-+" local err2 = 0\n"
-+" err2 = Cmod.poller_poll(self, timeout2)\n"
-+" if(err2 > 0) then\n"
-+" self.next = 0\n"
-+" count1 = err2\n"
-+" else\n"
-+" self.next = -1\n"
-+" count1 = 0\n"
-+" end\n"
-+"\n"
-+" if (-1 == err2) then\n"
-+" return nil,error_code__ZMQ_Error__push(err2)\n"
-+" end\n"
-+" return count1\n"
-+"end\n"
-+"\n"
-+"do\n"
-+" local next_revents_idx_revents_tmp = ffi.new(\"int[1]\")\n"
-+"-- method: next_revents_idx\n"
-+"function _meth.ZMQ_Poller.next_revents_idx(self)\n"
-+" \n"
-+" local idx1 = 0\n"
-+" local revents2 = next_revents_idx_revents_tmp\n"
-+" idx1 = Cmod.poller_next_revents(self, revents2)\n"
-+" return idx1, revents2[0]\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: count\n"
-+"function _meth.ZMQ_Poller.count(self)\n"
-+" \n"
-+" local count1 = 0\n"
-+" count1 = self.count;\n"
-+"\n"
-+" return count1\n"
-+"end\n"
-+"\n"
-+"_push.ZMQ_Poller = obj_type_ZMQ_Poller_push\n"
-+"ffi.metatype(\"ZMQ_Poller\", _priv.ZMQ_Poller)\n"
-+"-- End \"ZMQ_Poller\" FFI interface\n"
-+"\n"
-+"\n"
-+"-- Start \"ZMQ_Ctx\" FFI interface\n"
-+"-- method: term\n"
-+"function _meth.ZMQ_Ctx.term(self)\n"
-+" local self,this_flags1 = obj_type_ZMQ_Ctx_delete(self)\n"
-+" if not self then return end\n"
-+" local rc_zmq_term1 = 0\n"
-+" rc_zmq_term1 = C.zmq_term(self)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_zmq_term1) then\n"
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_term1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"_priv.ZMQ_Ctx.__gc = _meth.ZMQ_Ctx.term\n"
-+"\n"
-+"-- method: socket\n"
-+"function _meth.ZMQ_Ctx.socket(self, type2)\n"
-+" \n"
-+" \n"
-+" local rc_zmq_socket_flags1 = OBJ_UDATA_FLAG_OWN\n"
-+" local rc_zmq_socket1\n"
-+" rc_zmq_socket1 = C.zmq_socket(self, type2)\n"
-+" if (nil == rc_zmq_socket1) then\n"
-+" return nil, get_zmq_strerror()\n"
-+" end\n"
-+" return obj_type_ZMQ_Socket_push(rc_zmq_socket1, rc_zmq_socket_flags1)\n"
-+"end\n"
-+"\n"
-+"_push.ZMQ_Ctx = obj_type_ZMQ_Ctx_push\n"
-+"ffi.metatype(\"ZMQ_Ctx\", _priv.ZMQ_Ctx)\n"
-+"-- End \"ZMQ_Ctx\" FFI interface\n"
-+"\n"
-+"\n"
-+"-- Start \"ZMQ_StopWatch\" FFI interface\n"
-+"-- method: start\n"
-+"function _pub.ZMQ_StopWatch.start()\n"
-+" local this_flags1 = OBJ_UDATA_FLAG_OWN\n"
-+" local self\n"
-+" self = C.zmq_stopwatch_start()\n"
-+" return obj_type_ZMQ_StopWatch_push(self, this_flags1)\n"
-+"end\n"
-+"register_default_constructor(_pub,\"ZMQ_StopWatch\",_pub.ZMQ_StopWatch.start)\n"
-+"\n"
-+"-- method: stop\n"
-+"function _meth.ZMQ_StopWatch.stop(self)\n"
-+" local self,this_flags1 = obj_type_ZMQ_StopWatch_delete(self)\n"
-+" if not self then return end\n"
-+" local usecs1 = 0\n"
-+" usecs1 = C.zmq_stopwatch_stop(self)\n"
-+" return tonumber(usecs1)\n"
-+"end\n"
-+"_priv.ZMQ_StopWatch.__gc = _meth.ZMQ_StopWatch.stop\n"
-+"\n"
-+"_push.ZMQ_StopWatch = obj_type_ZMQ_StopWatch_push\n"
-+"ffi.metatype(\"ZMQ_StopWatch\", _priv.ZMQ_StopWatch)\n"
-+"-- End \"ZMQ_StopWatch\" FFI interface\n"
-+"\n"
-+"-- method: init\n"
-+"function _M.init(io_threads1)\n"
-+" io_threads1 = io_threads1 or 1\n"
-+" local rc_zmq_init_flags1 = OBJ_UDATA_FLAG_OWN\n"
-+" local rc_zmq_init1\n"
-+" rc_zmq_init1 = C.zmq_init(io_threads1)\n"
-+" if (nil == rc_zmq_init1) then\n"
-+" return nil, get_zmq_strerror()\n"
-+" end\n"
-+" return obj_type_ZMQ_Ctx_push(rc_zmq_init1, rc_zmq_init_flags1)\n"
-+"end\n"
-+"\n"
-+"-- method: init_ctx\n"
-+"function _M.init_ctx(ptr1)\n"
-+" local ctx1\n"
-+" local p_type = type(ptr1)\n"
-+" if p_type == 'userdata' then\n"
-+" ctx1 = ffi.cast('ZMQ_Ctx *', ptr1);\n"
-+" elseif p_type == 'cdata' and ffi.istype('void *', ptr1) then\n"
-+" ctx1 = ffi.cast('ZMQ_Ctx *', ptr1);\n"
-+" else\n"
-+" return error(\"expected lightuserdata/cdata<void *>\");\n"
-+" end\n"
-+"\n"
-+" if (nil == ctx1) then\n"
-+" return nil, get_zmq_strerror()\n"
-+" end\n"
-+" return obj_type_ZMQ_Ctx_push(ctx1, 0)\n"
-+"end\n"
-+"\n"
-+"-- method: device\n"
-+"if (_M.device) then\n"
-+"function _M.device(device1, insock2, outsock3)\n"
-+" \n"
-+" \n"
-+" \n"
-+" local rc_zmq_device1 = 0\n"
-+" rc_zmq_device1 = C.zmq_device(device1, insock2, outsock3)\n"
-+" -- check for error.\n"
-+" if (-1 == rc_zmq_device1) then\n", /* ----- CUT ----- */
-+" return nil, error_code__ZMQ_Error__push(rc_zmq_device1)\n"
-+" end\n"
-+" return true\n"
-+"end\n"
-+"end\n"
-+"\n"
-+"-- method: stopwatch_start\n"
-+"function _M.stopwatch_start()\n"
-+" local rc_zmq_stopwatch_start_flags1 = OBJ_UDATA_FLAG_OWN\n"
-+" local rc_zmq_stopwatch_start1\n"
-+" rc_zmq_stopwatch_start1 = C.zmq_stopwatch_start()\n"
-+" return obj_type_ZMQ_StopWatch_push(rc_zmq_stopwatch_start1, rc_zmq_stopwatch_start_flags1)\n"
-+"end\n"
-+"\n"
-+"-- method: sleep\n"
-+"function _M.sleep(seconds_1)\n"
-+" \n"
-+" C.zmq_sleep(seconds_1)\n"
-+" return \n"
-+"end\n"
-+"\n", NULL };
-+static char *zmq_ZErrors_key = "zmq_ZErrors_key";
-+/*
-+ * This wrapper function is to make the EAGAIN/ETERM error messages more like
-+ * what is returned by LuaSocket.
-+ */
-+static const char *get_zmq_strerror() {
-+ int err = zmq_errno();
-+ switch(err) {
-+ case EAGAIN:
-+ return "timeout";
-+ break;
-+ case EINTR:
-+ return "interrupted";
-+ break;
-+#if defined(ETERM)
-+ case ETERM:
-+ return "closed";
-+ break;
- #endif
-+ default:
-+ break;
-+ }
-+ return zmq_strerror(err);
-+}
-+
-+
-+
-+/* detect really old ZeroMQ 2.0.x series. */
-+#if !defined(ZMQ_RCVMORE)
-+# error "Your version of ZeroMQ is too old. Please upgrade to version 2.1 or to the latest 2.0.x"
- #endif
-
--/* detect really old ZeroMQ 2.0.x series. */
--#if !defined(ZMQ_RCVMORE)
--#error "Your version of ZeroMQ is too old. Please upgrade to version 2.1 or to the latest 2.0.x"
--#endif
-+typedef struct ZMQ_Socket ZMQ_Socket;
-+
-+#ifdef _WIN32
-+#include <winsock2.h>
-+typedef SOCKET socket_t;
-+#else
-+typedef int socket_t;
-+#endif
-+
-+#if VERSION_2_0
-+# define zmq_sendmsg zmq_send
-+# define zmq_recvmsg zmq_recv
-+#endif
-+
-+/* socket option types. */
-+#define OPT_TYPE_NONE 0
-+#define OPT_TYPE_INT 1
-+#define OPT_TYPE_UINT32 2
-+#define OPT_TYPE_UINT64 3
-+#define OPT_TYPE_INT64 4
-+#define OPT_TYPE_BLOB 5
-+#define OPT_TYPE_FD 6
-+
-+static const int opt_types[] = {
-+ OPT_TYPE_NONE, /* 0 unused */
-+#if VERSION_2_0
-+#define VERSION_2_0_MAX_OPT 13
-+ OPT_TYPE_UINT64, /* 1 ZMQ_HWM */
-+ OPT_TYPE_NONE, /* 2 unused */
-+ OPT_TYPE_INT64, /* 3 ZMQ_SWAP */
-+ OPT_TYPE_UINT64, /* 4 ZMQ_AFFINITY */
-+ OPT_TYPE_BLOB, /* 5 ZMQ_IDENTITY */
-+ OPT_TYPE_BLOB, /* 6 ZMQ_SUBSCRIBE */
-+ OPT_TYPE_BLOB, /* 7 ZMQ_UNSUBSCRIBE */
-+ OPT_TYPE_INT64, /* 8 ZMQ_RATE */
-+ OPT_TYPE_INT64, /* 9 ZMQ_RECOVERY_IVL */
-+ OPT_TYPE_INT64, /* 10 ZMQ_MCAST_LOOP */
-+ OPT_TYPE_UINT64, /* 11 ZMQ_SNDBUF */
-+ OPT_TYPE_UINT64, /* 12 ZMQ_RCVBUF */
-+ OPT_TYPE_INT64, /* 13 ZMQ_RCVMORE */
-+#endif /* #if VERSION_2_0 */
-+#if VERSION_2_1
-+#define VERSION_2_1_MAX_OPT 21
-+ OPT_TYPE_FD, /* 14 ZMQ_FD */
-+ OPT_TYPE_UINT32, /* 15 ZMQ_EVENTS */
-+ OPT_TYPE_INT, /* 16 ZMQ_TYPE */
-+ OPT_TYPE_INT, /* 17 ZMQ_LINGER */
-+ OPT_TYPE_INT, /* 18 ZMQ_RECONNECT_IVL */
-+ OPT_TYPE_INT, /* 19 ZMQ_BACKLOG */
-+ OPT_TYPE_INT64, /* 20 ZMQ_RECOVERY_IVL_MSEC */
-+ OPT_TYPE_INT, /* 21 ZMQ_RECONNECT_IVL_MAX */
-+#endif /* #if VERSION_2_1 */
-+#if VERSION_2_2
-+#define VERSION_2_2_MAX_OPT 28
-+ OPT_TYPE_NONE, /* 22 unused */
-+ OPT_TYPE_NONE, /* 23 unused */
-+ OPT_TYPE_NONE, /* 24 unused */
-+ OPT_TYPE_NONE, /* 25 unused */
-+ OPT_TYPE_NONE, /* 26 unused */
-+ OPT_TYPE_INT, /* 27 ZMQ_RCVTIMEO */
-+ OPT_TYPE_INT, /* 28 ZMQ_SNDTIMEO */
-+#endif /* #if VERSION_2_2 */
-+#if VERSION_3_0
-+#define VERSION_3_0_MAX_OPT 31
-+ OPT_TYPE_INT, /* 1 ZMQ_HWM */
-+ OPT_TYPE_NONE, /* 2 unused */
-+ OPT_TYPE_NONE, /* 3 unused */
-+ OPT_TYPE_UINT64, /* 4 ZMQ_AFFINITY */
-+ OPT_TYPE_BLOB, /* 5 ZMQ_IDENTITY */
-+ OPT_TYPE_BLOB, /* 6 ZMQ_SUBSCRIBE */
-+ OPT_TYPE_BLOB, /* 7 ZMQ_UNSUBSCRIBE */
-+ OPT_TYPE_INT, /* 8 ZMQ_RATE */
-+ OPT_TYPE_INT, /* 9 ZMQ_RECOVERY_IVL */
-+ OPT_TYPE_NONE, /* 10 unused */
-+ OPT_TYPE_INT, /* 11 ZMQ_SNDBUF */
-+ OPT_TYPE_INT, /* 12 ZMQ_RCVBUF */
-+ OPT_TYPE_INT, /* 13 ZMQ_RCVMORE */
-+ OPT_TYPE_FD, /* 14 ZMQ_FD */
-+ OPT_TYPE_INT, /* 15 ZMQ_EVENTS */
-+ OPT_TYPE_INT, /* 16 ZMQ_TYPE */
-+ OPT_TYPE_INT, /* 17 ZMQ_LINGER */
-+ OPT_TYPE_INT, /* 18 ZMQ_RECONNECT_IVL */
-+ OPT_TYPE_INT, /* 19 ZMQ_BACKLOG */
-+ OPT_TYPE_NONE, /* 20 unused */
-+ OPT_TYPE_INT, /* 21 ZMQ_RECONNECT_IVL_MAX */
-+ OPT_TYPE_INT64, /* 22 ZMQ_MAXMSGSIZE */
-+ OPT_TYPE_INT, /* 23 ZMQ_SNDHWM */
-+ OPT_TYPE_INT, /* 24 ZMQ_RCVHWM */
-+ OPT_TYPE_INT, /* 25 ZMQ_MULTICAST_HOPS */
-+ OPT_TYPE_NONE, /* 26 unused */
-+ OPT_TYPE_INT, /* 27 ZMQ_RCVTIMEO */
-+ OPT_TYPE_INT, /* 28 ZMQ_SNDTIMEO */
-+ OPT_TYPE_NONE, /* 29 unused */
-+ OPT_TYPE_NONE, /* 30 unused */
-+ OPT_TYPE_INT, /* 31 ZMQ_IPV4ONLY */
-+#endif /* #if VERSION_3_0 */
-+#if VERSION_3_0
-+# define MAX_OPTS VERSION_3_0_MAX_OPT
-+#else
-+# if VERSION_2_2
-+# define MAX_OPTS VERSION_2_2_MAX_OPT
-+# elif VERSION_2_1
-+# define MAX_OPTS VERSION_2_1_MAX_OPT
-+# else
-+# define MAX_OPTS VERSION_2_0_MAX_OPT
-+# endif
-+#endif
-+};
-+
-+#if VERSION_2_0
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_hwm(ZMQ_Socket *sock, int value) {
-+ uint64_t val = (uint64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_HWM, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_hwm(ZMQ_Socket *sock, int *value) {
-+ uint64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_HWM, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_swap(ZMQ_Socket *sock, int value) {
-+ int64_t val = (int64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_SWAP, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_swap(ZMQ_Socket *sock, int *value) {
-+ int64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_SWAP, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_affinity(ZMQ_Socket *sock, uint64_t value) {
-+ return zmq_setsockopt(sock, ZMQ_AFFINITY, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_affinity(ZMQ_Socket *sock, uint64_t *value) {
-+ size_t val_len = sizeof(uint64_t);
-+ return zmq_getsockopt(sock, ZMQ_AFFINITY, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_identity(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_IDENTITY, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_identity(ZMQ_Socket *sock, char *value, size_t *len) {
-+ return zmq_getsockopt(sock, ZMQ_IDENTITY, value, len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_subscribe(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_SUBSCRIBE, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_unsubscribe(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_UNSUBSCRIBE, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rate(ZMQ_Socket *sock, int value) {
-+ int64_t val = (int64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_RATE, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rate(ZMQ_Socket *sock, int *value) {
-+ int64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_RATE, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_recovery_ivl(ZMQ_Socket *sock, int value) {
-+ int64_t val = (int64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_RECOVERY_IVL, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_recovery_ivl(ZMQ_Socket *sock, int *value) {
-+ int64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_RECOVERY_IVL, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_mcast_loop(ZMQ_Socket *sock, int value) {
-+ int64_t val = (int64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_MCAST_LOOP, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_mcast_loop(ZMQ_Socket *sock, int *value) {
-+ int64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_MCAST_LOOP, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_sndbuf(ZMQ_Socket *sock, int value) {
-+ uint64_t val = (uint64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_SNDBUF, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_sndbuf(ZMQ_Socket *sock, int *value) {
-+ uint64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_SNDBUF, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rcvbuf(ZMQ_Socket *sock, int value) {
-+ uint64_t val = (uint64_t)value;
-+ return zmq_setsockopt(sock, ZMQ_RCVBUF, &val, sizeof(val));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvbuf(ZMQ_Socket *sock, int *value) {
-+ uint64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_RCVBUF, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvmore(ZMQ_Socket *sock, int *value) {
-+ int64_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_RCVMORE, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+#endif /* #if VERSION_2_0 */
-+#if VERSION_2_1
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_fd(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_FD, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_events(ZMQ_Socket *sock, int *value) {
-+ uint32_t val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ZMQ_EVENTS, &val, &val_len);
-+ *value = (int)val;
-+ return rc;
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_type(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_TYPE, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_linger(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_LINGER, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_linger(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_LINGER, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_reconnect_ivl(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RECONNECT_IVL, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_reconnect_ivl(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RECONNECT_IVL, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_backlog(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_BACKLOG, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_backlog(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_BACKLOG, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_recovery_ivl_msec(ZMQ_Socket *sock, int64_t value) {
-+ return zmq_setsockopt(sock, ZMQ_RECOVERY_IVL_MSEC, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_recovery_ivl_msec(ZMQ_Socket *sock, int64_t *value) {
-+ size_t val_len = sizeof(int64_t);
-+ return zmq_getsockopt(sock, ZMQ_RECOVERY_IVL_MSEC, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_reconnect_ivl_max(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_reconnect_ivl_max(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RECONNECT_IVL_MAX, value, &val_len);
-+}
-+
-+#endif /* #if VERSION_2_1 */
-+#if VERSION_2_2
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rcvtimeo(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RCVTIMEO, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvtimeo(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RCVTIMEO, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_sndtimeo(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_SNDTIMEO, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_sndtimeo(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_SNDTIMEO, value, &val_len);
-+}
-+
-+#endif /* #if VERSION_2_2 */
-+#if VERSION_3_0
-+ZMQ_Error lzmq_socket_set_hwm(ZMQ_Socket *sock, int value) {
-+ int val;
-+ int rc;
-+ val = (int)value;
-+ rc = zmq_setsockopt(sock, ZMQ_SNDHWM, &value, sizeof(value));
-+ if(-1 == rc) return rc;
-+ val = (int)value;
-+ return zmq_setsockopt(sock, ZMQ_RCVHWM, &value, sizeof(value));
-+}
-+ZMQ_Error lzmq_socket_hwm(ZMQ_Socket *sock, int *value) {
-+ size_t val_len;
-+ int rc;
-+ val_len = sizeof(value);
-+ rc = zmq_getsockopt(sock, ZMQ_SNDHWM, value, &val_len);
-+ if(-1 == rc) return rc;
-+ val_len = sizeof(value);
-+ return zmq_getsockopt(sock, ZMQ_RCVHWM, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_affinity(ZMQ_Socket *sock, uint64_t value) {
-+ return zmq_setsockopt(sock, ZMQ_AFFINITY, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_affinity(ZMQ_Socket *sock, uint64_t *value) {
-+ size_t val_len = sizeof(uint64_t);
-+ return zmq_getsockopt(sock, ZMQ_AFFINITY, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_identity(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_IDENTITY, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_identity(ZMQ_Socket *sock, char *value, size_t *len) {
-+ return zmq_getsockopt(sock, ZMQ_IDENTITY, value, len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_subscribe(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_SUBSCRIBE, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_unsubscribe(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ZMQ_UNSUBSCRIBE, value, str_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rate(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RATE, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rate(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RATE, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_recovery_ivl(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RECOVERY_IVL, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_recovery_ivl(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RECOVERY_IVL, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_sndbuf(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_SNDBUF, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_sndbuf(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_SNDBUF, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rcvbuf(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RCVBUF, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvbuf(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RCVBUF, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvmore(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RCVMORE, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_fd(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_FD, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_events(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_EVENTS, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_type(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_TYPE, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_linger(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_LINGER, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_linger(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_LINGER, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_reconnect_ivl(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RECONNECT_IVL, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_reconnect_ivl(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RECONNECT_IVL, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_backlog(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_BACKLOG, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_backlog(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_BACKLOG, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_reconnect_ivl_max(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_reconnect_ivl_max(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RECONNECT_IVL_MAX, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_maxmsgsize(ZMQ_Socket *sock, int64_t value) {
-+ return zmq_setsockopt(sock, ZMQ_MAXMSGSIZE, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_maxmsgsize(ZMQ_Socket *sock, int64_t *value) {
-+ size_t val_len = sizeof(int64_t);
-+ return zmq_getsockopt(sock, ZMQ_MAXMSGSIZE, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_sndhwm(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_SNDHWM, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_sndhwm(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_SNDHWM, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rcvhwm(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RCVHWM, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvhwm(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RCVHWM, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_multicast_hops(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_MULTICAST_HOPS, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_multicast_hops(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_MULTICAST_HOPS, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_rcvtimeo(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_RCVTIMEO, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_rcvtimeo(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_RCVTIMEO, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_sndtimeo(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_SNDTIMEO, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_sndtimeo(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_SNDTIMEO, value, &val_len);
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_set_ipv4only(ZMQ_Socket *sock, int value) {
-+ return zmq_setsockopt(sock, ZMQ_IPV4ONLY, &value, sizeof(value));
-+}
-+
-+LUA_NOBJ_API ZMQ_Error lzmq_socket_ipv4only(ZMQ_Socket *sock, int *value) {
-+ size_t val_len = sizeof(int);
-+ return zmq_getsockopt(sock, ZMQ_IPV4ONLY, value, &val_len);
-+}
-+
-+#endif /* #if VERSION_3_0 */
-+
-+LUA_NOBJ_API ZMQ_Error simple_zmq_send(ZMQ_Socket *sock, const char *data, size_t data_len, int flags) {
-+ ZMQ_Error err;
-+ zmq_msg_t msg;
-+ /* initialize message */
-+ err = zmq_msg_init_size(&msg, data_len);
-+ if(0 == err) {
-+ /* fill message */
-+ memcpy(zmq_msg_data(&msg), data, data_len);
-+ /* send message */
-+ err = zmq_sendmsg(sock, &msg, flags);
-+ /* close message */
-+ zmq_msg_close(&msg);
-+ }
-+ return err;
-+}
-+
-+struct ZMQ_Poller {
-+ zmq_pollitem_t *items;
-+ int next;
-+ int count;
-+ int free_list;
-+ int len;
-+};
-+
-+
-+typedef struct ZMQ_Poller ZMQ_Poller;
-+
-+#define FREE_ITEM_EVENTS_TAG ((short)0xFFFF)
-+
-+#define ITEM_TO_INDEX(items, item) (item - (items))
-+
-+static int poller_resize_items(ZMQ_Poller *poller, int len) {
-+ int old_len = poller->len;
-+
-+ /* make sure new length is atleast as large as items count. */
-+ len = (poller->count <= len) ? len : poller->count;
-+
-+ /* if the new length is the same as the old length, then don't try to resize. */
-+ if(old_len == len) return len;
-+
-+ poller->items = (zmq_pollitem_t *)realloc(poller->items, len * sizeof(zmq_pollitem_t));
-+ poller->len = len;
-+ if(len > old_len) {
-+ /* clear new space. */
-+ memset(&(poller->items[old_len]), 0, (len - old_len) * sizeof(zmq_pollitem_t));
-+ }
-+ return len;
-+}
-+
-+void poller_init(ZMQ_Poller *poller, int length) {
-+ poller->items = (zmq_pollitem_t *)calloc(length, sizeof(zmq_pollitem_t));
-+ poller->next = -1;
-+ poller->count = 0;
-+ poller->len = length;
-+ poller->free_list = -1;
-+}
-+
-+void poller_cleanup(ZMQ_Poller *poller) {
-+ free(poller->items);
-+ poller->items = NULL;
-+ poller->next = -1;
-+ poller->count = 0;
-+ poller->len = 0;
-+ poller->free_list = -1;
-+}
-+
-+int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock) {
-+ zmq_pollitem_t *items;
-+ int count;
-+ int n;
-+
-+ /* find ZMQ_Socket */
-+ items = poller->items;
-+ count = poller->count;
-+ for(n=0; n < count; n++) {
-+ if(items[n].socket == sock) return n;
-+ }
-+ /* not found. */
-+ return -1;
-+}
-+
-+int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd) {
-+ zmq_pollitem_t *items;
-+ int count;
-+ int n;
-+
-+ /* find fd */
-+ items = poller->items;
-+ count = poller->count;
-+ for(n=0; n < count; n++) {
-+ if(items[n].fd == fd) return n;
-+ }
-+ /* not found. */
-+ return -1;
-+}
-+
-+void poller_remove_item(ZMQ_Poller *poller, int idx) {
-+ zmq_pollitem_t *items;
-+ int free_list;
-+ int count;
-+
-+ count = poller->count;
-+ /* no item to remove. */
-+ if(idx >= count || count == 0) return;
-+
-+ items = poller->items;
-+ free_list = poller->free_list;
-+
-+ /* link new free slot to head of free list. */
-+ if(free_list >= 0 && free_list < count) {
-+ /* use socket pointer for free list's 'next' field. */
-+ items[idx].socket = &(items[free_list]);
-+ } else {
-+ /* free list is empty mark poller slot as the end. */
-+ items[idx].socket = NULL;
-+ }
-+ poller->free_list = idx;
-+ /* mark poller slot as a free slot. */
-+ items[idx].events = FREE_ITEM_EVENTS_TAG;
-+ /* clear old revents. */
-+ items[idx].revents = 0;
-+}
-+
-+int poller_get_free_item(ZMQ_Poller *poller) {
-+ zmq_pollitem_t *curr;
-+ zmq_pollitem_t *next;
-+ int count;
-+ int idx;
-+
-+ count = poller->count;
-+ idx = poller->free_list;
-+ /* check for a free slot in the free list. */
-+ if(idx >= 0 && idx < count) {
-+ /* remove free slot from free list. */
-+ curr = &(poller->items[idx]);
-+ /* valid free slot. */
-+ assert(curr->events == FREE_ITEM_EVENTS_TAG);
-+ /* is poller the last free slot? */
-+ next = ((zmq_pollitem_t *)curr->socket);
-+ if(next != NULL) {
-+ /* set next free slot as head of free list. */
-+ poller->free_list = ITEM_TO_INDEX(poller->items, next);
-+ } else {
-+ /* free list is empty now. */
-+ poller->free_list = -1;
-+ }
-+ /* clear slot */
-+ memset(curr, 0, sizeof(zmq_pollitem_t));
-+ return idx;
-+ }
-+
-+ idx = count;
-+ poller->count = ++count;
-+ /* make room for new item. */
-+ if(count >= poller->len) {
-+ poller_resize_items(poller, poller->len + 10);
-+ }
-+ return idx;
-+}
-+
-+static int poller_compact_items(ZMQ_Poller *poller) {
-+ zmq_pollitem_t *items;
-+ int count;
-+ int old_count;
-+ int next;
-+
-+ count = poller->count;
-+ /* if no free slot, then return. */
-+ if(poller->free_list < 0) return count;
-+ old_count = count;
-+
-+ items = poller->items;
-+ next = 0;
-+ /* find first free slot. */
-+ while(next < count && items[next].events != FREE_ITEM_EVENTS_TAG) {
-+ ++next;
-+ }
-+
-+ /* move non-free slots into free slot. */
-+ count = next;
-+ ++next;
-+ while(next < old_count) {
-+ if(items[next].events != FREE_ITEM_EVENTS_TAG) {
-+ /* found non-free slot, move it to the current free slot. */
-+ items[count] = items[next];
-+ ++count;
-+ }
-+ ++next;
-+ }
-+
-+ /* clear old used-space */
-+ memset(&(items[count]), 0, ((old_count - count) * sizeof(zmq_pollitem_t)));
-+ poller->count = count;
-+ poller->free_list = -1; /* free list is now empty. */
-
--typedef struct ZMQ_Socket ZMQ_Socket;
-+ assert(count <= poller->len);
-+ return count;
-+}
-
--#ifdef _WIN32
--#include <winsock2.h>
--typedef SOCKET socket_t;
--#else
--typedef int socket_t;
--#endif
-+int poller_poll(ZMQ_Poller *poller, long timeout) {
-+ int count;
-+ /* remove free slots from items list. */
-+ if(poller->free_list >= 0) {
-+ count = poller_compact_items(poller);
-+ } else {
-+ count = poller->count;
-+ }
-+ /* poll for events. */
-+ return zmq_poll(poller->items, count, timeout);
-+}
-
--/* socket option types. */
--#define OPT_TYPE_NONE 0
--#define OPT_TYPE_INT 1
--#define OPT_TYPE_UINT32 2
--#define OPT_TYPE_UINT64 3
--#define OPT_TYPE_INT64 4
--#define OPT_TYPE_STR 5
--#define OPT_TYPE_FD 6
-+int poller_next_revents(ZMQ_Poller *poller, int *revents) {
-+ zmq_pollitem_t *items;
-+ int count;
-+ int idx;
-+ int next;
-
--static const int opt_types[] = {
-- OPT_TYPE_NONE, /* 0 unused */
-- OPT_TYPE_UINT64, /* 1 ZMQ_HWM */
-- OPT_TYPE_NONE, /* 2 unused */
-- OPT_TYPE_INT64, /* 3 ZMQ_SWAP */
-- OPT_TYPE_UINT64, /* 4 ZMQ_AFFINITY */
-- OPT_TYPE_STR, /* 5 ZMQ_IDENTITY */
-- OPT_TYPE_STR, /* 6 ZMQ_SUBSCRIBE */
-- OPT_TYPE_STR, /* 7 ZMQ_UNSUBSCRIBE */
-- OPT_TYPE_INT64, /* 8 ZMQ_RATE */
-- OPT_TYPE_INT64, /* 9 ZMQ_RECOVERY_IVL */
-- OPT_TYPE_INT64, /* 10 ZMQ_MCAST_LOOP */
-- OPT_TYPE_UINT64, /* 11 ZMQ_SNDBUF */
-- OPT_TYPE_UINT64, /* 12 ZMQ_RCVBUF */
-- OPT_TYPE_INT64, /* 13 ZMQ_RCVMORE */
-+ idx = poller->next;
-+ /* do we need to poll for more events? */
-+ if(idx < 0) {
-+ return idx;
-+ }
-+ items = poller->items;
-+ count = poller->count;
-+ /* find next item with pending events. */
-+ for(;idx < count; ++idx) {
-+ /* did we find a pending event? */
-+ if(items[idx].revents != 0) {
-+ *revents = items[idx].revents;
-+ poller->next = idx+1;
-+ return idx;
-+ }
-+ }
-+ /* processed all pending events. */
-+ poller->next = -1;
-+ *revents = 0;
-+ return -1;
-+}
-
--#if VERSION_2_1
-- OPT_TYPE_FD, /* 14 ZMQ_FD */
-- OPT_TYPE_UINT32, /* 15 ZMQ_EVENTS */
-- OPT_TYPE_INT, /* 16 ZMQ_TYPE */
-- OPT_TYPE_INT, /* 17 ZMQ_LINGER */
-- OPT_TYPE_INT, /* 18 ZMQ_RECONNECT_IVL */
-- OPT_TYPE_INT, /* 19 ZMQ_BACKLOG */
--#endif
--};
--#if VERSION_2_1
--#define MAX_OPTS ZMQ_BACKLOG
--#else
--#define MAX_OPTS ZMQ_RCVMORE
-+
-+typedef struct ZMQ_Ctx ZMQ_Ctx;
-+
-+typedef struct ZMQ_StopWatch ZMQ_StopWatch;
-+
-+
-+
-+/* method: description */
-+static int ZErrors__description__meth(lua_State *L) {
-+ const char * msg1 = NULL;
-+ int err_type;
-+ int err_num = -1;
-+
-+ err_type = lua_type(L, 2);
-+ if(err_type == LUA_TSTRING) {
-+ lua_pushvalue(L, 2);
-+ lua_rawget(L, 1);
-+ if(lua_isnumber(L, -1)) {
-+ err_num = lua_tointeger(L, -1);
-+ }
-+ lua_pop(L, 1);
-+ } else if(err_type == LUA_TNUMBER) {
-+ err_num = lua_tointeger(L, 2);
-+ } else {
-+ return luaL_argerror(L, 2, "expected string/number");
-+ }
-+ if(err_num < 0) {
-+ lua_pushnil(L);
-+ lua_pushliteral(L, "UNKNOWN ERROR");
-+ return 2;
-+ }
-+ msg1 = strerror(err_num);
-+
-+ lua_pushstring(L, msg1);
-+ return 1;
-+}
-+
-+/* method: __index */
-+static int ZErrors____index__meth(lua_State *L) {
-+ int err2;
-+ const char * msg1 = NULL;
-+ err2 = luaL_checkinteger(L,2);
-+ switch(err2) {
-+ case EAGAIN:
-+ msg1 = "timeout";
-+ break;
-+ case EINTR:
-+ msg1 = "interrupted";
-+ break;
-+#if defined(ETERM)
-+ case ETERM:
-+ msg1 = "closed";
-+ break;
- #endif
-+ default:
-+ msg1 = zmq_strerror(err2);
-+ break;
-+ }
-+ lua_pushvalue(L, 2);
-+ lua_pushstring(L, msg1);
-+ lua_rawset(L, 1);
-
-+ lua_pushstring(L, msg1);
-+ return 1;
-+}
-
--static ZMQ_Error simple_zmq_send(ZMQ_Socket *sock, const char *data, size_t data_len, int flags) {
-- ZMQ_Error err;
-- zmq_msg_t msg;
-- /* initialize message */
-- err = zmq_msg_init_size(&msg, data_len);
-- if(0 == err) {
-+static void error_code__ZMQ_Error__push(lua_State *L, ZMQ_Error err) {
-+ const char *err_str = NULL;
-+ int num;
-+ if(-1 == err) {
-+ /* get ZErrors table. */
-+ lua_pushlightuserdata(L, zmq_ZErrors_key);
-+ lua_rawget(L, LUA_REGISTRYINDEX);
-+ /* convert zmq_errno to string. */
-+ num = zmq_errno();
-+ lua_pushinteger(L, num);
-+ lua_gettable(L, -2);
-+ /* remove ZErrors table. */
-+ lua_remove(L, -2);
-+ if(!lua_isnil(L, -1)) {
-+ /* found error. */
-+ return;
-+ }
-+ /* Unknown error. */
-+ lua_pop(L, 1);
-+ lua_pushfstring(L, "UNKNOWN ERROR(%d)", num);
-+ return;
-+ }
-+
-+ if(err_str) {
-+ lua_pushstring(L, err_str);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+}
-+
-+/* method: init */
-+static int zmq_msg_t__init__meth(lua_State *L) {
-+ zmq_msg_t this1_store;
-+ zmq_msg_t * this1 = &(this1_store);
-+ ZMQ_Error rc_zmq_msg_init2 = 0;
-+ rc_zmq_msg_init2 = zmq_msg_init(this1);
-+ if(!(-1 == rc_zmq_msg_init2)) {
-+ obj_type_zmq_msg_t_push(L, this1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_init2);
-+ return 2;
-+}
-+
-+/* method: init_size */
-+static int zmq_msg_t__init_size__meth(lua_State *L) {
-+ size_t size1;
-+ zmq_msg_t this1_store;
-+ zmq_msg_t * this1 = &(this1_store);
-+ ZMQ_Error rc_zmq_msg_init_size2 = 0;
-+ size1 = luaL_checkinteger(L,1);
-+ rc_zmq_msg_init_size2 = zmq_msg_init_size(this1, size1);
-+ if(!(-1 == rc_zmq_msg_init_size2)) {
-+ obj_type_zmq_msg_t_push(L, this1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_init_size2);
-+ return 2;
-+}
-+
-+/* method: init_data */
-+static int zmq_msg_t__init_data__meth(lua_State *L) {
-+ size_t data_len1;
-+ const char * data1;
-+ zmq_msg_t this1_store;
-+ zmq_msg_t * this1 = &(this1_store);
-+ ZMQ_Error err2 = 0;
-+ data1 = luaL_checklstring(L,1,&(data_len1));
-+ err2 = zmq_msg_init_size(this1, data_len1);
-+ if(0 == err2) {
- /* fill message */
-- memcpy(zmq_msg_data(&msg), data, data_len);
-- /* send message */
-- err = zmq_send(sock, &msg, flags);
-- /* close message */
-- zmq_msg_close(&msg);
-+ memcpy(zmq_msg_data(this1), data1, data_len1);
- }
-- return err;
-+
-+ if(!(-1 == err2)) {
-+ obj_type_zmq_msg_t_push(L, this1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, err2);
-+ return 2;
-+}
-+
-+/* method: _priv */
-+static int zmq_msg_t__delete__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ ZMQ_Error rc_zmq_msg_close1 = 0;
-+ this1 = obj_type_zmq_msg_t_delete(L,1);
-+ rc_zmq_msg_close1 = zmq_msg_close(this1);
-+ /* check for error. */
-+ if((-1 == rc_zmq_msg_close1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_close1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+
-+/* method: close */
-+static int zmq_msg_t__close__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ ZMQ_Error rc_zmq_msg_close1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ rc_zmq_msg_close1 = zmq_msg_close(this1);
-+ /* check for error. */
-+ if((-1 == rc_zmq_msg_close1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_close1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+
-+/* method: move */
-+static int zmq_msg_t__move__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ zmq_msg_t * src2;
-+ ZMQ_Error rc_zmq_msg_move1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ src2 = obj_type_zmq_msg_t_check(L,2);
-+ rc_zmq_msg_move1 = zmq_msg_move(this1, src2);
-+ /* check for error. */
-+ if((-1 == rc_zmq_msg_move1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_move1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+
-+/* method: copy */
-+static int zmq_msg_t__copy__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ zmq_msg_t * src2;
-+ ZMQ_Error rc_zmq_msg_copy1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ src2 = obj_type_zmq_msg_t_check(L,2);
-+ rc_zmq_msg_copy1 = zmq_msg_copy(this1, src2);
-+ /* check for error. */
-+ if((-1 == rc_zmq_msg_copy1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_msg_copy1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+
-+/* method: set_data */
-+static int zmq_msg_t__set_data__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ size_t data_len2;
-+ const char * data2;
-+ ZMQ_Error err1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ data2 = luaL_checklstring(L,2,&(data_len2));
-+ /* check message data size. */
-+ if(zmq_msg_size(this1) != data_len2) {
-+ /* need to resize message. */
-+ zmq_msg_close(this1); /* close old message, to free old data. */
-+ err1 = zmq_msg_init_size(this1, data_len2); /* re-initialize message. */
-+ if(0 != err1) {
-+ luaL_error(L, "set_data() failed: %s", get_zmq_strerror());
-+ }
-+ }
-+ /* copy data into message */
-+ memcpy(zmq_msg_data(this1), data2, data_len2);
-+
-+ /* check for error. */
-+ if((-1 == err1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, err1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+
-+/* method: data */
-+static int zmq_msg_t__data__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ void * rc_zmq_msg_data1 = NULL;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ rc_zmq_msg_data1 = zmq_msg_data(this1);
-+ lua_pushlightuserdata(L, rc_zmq_msg_data1);
-+ return 1;
-+}
-+
-+/* method: set_size */
-+static int zmq_msg_t__set_size__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ size_t size2;
-+ ZMQ_Error err1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ size2 = luaL_checkinteger(L,2);
-+ /* check message data size. */
-+ if(zmq_msg_size(this1) != size2) {
-+ /* need to resize message. */
-+ zmq_msg_close(this1); /* close old message, to free old data. */
-+ err1 = zmq_msg_init_size(this1, size2); /* re-initialize message. */
-+ if(0 != err1) {
-+ luaL_error(L, "set_size() failed: %s", get_zmq_strerror());
-+ }
-+ }
-+
-+ /* check for error. */
-+ if((-1 == err1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, err1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
- }
-
--struct ZMQ_Poller {
-- zmq_pollitem_t *items;
-- int next;
-- int count;
-- int free_list;
-- int len;
--};
-+/* method: size */
-+static int zmq_msg_t__size__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ size_t size1 = 0;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ size1 = zmq_msg_size(this1);
-+ lua_pushinteger(L, size1);
-+ return 1;
-+}
-
-+/* method: __tostring */
-+static int zmq_msg_t____tostring__meth(lua_State *L) {
-+ zmq_msg_t * this1;
-+ size_t data_len1 = 0;
-+ const char * data1 = NULL;
-+ this1 = obj_type_zmq_msg_t_check(L,1);
-+ data1 = zmq_msg_data(this1);
-+ data_len1 = zmq_msg_size(this1);
-
--typedef struct ZMQ_Poller ZMQ_Poller;
-+ if(data1 == NULL) lua_pushnil(L); else lua_pushlstring(L, data1,data_len1);
-+ return 1;
-+}
-
--#define FREE_ITEM_EVENTS_TAG ((short)0xFFFF)
-+/* method: close */
-+static int ZMQ_Socket__close__meth(lua_State *L) {
-+ int this_flags1 = 0;
-+ ZMQ_Socket * this1;
-+ ZMQ_Error rc_zmq_close1 = 0;
-+ this1 = obj_type_ZMQ_Socket_delete(L,1,&(this_flags1));
-+ if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
-+ rc_zmq_close1 = zmq_close(this1);
-+ /* check for error. */
-+ if((-1 == rc_zmq_close1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_close1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
--#define ITEM_TO_INDEX(items, item) (item - (items))
-+/* method: bind */
-+static int ZMQ_Socket__bind__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t addr_len2;
-+ const char * addr2;
-+ ZMQ_Error rc_zmq_bind1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ addr2 = luaL_checklstring(L,2,&(addr_len2));
-+ rc_zmq_bind1 = zmq_bind(this1, addr2);
-+ /* check for error. */
-+ if((-1 == rc_zmq_bind1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_bind1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
--static int poller_resize_items(ZMQ_Poller *poller, int len) {
-- int old_len = poller->len;
-+/* method: connect */
-+static int ZMQ_Socket__connect__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t addr_len2;
-+ const char * addr2;
-+ ZMQ_Error rc_zmq_connect1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ addr2 = luaL_checklstring(L,2,&(addr_len2));
-+ rc_zmq_connect1 = zmq_connect(this1, addr2);
-+ /* check for error. */
-+ if((-1 == rc_zmq_connect1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_connect1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
-- /* make sure new length is atleast as large as items count. */
-- len = (poller->count <= len) ? len : poller->count;
-+/* method: setopt */
-+static int ZMQ_Socket__setopt__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ uint32_t opt2;
-+ ZMQ_Error err1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ opt2 = luaL_checkinteger(L,2);
-+ size_t val_len;
-+ const void *val;
-
-- /* if the new length is the same as the old length, then don't try to resize. */
-- if(old_len == len) return len;
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
-+ socket_t fd_val;
-+#endif
-+ int int_val;
-+ uint32_t uint32_val;
-+ uint64_t uint64_val;
-+ int64_t int64_val;
-
-- poller->items = (zmq_pollitem_t *)realloc(poller->items, len * sizeof(zmq_pollitem_t));
-- poller->len = len;
-- if(len > old_len) {
-- /* clear new space. */
-- memset(&(poller->items[old_len]), 0, (len - old_len) * sizeof(zmq_pollitem_t));
-+#if VERSION_3_0
-+ /* 3.0 backwards compatibility support for HWM. */
-+ if(opt2 == ZMQ_HWM) {
-+ int_val = luaL_checklong(L, 3);
-+ val = &int_val;
-+ val_len = sizeof(int_val);
-+ err1 = zmq_setsockopt(this1, ZMQ_SNDHWM, val, val_len);
-+ if(-1 != err1) {
-+ err1 = zmq_setsockopt(this1, ZMQ_RCVHWM, val, val_len);
-+ }
-+ goto finished;
- }
-- return len;
--}
--
--static int poller_find_sock_item(ZMQ_Poller *poller, ZMQ_Socket *sock) {
-- zmq_pollitem_t *items;
-- int count;
-- int n;
-+#endif
-
-- /* find ZMQ_Socket */
-- items = poller->items;
-- count = poller->count;
-- for(n=0; n < count; n++) {
-- if(items[n].socket == sock) return n;
-+ if(opt2 > MAX_OPTS) {
-+ return luaL_argerror(L, 2, "Invalid socket option.");
- }
-- /* not found. */
-- return -1;
--}
--
--static int poller_find_fd_item(ZMQ_Poller *poller, socket_t fd) {
-- zmq_pollitem_t *items;
-- int count;
-- int n;
-
-- /* find fd */
-- items = poller->items;
-- count = poller->count;
-- for(n=0; n < count; n++) {
-- if(items[n].fd == fd) return n;
-+ switch(opt_types[opt2]) {
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
-+ case OPT_TYPE_FD:
-+ fd_val = luaL_checklong(L, 3);
-+ val = &fd_val;
-+ val_len = sizeof(fd_val);
-+ break;
-+#endif
-+ case OPT_TYPE_INT:
-+ int_val = luaL_checklong(L, 3);
-+ val = &int_val;
-+ val_len = sizeof(int_val);
-+ break;
-+ case OPT_TYPE_UINT32:
-+ uint32_val = luaL_checklong(L, 3);
-+ val = &uint32_val;
-+ val_len = sizeof(uint32_val);
-+ break;
-+ case OPT_TYPE_UINT64:
-+ uint64_val = luaL_checklong(L, 3);
-+ val = &uint64_val;
-+ val_len = sizeof(uint64_val);
-+ break;
-+ case OPT_TYPE_INT64:
-+ int64_val = luaL_checklong(L, 3);
-+ val = &int64_val;
-+ val_len = sizeof(int64_val);
-+ break;
-+ case OPT_TYPE_BLOB:
-+ val = luaL_checklstring(L, 3, &(val_len));
-+ break;
-+ default:
-+ printf("Invalid socket option type, this shouldn't happen.\n");
-+ abort();
-+ break;
- }
-- /* not found. */
-- return -1;
--}
-+ err1 = zmq_setsockopt(this1, opt2, val, val_len);
-+finished:
-
--static void poller_remove_item(ZMQ_Poller *poller, int idx) {
-- zmq_pollitem_t *items;
-- int free_list;
-- int count;
-+ /* check for error. */
-+ if((-1 == err1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, err1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
-- count = poller->count;
-- /* no item to remove. */
-- if(idx >= count || count == 0) return;
-+/* method: getopt */
-+static int ZMQ_Socket__getopt__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ uint32_t opt2;
-+ ZMQ_Error err2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ opt2 = luaL_checkinteger(L,2);
-+ size_t val_len;
-
-- items = poller->items;
-- free_list = poller->free_list;
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
-+ socket_t fd_val;
-+#endif
-+ int int_val;
-+ uint32_t uint32_val;
-+ uint64_t uint64_val;
-+ int64_t int64_val;
-+#define STR_MAX 255
-+ char str_val[STR_MAX];
-
-- /* link new free slot to head of free list. */
-- if(free_list >= 0 && free_list < count) {
-- /* use socket pointer for free list's 'next' field. */
-- items[idx].socket = &(items[free_list]);
-- } else {
-- /* free list is empty mark poller slot as the end. */
-- items[idx].socket = NULL;
-+ if(opt2 > MAX_OPTS) {
-+ lua_pushnil(L);
-+ lua_pushliteral(L, "Invalid socket option.");
-+ return 2;
- }
-- poller->free_list = idx;
-- /* mark poller slot as a free slot. */
-- items[idx].events = FREE_ITEM_EVENTS_TAG;
-- /* clear old revents. */
-- items[idx].revents = 0;
--}
-
--static int poller_get_free_item(ZMQ_Poller *poller) {
-- zmq_pollitem_t *curr;
-- zmq_pollitem_t *next;
-- int count;
-- int idx;
--
-- count = poller->count;
-- idx = poller->free_list;
-- /* check for a free slot in the free list. */
-- if(idx >= 0 && idx < count) {
-- /* remove free slot from free list. */
-- curr = &(poller->items[idx]);
-- /* valid free slot. */
-- assert(curr->events == FREE_ITEM_EVENTS_TAG);
-- /* is poller the last free slot? */
-- next = ((zmq_pollitem_t *)curr->socket);
-- if(next != NULL) {
-- /* set next free slot as head of free list. */
-- poller->free_list = ITEM_TO_INDEX(poller->items, next);
-- } else {
-- /* free list is empty now. */
-- poller->free_list = -1;
-+ switch(opt_types[opt2]) {
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
-+ case OPT_TYPE_FD:
-+ val_len = sizeof(fd_val);
-+ err2 = zmq_getsockopt(this1, opt2, &fd_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushinteger(L, (lua_Integer)fd_val);
-+ return 1;
-+ }
-+ break;
-+#endif
-+ case OPT_TYPE_INT:
-+ val_len = sizeof(int_val);
-+ err2 = zmq_getsockopt(this1, opt2, &int_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushinteger(L, (lua_Integer)int_val);
-+ return 1;
-+ }
-+ break;
-+ case OPT_TYPE_UINT32:
-+ val_len = sizeof(uint32_val);
-+ err2 = zmq_getsockopt(this1, opt2, &uint32_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushinteger(L, (lua_Integer)uint32_val);
-+ return 1;
-+ }
-+ break;
-+ case OPT_TYPE_UINT64:
-+ val_len = sizeof(uint64_val);
-+ err2 = zmq_getsockopt(this1, opt2, &uint64_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushinteger(L, (lua_Integer)uint64_val);
-+ return 1;
- }
-- /* clear slot */
-- memset(curr, 0, sizeof(zmq_pollitem_t));
-- return idx;
-+ break;
-+ case OPT_TYPE_INT64:
-+ val_len = sizeof(int64_val);
-+ err2 = zmq_getsockopt(this1, opt2, &int64_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushinteger(L, (lua_Integer)int64_val);
-+ return 1;
-+ }
-+ break;
-+ case OPT_TYPE_BLOB:
-+ val_len = STR_MAX;
-+ err2 = zmq_getsockopt(this1, opt2, str_val, &val_len);
-+ if(0 == err2) {
-+ lua_pushlstring(L, str_val, val_len);
-+ return 1;
-+ }
-+#undef STR_MAX
-+ break;
-+ default:
-+ printf("Invalid socket option type, this shouldn't happen.\n");
-+ abort();
-+ break;
- }
-+ lua_pushnil(L);
-
-- idx = count;
-- poller->count = ++count;
-- /* make room for new item. */
-- if(count >= poller->len) {
-- poller_resize_items(poller, poller->len + 10);
-- }
-- return idx;
-+ error_code__ZMQ_Error__push(L, err2);
-+ return 2;
- }
-
--static int poller_compact_items(ZMQ_Poller *poller) {
-- zmq_pollitem_t *items;
-- int count;
-- int old_count;
-- int next;
-+/* method: send_msg */
-+static int ZMQ_Socket__send_msg__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ zmq_msg_t * msg2;
-+ int flags3;
-+ ZMQ_Error rc_zmq_sendmsg1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ msg2 = obj_type_zmq_msg_t_check(L,2);
-+ flags3 = luaL_optinteger(L,3,0);
-+ rc_zmq_sendmsg1 = zmq_sendmsg(this1, msg2, flags3);
-+ /* check for error. */
-+ if((-1 == rc_zmq_sendmsg1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_sendmsg1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
-- count = poller->count;
-- /* if no free slot, then return. */
-- if(poller->free_list < 0) return count;
-- old_count = count;
-+/* method: send */
-+static int ZMQ_Socket__send__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t data_len2;
-+ const char * data2;
-+ int flags3;
-+ ZMQ_Error rc_simple_zmq_send1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ data2 = luaL_checklstring(L,2,&(data_len2));
-+ flags3 = luaL_optinteger(L,3,0);
-+ rc_simple_zmq_send1 = simple_zmq_send(this1, data2, data_len2, flags3);
-+ /* check for error. */
-+ if((-1 == rc_simple_zmq_send1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_simple_zmq_send1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
-- items = poller->items;
-- next = 0;
-- /* find first free slot. */
-- while(next < count && items[next].events != FREE_ITEM_EVENTS_TAG) {
-- ++next;
-- }
-+/* method: recv_msg */
-+static int ZMQ_Socket__recv_msg__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ zmq_msg_t * msg2;
-+ int flags3;
-+ ZMQ_Error rc_zmq_recvmsg1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ msg2 = obj_type_zmq_msg_t_check(L,2);
-+ flags3 = luaL_optinteger(L,3,0);
-+ rc_zmq_recvmsg1 = zmq_recvmsg(this1, msg2, flags3);
-+ /* check for error. */
-+ if((-1 == rc_zmq_recvmsg1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_zmq_recvmsg1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-
-- /* move non-free slots into free slot. */
-- count = next;
-- ++next;
-- while(next < old_count) {
-- if(items[next].events != FREE_ITEM_EVENTS_TAG) {
-- /* found non-free slot, move it to the current free slot. */
-- items[count] = items[next];
-- ++count;
-+/* method: recv */
-+static int ZMQ_Socket__recv__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int flags2;
-+ size_t data_len1 = 0;
-+ const char * data1 = NULL;
-+ ZMQ_Error err2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ flags2 = luaL_optinteger(L,2,0);
-+ zmq_msg_t msg;
-+ /* initialize message */
-+ err2 = zmq_msg_init(&msg);
-+ if(0 == err2) {
-+ /* receive message */
-+ err2 = zmq_recvmsg(this1, &msg, flags2);
-+ if(err2 >= 0) {
-+ data1 = zmq_msg_data(&msg);
-+ data_len1 = zmq_msg_size(&msg);
- }
-- ++next;
- }
-
-- /* clear old used-space */
-- memset(&(items[count]), 0, ((old_count - count) * sizeof(zmq_pollitem_t)));
-- poller->count = count;
-- poller->free_list = -1; /* free list is now empty. */
-+ if(!(-1 == err2)) {
-+ if(data1 == NULL) lua_pushnil(L); else lua_pushlstring(L, data1,data_len1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, err2);
-+ /* close message */
-+ zmq_msg_close(&msg);
-
-- assert(count <= poller->len);
-- return count;
-+ return 2;
- }
-
--static int poller_poll(ZMQ_Poller *poller, long timeout) {
-- int count;
-- /* remove free slots from items list. */
-- count = poller_compact_items(poller);
-- /* poll for events. */
-- return zmq_poll(poller->items, count, timeout);
-+/* method: hwm */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__hwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_hwm2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_hwm2 = lzmq_socket_hwm(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_hwm2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_hwm2);
-+ return 2;
- }
-+#endif
-
-+/* method: set_hwm */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_hwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_hwm1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_hwm1 = lzmq_socket_set_hwm(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_hwm1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_hwm1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
--typedef struct ZMQ_Ctx ZMQ_Ctx;
-+/* method: swap */
-+#if (VERSION_2_0)
-+static int ZMQ_Socket__swap__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_swap2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_swap2 = lzmq_socket_swap(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_swap2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_swap2);
-+ return 2;
-+}
-+#endif
-
--typedef struct ZMQ_StopWatch ZMQ_StopWatch;
-+/* method: set_swap */
-+#if (VERSION_2_0)
-+static int ZMQ_Socket__set_swap__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_swap1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_swap1 = lzmq_socket_set_swap(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_swap1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_swap1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
--/*
-- * This wrapper function is to make the EAGAIN/ETERM error messages more like
-- * what is returned by LuaSocket.
-- */
--static const char *get_zmq_strerror() {
-- int err = zmq_errno();
-- switch(err) {
-- case EAGAIN:
-- return "timeout";
-- break;
--#if defined(ETERM)
-- case ETERM:
-- return "closed";
-- break;
-+/* method: affinity */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__affinity__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ uint64_t value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_affinity2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_affinity2 = lzmq_socket_affinity(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_affinity2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_affinity2);
-+ return 2;
-+}
- #endif
-- default:
-- break;
-- }
-- return zmq_strerror(err);
-+
-+/* method: set_affinity */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_affinity__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ uint64_t value2;
-+ ZMQ_Error rc_lzmq_socket_set_affinity1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_affinity1 = lzmq_socket_set_affinity(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_affinity1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_affinity1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-+
-+/* method: identity */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__identity__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t value_len1 = 0;
-+ char * value1 = NULL;
-+ ZMQ_Error rc_lzmq_socket_identity2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_identity2 = lzmq_socket_identity(this1, value1, &(value_len1));
-+ if(!(-1 == rc_lzmq_socket_identity2)) {
-+ if(value1 == NULL) lua_pushnil(L); else lua_pushlstring(L, value1,value_len1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_identity2);
-+ return 2;
- }
-+#endif
-
-+/* method: set_identity */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_identity__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t value_len2;
-+ const char * value2;
-+ ZMQ_Error rc_lzmq_socket_set_identity1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checklstring(L,2,&(value_len2));
-+ rc_lzmq_socket_set_identity1 = lzmq_socket_set_identity(this1, value2, value_len2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_identity1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_identity1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
-+/* method: subscribe */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__subscribe__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t value_len2;
-+ const char * value2;
-+ ZMQ_Error rc_lzmq_socket_subscribe1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checklstring(L,2,&(value_len2));
-+ rc_lzmq_socket_subscribe1 = lzmq_socket_subscribe(this1, value2, value_len2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_subscribe1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_subscribe1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
-+/* method: unsubscribe */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__unsubscribe__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ size_t value_len2;
-+ const char * value2;
-+ ZMQ_Error rc_lzmq_socket_unsubscribe1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checklstring(L,2,&(value_len2));
-+ rc_lzmq_socket_unsubscribe1 = lzmq_socket_unsubscribe(this1, value2, value_len2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_unsubscribe1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_unsubscribe1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
--static void error_code__ZMQ_Error__push(lua_State *L, ZMQ_Error err) {
-- const char *err_str = NULL;
-- if(-1 == err) {
-- err_str = get_zmq_strerror();
-- }
-+/* method: rate */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__rate__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_rate2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_rate2 = lzmq_socket_rate(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_rate2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_rate2);
-+ return 2;
-+}
-+#endif
-
-- if(err_str) {
-- lua_pushstring(L, err_str);
-- } else {
-- lua_pushnil(L);
-- }
-+/* method: set_rate */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_rate__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_rate1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_rate1 = lzmq_socket_set_rate(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_rate1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_rate1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
- }
-+#endif
-
--/* method: init */
--static int zmq_msg_t__init__meth(lua_State *L) {
-- int this_flags1 = OBJ_UDATA_FLAG_OWN;
-- zmq_msg_t * this1;
-- ZMQ_Error err2 = 0;
-- zmq_msg_t tmp;
-- this1 = &tmp;
-- err2 = zmq_msg_init(this1);
-+/* method: recovery_ivl */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__recovery_ivl__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_recovery_ivl2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_recovery_ivl2 = lzmq_socket_recovery_ivl(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_recovery_ivl2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_recovery_ivl2);
-+ return 2;
-+}
-+#endif
-
-- if(!(-1 == err2)) {
-- obj_type_zmq_msg_t_push(L, this1, this_flags1);
-+/* method: set_recovery_ivl */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_recovery_ivl__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_recovery_ivl1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_recovery_ivl1 = lzmq_socket_set_recovery_ivl(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_recovery_ivl1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_recovery_ivl1);
- } else {
-+ lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
-- error_code__ZMQ_Error__push(L, err2);
- return 2;
- }
-+#endif
-
--/* method: init_size */
--static int zmq_msg_t__init_size__meth(lua_State *L) {
-- size_t size1 = luaL_checkinteger(L,1);
-- int this_flags1 = OBJ_UDATA_FLAG_OWN;
-- zmq_msg_t * this1;
-- ZMQ_Error err2 = 0;
-- zmq_msg_t tmp;
-- this1 = &tmp;
-- err2 = zmq_msg_init_size(this1, size1);
--
-- if(!(-1 == err2)) {
-- obj_type_zmq_msg_t_push(L, this1, this_flags1);
-+/* method: mcast_loop */
-+#if (VERSION_2_0)
-+static int ZMQ_Socket__mcast_loop__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_mcast_loop2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_mcast_loop2 = lzmq_socket_mcast_loop(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_mcast_loop2)) {
-+ lua_pushinteger(L, value1);
- } else {
- lua_pushnil(L);
- }
-- error_code__ZMQ_Error__push(L, err2);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_mcast_loop2);
- return 2;
- }
-+#endif
-
--/* method: init_data */
--static int zmq_msg_t__init_data__meth(lua_State *L) {
-- size_t data_len1;
-- const char * data1 = luaL_checklstring(L,1,&(data_len1));
-- int this_flags1 = OBJ_UDATA_FLAG_OWN;
-- zmq_msg_t * this1;
-- ZMQ_Error err2 = 0;
-- zmq_msg_t tmp;
-- this1 = &tmp;
-- err2 = zmq_msg_init_size(this1, data_len1);
-- if(0 == err2) {
-- /* fill message */
-- memcpy(zmq_msg_data(this1), data1, data_len1);
-- }
-+/* method: set_mcast_loop */
-+#if (VERSION_2_0)
-+static int ZMQ_Socket__set_mcast_loop__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_mcast_loop1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_mcast_loop1 = lzmq_socket_set_mcast_loop(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_mcast_loop1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_mcast_loop1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
-+#endif
-
-- if(!(-1 == err2)) {
-- obj_type_zmq_msg_t_push(L, this1, this_flags1);
-+/* method: sndbuf */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__sndbuf__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_sndbuf2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_sndbuf2 = lzmq_socket_sndbuf(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_sndbuf2)) {
-+ lua_pushinteger(L, value1);
- } else {
- lua_pushnil(L);
- }
-- error_code__ZMQ_Error__push(L, err2);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_sndbuf2);
- return 2;
- }
-+#endif
-
--/* method: delete */
--static int zmq_msg_t__delete__meth(lua_State *L) {
-- int this_flags1 = 0;
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_delete(L,1,&(this_flags1));
-- ZMQ_Error rc_zmq_msg_close1 = 0;
-- if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
-- rc_zmq_msg_close1 = zmq_msg_close(this1);
-+/* method: set_sndbuf */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_sndbuf__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_sndbuf1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_sndbuf1 = lzmq_socket_set_sndbuf(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_msg_close1)) {
-+ if((-1 == rc_lzmq_socket_set_sndbuf1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_msg_close1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_sndbuf1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: close */
--static int zmq_msg_t__close__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- ZMQ_Error rc_zmq_msg_close1 = 0;
-- rc_zmq_msg_close1 = zmq_msg_close(this1);
-+/* method: rcvbuf */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__rcvbuf__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_rcvbuf2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_rcvbuf2 = lzmq_socket_rcvbuf(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_rcvbuf2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_rcvbuf2);
-+ return 2;
-+}
-+#endif
-+
-+/* method: set_rcvbuf */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__set_rcvbuf__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_rcvbuf1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_rcvbuf1 = lzmq_socket_set_rcvbuf(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_msg_close1)) {
-+ if((-1 == rc_lzmq_socket_set_rcvbuf1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_msg_close1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_rcvbuf1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: move */
--static int zmq_msg_t__move__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- zmq_msg_t * src2 = obj_type_zmq_msg_t_check(L,2);
-- ZMQ_Error rc_zmq_msg_move1 = 0;
-- rc_zmq_msg_move1 = zmq_msg_move(this1, src2);
-- /* check for error. */
-- if((-1 == rc_zmq_msg_move1)) {
-+/* method: rcvmore */
-+#if (VERSION_2_0|VERSION_3_0)
-+static int ZMQ_Socket__rcvmore__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_rcvmore2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_rcvmore2 = lzmq_socket_rcvmore(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_rcvmore2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_msg_move1);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_rcvmore2);
-+ return 2;
-+}
-+#endif
-+
-+/* method: fd */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__fd__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_fd2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_fd2 = lzmq_socket_fd(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_fd2)) {
-+ lua_pushinteger(L, value1);
- } else {
-- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_fd2);
- return 2;
- }
-+#endif
-
--/* method: copy */
--static int zmq_msg_t__copy__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- zmq_msg_t * src2 = obj_type_zmq_msg_t_check(L,2);
-- ZMQ_Error rc_zmq_msg_copy1 = 0;
-- rc_zmq_msg_copy1 = zmq_msg_copy(this1, src2);
-- /* check for error. */
-- if((-1 == rc_zmq_msg_copy1)) {
-+/* method: events */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__events__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_events2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_events2 = lzmq_socket_events(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_events2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_msg_copy1);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_events2);
-+ return 2;
-+}
-+#endif
-+
-+/* method: type */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__type__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_type2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_type2 = lzmq_socket_type(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_type2)) {
-+ lua_pushinteger(L, value1);
- } else {
-- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_type2);
- return 2;
- }
-+#endif
-
--/* method: set_data */
--static int zmq_msg_t__set_data__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- size_t data_len2;
-- const char * data2 = luaL_checklstring(L,2,&(data_len2));
-- ZMQ_Error err1 = 0;
-- /* check message data size. */
-- if(zmq_msg_size(this1) != data_len2) {
-- /* need to resize message. */
-- zmq_msg_close(this1); /* close old message, to free old data. */
-- err1 = zmq_msg_init_size(this1, data_len2); /* re-initialize message. */
-- if(0 != err1) {
-- luaL_error(L, "set_data() failed: %s", get_zmq_strerror());
-- }
-- }
-- /* copy data into message */
-- memcpy(zmq_msg_data(this1), data2, data_len2);
-+/* method: linger */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__linger__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_linger2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_linger2 = lzmq_socket_linger(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_linger2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_linger2);
-+ return 2;
-+}
-+#endif
-
-+/* method: set_linger */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__set_linger__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_linger1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_linger1 = lzmq_socket_set_linger(this1, value2);
- /* check for error. */
-- if((-1 == err1)) {
-+ if((-1 == rc_lzmq_socket_set_linger1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, err1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_linger1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: data */
--static int zmq_msg_t__data__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- void * rc_zmq_msg_data1 = NULL;
-- rc_zmq_msg_data1 = zmq_msg_data(this1);
-- lua_pushlightuserdata(L, rc_zmq_msg_data1);
-- return 1;
-+/* method: reconnect_ivl */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__reconnect_ivl__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_reconnect_ivl2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_reconnect_ivl2 = lzmq_socket_reconnect_ivl(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_reconnect_ivl2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_reconnect_ivl2);
-+ return 2;
- }
-+#endif
-
--/* method: set_size */
--static int zmq_msg_t__set_size__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- size_t size2 = luaL_checkinteger(L,2);
-- ZMQ_Error err1 = 0;
-- /* check message data size. */
-- if(zmq_msg_size(this1) != size2) {
-- /* need to resize message. */
-- zmq_msg_close(this1); /* close old message, to free old data. */
-- err1 = zmq_msg_init_size(this1, size2); /* re-initialize message. */
-- if(0 != err1) {
-- luaL_error(L, "set_size() failed: %s", get_zmq_strerror());
-- }
-- }
--
-+/* method: set_reconnect_ivl */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__set_reconnect_ivl__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_reconnect_ivl1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_reconnect_ivl1 = lzmq_socket_set_reconnect_ivl(this1, value2);
- /* check for error. */
-- if((-1 == err1)) {
-+ if((-1 == rc_lzmq_socket_set_reconnect_ivl1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, err1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_reconnect_ivl1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: size */
--static int zmq_msg_t__size__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- size_t rc_zmq_msg_size1 = 0;
-- rc_zmq_msg_size1 = zmq_msg_size(this1);
-- lua_pushinteger(L, rc_zmq_msg_size1);
-- return 1;
--}
--
--/* method: __tostring */
--static int zmq_msg_t____tostring__meth(lua_State *L) {
-- zmq_msg_t * this1 = obj_type_zmq_msg_t_check(L,1);
-- size_t data_len1 = 0;
-- const char * data1 = NULL;
-- data1 = zmq_msg_data(this1);
-- data_len1 = zmq_msg_size(this1);
--
-- if(data1 == NULL) lua_pushnil(L); else lua_pushlstring(L, data1,data_len1);
-- return 1;
-+/* method: backlog */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__backlog__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_backlog2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_backlog2 = lzmq_socket_backlog(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_backlog2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_backlog2);
-+ return 2;
- }
-+#endif
-
--/* method: close */
--static int ZMQ_Socket__close__meth(lua_State *L) {
-- int this_flags1 = 0;
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_delete(L,1,&(this_flags1));
-- ZMQ_Error rc_zmq_close1 = 0;
-- if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
-- rc_zmq_close1 = zmq_close(this1);
-+/* method: set_backlog */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__set_backlog__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_backlog1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_backlog1 = lzmq_socket_set_backlog(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_close1)) {
-+ if((-1 == rc_lzmq_socket_set_backlog1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_close1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_backlog1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: bind */
--static int ZMQ_Socket__bind__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- size_t addr_len2;
-- const char * addr2 = luaL_checklstring(L,2,&(addr_len2));
-- ZMQ_Error rc_zmq_bind1 = 0;
-- rc_zmq_bind1 = zmq_bind(this1, addr2);
-+/* method: recovery_ivl_msec */
-+#if (VERSION_2_1)
-+static int ZMQ_Socket__recovery_ivl_msec__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int64_t value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_recovery_ivl_msec2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_recovery_ivl_msec2 = lzmq_socket_recovery_ivl_msec(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_recovery_ivl_msec2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_recovery_ivl_msec2);
-+ return 2;
-+}
-+#endif
-+
-+/* method: set_recovery_ivl_msec */
-+#if (VERSION_2_1)
-+static int ZMQ_Socket__set_recovery_ivl_msec__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int64_t value2;
-+ ZMQ_Error rc_lzmq_socket_set_recovery_ivl_msec1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_recovery_ivl_msec1 = lzmq_socket_set_recovery_ivl_msec(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_bind1)) {
-+ if((-1 == rc_lzmq_socket_set_recovery_ivl_msec1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_bind1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_recovery_ivl_msec1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: connect */
--static int ZMQ_Socket__connect__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- size_t addr_len2;
-- const char * addr2 = luaL_checklstring(L,2,&(addr_len2));
-- ZMQ_Error rc_zmq_connect1 = 0;
-- rc_zmq_connect1 = zmq_connect(this1, addr2);
-+/* method: reconnect_ivl_max */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__reconnect_ivl_max__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_reconnect_ivl_max2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_reconnect_ivl_max2 = lzmq_socket_reconnect_ivl_max(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_reconnect_ivl_max2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_reconnect_ivl_max2);
-+ return 2;
-+}
-+#endif
-+
-+/* method: set_reconnect_ivl_max */
-+#if (VERSION_2_1|VERSION_3_0)
-+static int ZMQ_Socket__set_reconnect_ivl_max__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_reconnect_ivl_max1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_reconnect_ivl_max1 = lzmq_socket_set_reconnect_ivl_max(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_connect1)) {
-+ if((-1 == rc_lzmq_socket_set_reconnect_ivl_max1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_connect1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_reconnect_ivl_max1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
--
--/* method: setopt */
--static int ZMQ_Socket__setopt__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- uint32_t opt2 = luaL_checkinteger(L,2);
-- ZMQ_Error err1 = 0;
-- size_t val_len;
-- const void *val;
--
--#if VERSION_2_1
-- socket_t fd_val;
- #endif
-- int int_val;
-- uint32_t uint32_val;
-- uint64_t uint64_val;
-- int64_t int64_val;
--
-- if(opt2 > MAX_OPTS) {
-- return luaL_argerror(L, 2, "Invalid socket option.");
-- }
-
-- switch(opt_types[opt2]) {
--#if VERSION_2_1
-- case OPT_TYPE_FD:
-- fd_val = luaL_checklong(L, 3);
-- val = &fd_val;
-- val_len = sizeof(fd_val);
-- break;
-+/* method: maxmsgsize */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__maxmsgsize__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int64_t value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_maxmsgsize2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_maxmsgsize2 = lzmq_socket_maxmsgsize(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_maxmsgsize2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_maxmsgsize2);
-+ return 2;
-+}
- #endif
-- case OPT_TYPE_INT:
-- int_val = luaL_checklong(L, 3);
-- val = &int_val;
-- val_len = sizeof(int_val);
-- break;
-- case OPT_TYPE_UINT32:
-- uint32_val = luaL_checklong(L, 3);
-- val = &uint32_val;
-- val_len = sizeof(uint32_val);
-- break;
-- case OPT_TYPE_UINT64:
-- uint64_val = luaL_checklong(L, 3);
-- val = &uint64_val;
-- val_len = sizeof(uint64_val);
-- break;
-- case OPT_TYPE_INT64:
-- int64_val = luaL_checklong(L, 3);
-- val = &int64_val;
-- val_len = sizeof(int64_val);
-- break;
-- case OPT_TYPE_STR:
-- val = luaL_checklstring(L, 3, &(val_len));
-- break;
-- default:
-- printf("Invalid socket option type, this shouldn't happen.\n");
-- abort();
-- break;
-- }
-- err1 = zmq_setsockopt(this1, opt2, val, val_len);
-
-+/* method: set_maxmsgsize */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__set_maxmsgsize__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int64_t value2;
-+ ZMQ_Error rc_lzmq_socket_set_maxmsgsize1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_maxmsgsize1 = lzmq_socket_set_maxmsgsize(this1, value2);
- /* check for error. */
-- if((-1 == err1)) {
-+ if((-1 == rc_lzmq_socket_set_maxmsgsize1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, err1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_maxmsgsize1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
--
--/* method: getopt */
--static int ZMQ_Socket__getopt__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- uint32_t opt2 = luaL_checkinteger(L,2);
-- ZMQ_Error err2 = 0;
-- size_t val_len;
--
--#if VERSION_2_1
-- socket_t fd_val;
- #endif
-- int int_val;
-- uint32_t uint32_val;
-- uint64_t uint64_val;
-- int64_t int64_val;
--#define STR_MAX 255
-- char str_val[STR_MAX];
-
-- if(opt2 > MAX_OPTS) {
-- lua_pushnil(L);
-- lua_pushliteral(L, "Invalid socket option.");
-- return 2;
-- }
-+/* method: sndhwm */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__sndhwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_sndhwm2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_sndhwm2 = lzmq_socket_sndhwm(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_sndhwm2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_sndhwm2);
-+ return 2;
-+}
-+#endif
-
-- switch(opt_types[opt2]) {
--#if VERSION_2_1
-- case OPT_TYPE_FD:
-- val_len = sizeof(fd_val);
-- err2 = zmq_getsockopt(this1, opt2, &fd_val, &val_len);
-- if(0 == err2) {
-- lua_pushinteger(L, (lua_Integer)fd_val);
-- return 1;
-- }
-- break;
-+/* method: set_sndhwm */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__set_sndhwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_sndhwm1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_sndhwm1 = lzmq_socket_set_sndhwm(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_sndhwm1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_sndhwm1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
- #endif
-- case OPT_TYPE_INT:
-- val_len = sizeof(int_val);
-- err2 = zmq_getsockopt(this1, opt2, &int_val, &val_len);
-- if(0 == err2) {
-- lua_pushinteger(L, (lua_Integer)int_val);
-- return 1;
-- }
-- break;
-- case OPT_TYPE_UINT32:
-- val_len = sizeof(uint32_val);
-- err2 = zmq_getsockopt(this1, opt2, &uint32_val, &val_len);
-- if(0 == err2) {
-- lua_pushinteger(L, (lua_Integer)uint32_val);
-- return 1;
-- }
-- break;
-- case OPT_TYPE_UINT64:
-- val_len = sizeof(uint64_val);
-- err2 = zmq_getsockopt(this1, opt2, &uint64_val, &val_len);
-- if(0 == err2) {
-- lua_pushinteger(L, (lua_Integer)uint64_val);
-- return 1;
-- }
-- break;
-- case OPT_TYPE_INT64:
-- val_len = sizeof(int64_val);
-- err2 = zmq_getsockopt(this1, opt2, &int64_val, &val_len);
-- if(0 == err2) {
-- lua_pushinteger(L, (lua_Integer)int64_val);
-- return 1;
-- }
-- break;
-- case OPT_TYPE_STR:
-- val_len = STR_MAX;
-- err2 = zmq_getsockopt(this1, opt2, str_val, &val_len);
-- if(0 == err2) {
-- lua_pushlstring(L, str_val, val_len);
-- return 1;
-- }
--#undef STR_MAX
-- break;
-- default:
-- printf("Invalid socket option type, this shouldn't happen.\n");
-- abort();
-- break;
-- }
-- lua_pushnil(L);
-
-- error_code__ZMQ_Error__push(L, err2);
-+/* method: rcvhwm */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__rcvhwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_rcvhwm2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_rcvhwm2 = lzmq_socket_rcvhwm(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_rcvhwm2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_rcvhwm2);
- return 2;
- }
-+#endif
-
--/* method: events */
--static int ZMQ_Socket__events__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- uint32_t events1 = 0;
-- ZMQ_Error err2 = 0;
--#if VERSION_2_1
-- size_t val_len = sizeof(events1);
-- err2 = zmq_getsockopt(this1, ZMQ_EVENTS, &(events1), &val_len);
--#else
-- luaL_error(L, "'events' method only supported in 0MQ version >= 2.1");
-+/* method: set_rcvhwm */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__set_rcvhwm__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_rcvhwm1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_rcvhwm1 = lzmq_socket_set_rcvhwm(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_rcvhwm1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_rcvhwm1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
-+ return 2;
-+}
- #endif
-
-- if(!(-1 == err2)) {
-- lua_pushinteger(L, events1);
-+/* method: multicast_hops */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__multicast_hops__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_multicast_hops2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_multicast_hops2 = lzmq_socket_multicast_hops(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_multicast_hops2)) {
-+ lua_pushinteger(L, value1);
- } else {
- lua_pushnil(L);
- }
-- error_code__ZMQ_Error__push(L, err2);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_multicast_hops2);
- return 2;
- }
-+#endif
-
--/* method: send_msg */
--static int ZMQ_Socket__send_msg__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- zmq_msg_t * msg2 = obj_type_zmq_msg_t_check(L,2);
-- int flags3 = luaL_optinteger(L,3,0);
-- ZMQ_Error rc_zmq_send1 = 0;
-- rc_zmq_send1 = zmq_send(this1, msg2, flags3);
-+/* method: set_multicast_hops */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__set_multicast_hops__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_multicast_hops1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_multicast_hops1 = lzmq_socket_set_multicast_hops(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_send1)) {
-+ if((-1 == rc_lzmq_socket_set_multicast_hops1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_send1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_multicast_hops1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: send */
--static int ZMQ_Socket__send__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- size_t data_len2;
-- const char * data2 = luaL_checklstring(L,2,&(data_len2));
-- int flags3 = luaL_optinteger(L,3,0);
-- ZMQ_Error err1 = 0;
-- err1 = simple_zmq_send(this1, data2, data_len2, flags3);
-+/* method: rcvtimeo */
-+#if (VERSION_2_2|VERSION_3_0)
-+static int ZMQ_Socket__rcvtimeo__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_rcvtimeo2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_rcvtimeo2 = lzmq_socket_rcvtimeo(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_rcvtimeo2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_rcvtimeo2);
-+ return 2;
-+}
-+#endif
-
-+/* method: set_rcvtimeo */
-+#if (VERSION_2_2|VERSION_3_0)
-+static int ZMQ_Socket__set_rcvtimeo__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_rcvtimeo1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_rcvtimeo1 = lzmq_socket_set_rcvtimeo(this1, value2);
- /* check for error. */
-- if((-1 == err1)) {
-+ if((-1 == rc_lzmq_socket_set_rcvtimeo1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, err1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_rcvtimeo1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-+
-+/* method: sndtimeo */
-+#if (VERSION_2_2|VERSION_3_0)
-+static int ZMQ_Socket__sndtimeo__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_sndtimeo2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_sndtimeo2 = lzmq_socket_sndtimeo(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_sndtimeo2)) {
-+ lua_pushinteger(L, value1);
-+ } else {
-+ lua_pushnil(L);
-+ }
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_sndtimeo2);
-+ return 2;
-+}
-+#endif
-
--/* method: recv_msg */
--static int ZMQ_Socket__recv_msg__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- zmq_msg_t * msg2 = obj_type_zmq_msg_t_check(L,2);
-- int flags3 = luaL_optinteger(L,3,0);
-- ZMQ_Error rc_zmq_recv1 = 0;
-- rc_zmq_recv1 = zmq_recv(this1, msg2, flags3);
-+/* method: set_sndtimeo */
-+#if (VERSION_2_2|VERSION_3_0)
-+static int ZMQ_Socket__set_sndtimeo__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_sndtimeo1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_sndtimeo1 = lzmq_socket_set_sndtimeo(this1, value2);
- /* check for error. */
-- if((-1 == rc_zmq_recv1)) {
-+ if((-1 == rc_lzmq_socket_set_sndtimeo1)) {
- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, rc_zmq_recv1);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_sndtimeo1);
- } else {
- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
- return 2;
- }
-+#endif
-
--/* method: recv */
--static int ZMQ_Socket__recv__meth(lua_State *L) {
-- ZMQ_Socket * this1 = obj_type_ZMQ_Socket_check(L,1);
-- int flags2 = luaL_optinteger(L,2,0);
-- size_t data_len1 = 0;
-- const char * data1 = NULL;
-- ZMQ_Error err2 = 0;
-- zmq_msg_t msg;
-- /* initialize message */
-- err2 = zmq_msg_init(&msg);
-- if(0 == err2) {
-- /* receive message */
-- err2 = zmq_recv(this1, &msg, flags2);
-- if(0 == err2) {
-- data1 = zmq_msg_data(&msg);
-- data_len1 = zmq_msg_size(&msg);
-- }
-- }
--
-- if(!(-1 == err2)) {
-- if(data1 == NULL) lua_pushnil(L); else lua_pushlstring(L, data1,data_len1);
-+/* method: ipv4only */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__ipv4only__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value1 = 0;
-+ ZMQ_Error rc_lzmq_socket_ipv4only2 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ rc_lzmq_socket_ipv4only2 = lzmq_socket_ipv4only(this1, &(value1));
-+ if(!(-1 == rc_lzmq_socket_ipv4only2)) {
-+ lua_pushinteger(L, value1);
- } else {
- lua_pushnil(L);
- }
-- error_code__ZMQ_Error__push(L, err2);
-- /* close message */
-- zmq_msg_close(&msg);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_ipv4only2);
-+ return 2;
-+}
-+#endif
-
-+/* method: set_ipv4only */
-+#if (VERSION_3_0)
-+static int ZMQ_Socket__set_ipv4only__meth(lua_State *L) {
-+ ZMQ_Socket * this1;
-+ int value2;
-+ ZMQ_Error rc_lzmq_socket_set_ipv4only1 = 0;
-+ this1 = obj_type_ZMQ_Socket_check(L,1);
-+ value2 = luaL_checkinteger(L,2);
-+ rc_lzmq_socket_set_ipv4only1 = lzmq_socket_set_ipv4only(this1, value2);
-+ /* check for error. */
-+ if((-1 == rc_lzmq_socket_set_ipv4only1)) {
-+ lua_pushnil(L);
-+ error_code__ZMQ_Error__push(L, rc_lzmq_socket_set_ipv4only1);
-+ } else {
-+ lua_pushboolean(L, 1);
-+ lua_pushnil(L);
-+ }
- return 2;
- }
-+#endif
-
- /* method: new */
- static int ZMQ_Poller__new__meth(lua_State *L) {
-- unsigned int length1 = luaL_optinteger(L,1,10);
-- int this_flags1 = OBJ_UDATA_FLAG_OWN;
-- ZMQ_Poller * this1;
-- ZMQ_Poller poller;
-- this1 = &poller;
-- this1->items = (zmq_pollitem_t *)calloc(length1, sizeof(zmq_pollitem_t));
-- this1->next = -1;
-- this1->count = 0;
-- this1->len = length1;
-- this1->free_list = -1;
--
-- obj_type_ZMQ_Poller_push(L, this1, this_flags1);
-+ unsigned int length1;
-+ ZMQ_Poller this1_store;
-+ ZMQ_Poller * this1 = &(this1_store);
-+ length1 = luaL_optinteger(L,1,10);
-+ poller_init(this1, length1);
-+ obj_type_ZMQ_Poller_push(L, this1);
- return 1;
- }
-
- /* method: close */
- static int ZMQ_Poller__close__meth(lua_State *L) {
-- int this_flags1 = 0;
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_delete(L,1,&(this_flags1));
-- if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
-- free(this1->items);
-- this1->items = NULL;
-- this1->next = -1;
-- this1->count = 0;
-- this1->len = 0;
-- this1->free_list = -1;
--
-+ ZMQ_Poller * this1;
-+ this1 = obj_type_ZMQ_Poller_delete(L,1);
-+ poller_cleanup(this1);
- return 0;
- }
-
- /* method: add */
- static int ZMQ_Poller__add__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-- short events3 = luaL_checkinteger(L,3);
-+ ZMQ_Poller * this1;
-+ short events3;
- int idx1 = 0;
- zmq_pollitem_t *item;
- ZMQ_Socket *sock = NULL;
- socket_t fd = 0;
-
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
-+ events3 = luaL_checkinteger(L,3);
- if(lua_isuserdata(L, 2)) {
- sock = obj_type_ZMQ_Socket_check(L, 2);
- } else if(lua_isnumber(L, 2)) {
-@@ -2777,13 +6247,15 @@ static int ZMQ_Poller__add__meth(lua_State *L) {
-
- /* method: modify */
- static int ZMQ_Poller__modify__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-- short events3 = luaL_checkinteger(L,3);
-+ ZMQ_Poller * this1;
-+ short events3;
- int idx1 = 0;
- zmq_pollitem_t *item;
- ZMQ_Socket *sock = NULL;
- socket_t fd = 0;
-
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
-+ events3 = luaL_checkinteger(L,3);
- if(lua_isuserdata(L, 2)) {
- sock = obj_type_ZMQ_Socket_check(L, 2);
- /* find sock in items list. */
-@@ -2815,98 +6287,76 @@ static int ZMQ_Poller__modify__meth(lua_State *L) {
-
- /* method: remove */
- static int ZMQ_Poller__remove__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-+ ZMQ_Poller * this1;
-+ int idx1 = 0;
- ZMQ_Socket *sock;
- socket_t fd;
-- int idx;
-
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
- /* ZMQ_Socket or fd */
- if(lua_isuserdata(L, 2)) {
- sock = obj_type_ZMQ_Socket_check(L, 2);
- /* find sock in items list. */
-- idx = poller_find_sock_item(this1, sock);
-+ idx1 = poller_find_sock_item(this1, sock);
- } else if(lua_isnumber(L, 2)) {
- fd = lua_tonumber(L, 2);
- /* find fd in items list. */
-- idx = poller_find_fd_item(this1, fd);
-+ idx1 = poller_find_fd_item(this1, fd);
- } else {
- return luaL_typerror(L, 2, "number or ZMQ_Socket");
- }
- /* if sock/fd was found. */
-- if(idx >= 0) {
-- poller_remove_item(this1, idx);
-+ if(idx1 >= 0) {
-+ poller_remove_item(this1, idx1);
- }
-
-- return 0;
-+ lua_pushinteger(L, idx1);
-+ return 1;
- }
-
- /* method: poll */
- static int ZMQ_Poller__poll__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-- long timeout2 = luaL_checkinteger(L,2);
-- ZMQ_Error err1 = 0;
-- /* poll for events */
-- err1 = poller_poll(this1, timeout2);
-- if(err1 > 0) {
-+ ZMQ_Poller * this1;
-+ long timeout2;
-+ int count1 = 0;
-+ ZMQ_Error err2 = 0;
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
-+ timeout2 = luaL_checkinteger(L,2);
-+ err2 = poller_poll(this1, timeout2);
-+ if(err2 > 0) {
- this1->next = 0;
-+ count1 = err2;
- } else {
- this1->next = -1;
-+ count1 = 0;
- }
-
-- /* check for error. */
-- if((-1 == err1)) {
-- lua_pushnil(L);
-- error_code__ZMQ_Error__push(L, err1);
-+ if(!(-1 == err2)) {
-+ lua_pushinteger(L, count1);
- } else {
-- lua_pushboolean(L, 1);
- lua_pushnil(L);
- }
-+ error_code__ZMQ_Error__push(L, err2);
- return 2;
- }
-
--/* method: next_revents */
--static int ZMQ_Poller__next_revents__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-- short revents2 = 0;
-- zmq_pollitem_t *items;
-- int count;
-- int idx;
--
-- revents2 = -1;
-- idx = this1->next;
-- if(idx >= 0) {
-- count = this1->count;
-- items = this1->items;
-- /* find next item with pending events. */
-- while(idx < count && items[idx].revents == 0) ++idx;
-- /* did we find a pending event? */
-- if(idx < count) {
-- /* push the event's sock/fd. */
-- if(items[idx].socket != NULL) {
-- obj_type_ZMQ_Socket_push(L, items[idx].socket, 0);
-- } else {
-- lua_pushnumber(L, items[idx].fd);
-- }
-- revents2 = items[idx].revents;
-- /* is this the last event. */
-- ++idx;
-- this1->next = (idx < count) ? idx : -1;
-- }
-- }
-- if(revents2 < 0) {
-- /* no more pending events. */
-- lua_pushnil(L);
-- this1->next = -1;
-- }
--
-+/* method: next_revents_idx */
-+static int ZMQ_Poller__next_revents_idx__meth(lua_State *L) {
-+ ZMQ_Poller * this1;
-+ int idx1 = 0;
-+ int revents2 = 0;
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
-+ idx1 = poller_next_revents(this1, &(revents2));
-+ lua_pushinteger(L, idx1);
- lua_pushinteger(L, revents2);
- return 2;
- }
-
- /* method: count */
- static int ZMQ_Poller__count__meth(lua_State *L) {
-- ZMQ_Poller * this1 = obj_type_ZMQ_Poller_check(L,1);
-+ ZMQ_Poller * this1;
- int count1 = 0;
-+ this1 = obj_type_ZMQ_Poller_check(L,1);
- count1 = this1->count;
-
- lua_pushinteger(L, count1);
-@@ -2916,8 +6366,9 @@ static int ZMQ_Poller__count__meth(lua_State *L) {
- /* method: term */
- static int ZMQ_Ctx__term__meth(lua_State *L) {
- int this_flags1 = 0;
-- ZMQ_Ctx * this1 = obj_type_ZMQ_Ctx_delete(L,1,&(this_flags1));
-+ ZMQ_Ctx * this1;
- ZMQ_Error rc_zmq_term1 = 0;
-+ this1 = obj_type_ZMQ_Ctx_delete(L,1,&(this_flags1));
- if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
- rc_zmq_term1 = zmq_term(this1);
- /* check for error. */
-@@ -2933,8 +6384,9 @@ static int ZMQ_Ctx__term__meth(lua_State *L) {
-
- /* method: lightuserdata */
- static int ZMQ_Ctx__lightuserdata__meth(lua_State *L) {
-- ZMQ_Ctx * this1 = obj_type_ZMQ_Ctx_check(L,1);
-+ ZMQ_Ctx * this1;
- void * ptr1 = NULL;
-+ this1 = obj_type_ZMQ_Ctx_check(L,1);
- ptr1 = this1;
-
- lua_pushlightuserdata(L, ptr1);
-@@ -2943,10 +6395,12 @@ static int ZMQ_Ctx__lightuserdata__meth(lua_State *L) {
-
- /* method: socket */
- static int ZMQ_Ctx__socket__meth(lua_State *L) {
-- ZMQ_Ctx * this1 = obj_type_ZMQ_Ctx_check(L,1);
-- int type2 = luaL_checkinteger(L,2);
-+ ZMQ_Ctx * this1;
-+ int type2;
- int rc_zmq_socket_flags1 = OBJ_UDATA_FLAG_OWN;
- ZMQ_Socket * rc_zmq_socket1;
-+ this1 = obj_type_ZMQ_Ctx_check(L,1);
-+ type2 = luaL_checkinteger(L,2);
- rc_zmq_socket1 = zmq_socket(this1, type2);
- if((NULL == rc_zmq_socket1)) {
- lua_pushnil(L);
-@@ -2969,8 +6423,9 @@ static int ZMQ_StopWatch__start__meth(lua_State *L) {
- /* method: stop */
- static int ZMQ_StopWatch__stop__meth(lua_State *L) {
- int this_flags1 = 0;
-- ZMQ_StopWatch * this1 = obj_type_ZMQ_StopWatch_delete(L,1,&(this_flags1));
-+ ZMQ_StopWatch * this1;
- unsigned long usecs1 = 0;
-+ this1 = obj_type_ZMQ_StopWatch_delete(L,1,&(this_flags1));
- if(!(this_flags1 & OBJ_UDATA_FLAG_OWN)) { return 0; }
- usecs1 = zmq_stopwatch_stop(this1);
- lua_pushinteger(L, usecs1);
-@@ -2996,9 +6451,10 @@ static int zmq__version__func(lua_State *L) {
-
- /* method: init */
- static int zmq__init__func(lua_State *L) {
-- int io_threads1 = luaL_checkinteger(L,1);
-+ int io_threads1;
- int rc_zmq_init_flags1 = OBJ_UDATA_FLAG_OWN;
- ZMQ_Ctx * rc_zmq_init1;
-+ io_threads1 = luaL_optinteger(L,1,1);
- rc_zmq_init1 = zmq_init(io_threads1);
- if((NULL == rc_zmq_init1)) {
- lua_pushnil(L);
-@@ -3028,11 +6484,15 @@ static int zmq__init_ctx__func(lua_State *L) {
- }
-
- /* method: device */
-+#if (VERSION_2_0)
- static int zmq__device__func(lua_State *L) {
-- int device1 = luaL_checkinteger(L,1);
-- ZMQ_Socket * insock2 = obj_type_ZMQ_Socket_check(L,2);
-- ZMQ_Socket * outsock3 = obj_type_ZMQ_Socket_check(L,3);
-+ int device1;
-+ ZMQ_Socket * insock2;
-+ ZMQ_Socket * outsock3;
- ZMQ_Error rc_zmq_device1 = 0;
-+ device1 = luaL_checkinteger(L,1);
-+ insock2 = obj_type_ZMQ_Socket_check(L,2);
-+ outsock3 = obj_type_ZMQ_Socket_check(L,3);
- rc_zmq_device1 = zmq_device(device1, insock2, outsock3);
- /* check for error. */
- if((-1 == rc_zmq_device1)) {
-@@ -3044,6 +6504,7 @@ static int zmq__device__func(lua_State *L) {
- }
- return 2;
- }
-+#endif
-
- /* method: stopwatch_start */
- static int zmq__stopwatch_start__func(lua_State *L) {
-@@ -3056,32 +6517,452 @@ static int zmq__stopwatch_start__func(lua_State *L) {
-
- /* method: sleep */
- static int zmq__sleep__func(lua_State *L) {
-- int seconds_1 = luaL_checkinteger(L,1);
-+ int seconds_1;
-+ seconds_1 = luaL_checkinteger(L,1);
- zmq_sleep(seconds_1);
- return 0;
- }
-
--/* method: dump_ffi */
--static int zmq__dump_ffi__func(lua_State *L) {
-- size_t ffi_code_len1 = 0;
-- const char * ffi_code1 = NULL;
-- ffi_code1 = zmq_ffi_lua_code;
-- ffi_code_len1 = sizeof(zmq_ffi_lua_code) - 1;
-
-- if(ffi_code1 == NULL) lua_pushnil(L); else lua_pushlstring(L, ffi_code1,ffi_code_len1);
-- return 1;
--}
-
-+static const luaL_Reg obj_ZErrors_pub_funcs[] = {
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZErrors_methods[] = {
-+ {"description", ZErrors__description__meth},
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZErrors_metas[] = {
-+ {"__index", ZErrors____index__meth},
-+ {NULL, NULL}
-+};
-+
-+static const obj_const obj_ZErrors_constants[] = {
-+#ifdef ELNRNG
-+ {"ELNRNG", NULL, ELNRNG, CONST_NUMBER},
-+#endif
-+#ifdef EPFNOSUPPORT
-+ {"EPFNOSUPPORT", NULL, EPFNOSUPPORT, CONST_NUMBER},
-+#endif
-+#ifdef EBADR
-+ {"EBADR", NULL, EBADR, CONST_NUMBER},
-+#endif
-+#ifdef ENOLINK
-+ {"ENOLINK", NULL, ENOLINK, CONST_NUMBER},
-+#endif
-+#ifdef ENOSTR
-+ {"ENOSTR", NULL, ENOSTR, CONST_NUMBER},
-+#endif
-+#ifdef ERESTART
-+ {"ERESTART", NULL, ERESTART, CONST_NUMBER},
-+#endif
-+#ifdef EUCLEAN
-+ {"EUCLEAN", NULL, EUCLEAN, CONST_NUMBER},
-+#endif
-+#ifdef ELIBSCN
-+ {"ELIBSCN", NULL, ELIBSCN, CONST_NUMBER},
-+#endif
-+#ifdef EROFS
-+ {"EROFS", NULL, EROFS, CONST_NUMBER},
-+#endif
-+#ifdef EBADE
-+ {"EBADE", NULL, EBADE, CONST_NUMBER},
-+#endif
-+#ifdef ENOTSOCK
-+ {"ENOTSOCK", NULL, ENOTSOCK, CONST_NUMBER},
-+#endif
-+#ifdef ENOTCONN
-+ {"ENOTCONN", NULL, ENOTCONN, CONST_NUMBER},
-+#endif
-+#ifdef EREMOTE
-+ {"EREMOTE", NULL, EREMOTE, CONST_NUMBER},
-+#endif
-+#ifdef ECOMM
-+ {"ECOMM", NULL, ECOMM, CONST_NUMBER},
-+#endif
-+#ifdef ENODATA
-+ {"ENODATA", NULL, ENODATA, CONST_NUMBER},
-+#endif
-+#ifdef EPERM
-+ {"EPERM", NULL, EPERM, CONST_NUMBER},
-+#endif
-+#ifdef EBADRQC
-+ {"EBADRQC", NULL, EBADRQC, CONST_NUMBER},
-+#endif
-+#ifdef ENOSR
-+ {"ENOSR", NULL, ENOSR, CONST_NUMBER},
-+#endif
-+#ifdef ELIBMAX
-+ {"ELIBMAX", NULL, ELIBMAX, CONST_NUMBER},
-+#endif
-+#ifdef EDOTDOT
-+ {"EDOTDOT", NULL, EDOTDOT, CONST_NUMBER},
-+#endif
-+#ifdef EFSM
-+ {"EFSM", NULL, EFSM, CONST_NUMBER},
-+#endif
-+#ifdef ENOPROTOOPT
-+ {"ENOPROTOOPT", NULL, ENOPROTOOPT, CONST_NUMBER},
-+#endif
-+#ifdef EBFONT
-+ {"EBFONT", NULL, EBFONT, CONST_NUMBER},
-+#endif
-+#ifdef ENOCOMPATPROTO
-+ {"ENOCOMPATPROTO", NULL, ENOCOMPATPROTO, CONST_NUMBER},
-+#endif
-+#ifdef EKEYREVOKED
-+ {"EKEYREVOKED", NULL, EKEYREVOKED, CONST_NUMBER},
-+#endif
-+#ifdef ESRMNT
-+ {"ESRMNT", NULL, ESRMNT, CONST_NUMBER},
-+#endif
-+#ifdef EOVERFLOW
-+ {"EOVERFLOW", NULL, EOVERFLOW, CONST_NUMBER},
-+#endif
-+#ifdef EDQUOT
-+ {"EDQUOT", NULL, EDQUOT, CONST_NUMBER},
-+#endif
-+#ifdef EFBIG
-+ {"EFBIG", NULL, EFBIG, CONST_NUMBER},
-+#endif
-+#ifdef EIDRM
-+ {"EIDRM", NULL, EIDRM, CONST_NUMBER},
-+#endif
-+#ifdef EDOM
-+ {"EDOM", NULL, EDOM, CONST_NUMBER},
-+#endif
-+#ifdef EPROTO
-+ {"EPROTO", NULL, EPROTO, CONST_NUMBER},
-+#endif
-+#ifdef EMULTIHOP
-+ {"EMULTIHOP", NULL, EMULTIHOP, CONST_NUMBER},
-+#endif
-+#ifdef ENOCSI
-+ {"ENOCSI", NULL, ENOCSI, CONST_NUMBER},
-+#endif
-+#ifdef EDEADLOCK
-+ {"EDEADLOCK", NULL, EDEADLOCK, CONST_NUMBER},
-+#endif
-+#ifdef ENOPKG
-+ {"ENOPKG", NULL, ENOPKG, CONST_NUMBER},
-+#endif
-+#ifdef EPIPE
-+ {"EPIPE", NULL, EPIPE, CONST_NUMBER},
-+#endif
-+#ifdef EADDRINUSE
-+ {"EADDRINUSE", NULL, EADDRINUSE, CONST_NUMBER},
-+#endif
-+#ifdef EFAULT
-+ {"EFAULT", NULL, EFAULT, CONST_NUMBER},
-+#endif
-+#ifdef EDEADLK
-+ {"EDEADLK", NULL, EDEADLK, CONST_NUMBER},
-+#endif
-+#ifdef ENFILE
-+ {"ENFILE", NULL, ENFILE, CONST_NUMBER},
-+#endif
-+#ifdef EAGAIN
-+ {"EAGAIN", NULL, EAGAIN, CONST_NUMBER},
-+#endif
-+#ifdef ECONNABORTED
-+ {"ECONNABORTED", NULL, ECONNABORTED, CONST_NUMBER},
-+#endif
-+#ifdef EMLINK
-+ {"EMLINK", NULL, EMLINK, CONST_NUMBER},
-+#endif
-+#ifdef EBADMSG
-+ {"EBADMSG", NULL, EBADMSG, CONST_NUMBER},
-+#endif
-+#ifdef ERFKILL
-+ {"ERFKILL", NULL, ERFKILL, CONST_NUMBER},
-+#endif
-+#ifdef ENOTTY
-+ {"ENOTTY", NULL, ENOTTY, CONST_NUMBER},
-+#endif
-+#ifdef ELIBACC
-+ {"ELIBACC", NULL, ELIBACC, CONST_NUMBER},
-+#endif
-+#ifdef ETIME
-+ {"ETIME", NULL, ETIME, CONST_NUMBER},
-+#endif
-+#ifdef ECHILD
-+ {"ECHILD", NULL, ECHILD, CONST_NUMBER},
-+#endif
-+#ifdef ENOTRECOVERABLE
-+ {"ENOTRECOVERABLE", NULL, ENOTRECOVERABLE, CONST_NUMBER},
-+#endif
-+#ifdef EISCONN
-+ {"EISCONN", NULL, EISCONN, CONST_NUMBER},
-+#endif
-+#ifdef ENAVAIL
-+ {"ENAVAIL", NULL, ENAVAIL, CONST_NUMBER},
-+#endif
-+#ifdef EDESTADDRREQ
-+ {"EDESTADDRREQ", NULL, EDESTADDRREQ, CONST_NUMBER},
-+#endif
-+#ifdef EREMOTEIO
-+ {"EREMOTEIO", NULL, EREMOTEIO, CONST_NUMBER},
-+#endif
-+#ifdef ESTALE
-+ {"ESTALE", NULL, ESTALE, CONST_NUMBER},
-+#endif
-+#ifdef ESTRPIPE
-+ {"ESTRPIPE", NULL, ESTRPIPE, CONST_NUMBER},
-+#endif
-+#ifdef EHOSTUNREACH
-+ {"EHOSTUNREACH", NULL, EHOSTUNREACH, CONST_NUMBER},
-+#endif
-+#ifdef ENOTBLK
-+ {"ENOTBLK", NULL, ENOTBLK, CONST_NUMBER},
-+#endif
-+#ifdef EEXIST
-+ {"EEXIST", NULL, EEXIST, CONST_NUMBER},
-+#endif
-+#ifdef ENOTDIR
-+ {"ENOTDIR", NULL, ENOTDIR, CONST_NUMBER},
-+#endif
-+#ifdef EWOULDBLOCK
-+ {"EWOULDBLOCK", NULL, EWOULDBLOCK, CONST_NUMBER},
-+#endif
-+#ifdef EREMCHG
-+ {"EREMCHG", NULL, EREMCHG, CONST_NUMBER},
-+#endif
-+#ifdef ELOOP
-+ {"ELOOP", NULL, ELOOP, CONST_NUMBER},
-+#endif
-+#ifdef ENOTUNIQ
-+ {"ENOTUNIQ", NULL, ENOTUNIQ, CONST_NUMBER},
-+#endif
-+#ifdef EMEDIUMTYPE
-+ {"EMEDIUMTYPE", NULL, EMEDIUMTYPE, CONST_NUMBER},
-+#endif
-+#ifdef ENOLCK
-+ {"ENOLCK", NULL, ENOLCK, CONST_NUMBER},
-+#endif
-+#ifdef EUNATCH
-+ {"EUNATCH", NULL, EUNATCH, CONST_NUMBER},
-+#endif
-+#ifdef EPROTONOSUPPORT
-+ {"EPROTONOSUPPORT", NULL, EPROTONOSUPPORT, CONST_NUMBER},
-+#endif
-+#ifdef EHOSTDOWN
-+ {"EHOSTDOWN", NULL, EHOSTDOWN, CONST_NUMBER},
-+#endif
-+#ifdef EINTR
-+ {"EINTR", NULL, EINTR, CONST_NUMBER},
-+#endif
-+#ifdef ETIMEDOUT
-+ {"ETIMEDOUT", NULL, ETIMEDOUT, CONST_NUMBER},
-+#endif
-+#ifdef EOWNERDEAD
-+ {"EOWNERDEAD", NULL, EOWNERDEAD, CONST_NUMBER},
-+#endif
-+#ifdef EL2HLT
-+ {"EL2HLT", NULL, EL2HLT, CONST_NUMBER},
-+#endif
-+#ifdef ETERM
-+ {"ETERM", NULL, ETERM, CONST_NUMBER},
-+#endif
-+#ifdef EBADSLT
-+ {"EBADSLT", NULL, EBADSLT, CONST_NUMBER},
-+#endif
-+#ifdef ESHUTDOWN
-+ {"ESHUTDOWN", NULL, ESHUTDOWN, CONST_NUMBER},
-+#endif
-+#ifdef EIO
-+ {"EIO", NULL, EIO, CONST_NUMBER},
-+#endif
-+#ifdef ENOANO
-+ {"ENOANO", NULL, ENOANO, CONST_NUMBER},
-+#endif
-+#ifdef EACCES
-+ {"EACCES", NULL, EACCES, CONST_NUMBER},
-+#endif
-+#ifdef EOPNOTSUPP
-+ {"EOPNOTSUPP", NULL, EOPNOTSUPP, CONST_NUMBER},
-+#endif
-+#ifdef EKEYREJECTED
-+ {"EKEYREJECTED", NULL, EKEYREJECTED, CONST_NUMBER},
-+#endif
-+#ifdef ESOCKTNOSUPPORT
-+ {"ESOCKTNOSUPPORT", NULL, ESOCKTNOSUPPORT, CONST_NUMBER},
-+#endif
-+#ifdef ENOKEY
-+ {"ENOKEY", NULL, ENOKEY, CONST_NUMBER},
-+#endif
-+#ifdef ELIBBAD
-+ {"ELIBBAD", NULL, ELIBBAD, CONST_NUMBER},
-+#endif
-+#ifdef ENODEV
-+ {"ENODEV", NULL, ENODEV, CONST_NUMBER},
-+#endif
-+#ifdef ECANCELED
-+ {"ECANCELED", NULL, ECANCELED, CONST_NUMBER},
-+#endif
-+#ifdef ENOBUFS
-+ {"ENOBUFS", NULL, ENOBUFS, CONST_NUMBER},
-+#endif
-+#ifdef ENETUNREACH
-+ {"ENETUNREACH", NULL, ENETUNREACH, CONST_NUMBER},
-+#endif
-+#ifdef EL3HLT
-+ {"EL3HLT", NULL, EL3HLT, CONST_NUMBER},
-+#endif
-+#ifdef ENXIO
-+ {"ENXIO", NULL, ENXIO, CONST_NUMBER},
-+#endif
-+#ifdef ENETRESET
-+ {"ENETRESET", NULL, ENETRESET, CONST_NUMBER},
-+#endif
-+#ifdef ENOENT
-+ {"ENOENT", NULL, ENOENT, CONST_NUMBER},
-+#endif
-+#ifdef ENOMSG
-+ {"ENOMSG", NULL, ENOMSG, CONST_NUMBER},
-+#endif
-+#ifdef EL3RST
-+ {"EL3RST", NULL, EL3RST, CONST_NUMBER},
-+#endif
-+#ifdef EMFILE
-+ {"EMFILE", NULL, EMFILE, CONST_NUMBER},
-+#endif
-+#ifdef ENOEXEC
-+ {"ENOEXEC", NULL, ENOEXEC, CONST_NUMBER},
-+#endif
-+#ifdef ENOTEMPTY
-+ {"ENOTEMPTY", NULL, ENOTEMPTY, CONST_NUMBER},
-+#endif
-+#ifdef EMTHREAD
-+ {"EMTHREAD", NULL, EMTHREAD, CONST_NUMBER},
-+#endif
-+#ifdef EISNAM
-+ {"EISNAM", NULL, EISNAM, CONST_NUMBER},
-+#endif
-+#ifdef EINVAL
-+ {"EINVAL", NULL, EINVAL, CONST_NUMBER},
-+#endif
-+#ifdef ERANGE
-+ {"ERANGE", NULL, ERANGE, CONST_NUMBER},
-+#endif
-+#ifdef E2BIG
-+ {"E2BIG", NULL, E2BIG, CONST_NUMBER},
-+#endif
-+#ifdef ENOTNAM
-+ {"ENOTNAM", NULL, ENOTNAM, CONST_NUMBER},
-+#endif
-+#ifdef ENONET
-+ {"ENONET", NULL, ENONET, CONST_NUMBER},
-+#endif
-+#ifdef EADDRNOTAVAIL
-+ {"EADDRNOTAVAIL", NULL, EADDRNOTAVAIL, CONST_NUMBER},
-+#endif
-+#ifdef ENOSYS
-+ {"ENOSYS", NULL, ENOSYS, CONST_NUMBER},
-+#endif
-+#ifdef EINPROGRESS
-+ {"EINPROGRESS", NULL, EINPROGRESS, CONST_NUMBER},
-+#endif
-+#ifdef EBUSY
-+ {"EBUSY", NULL, EBUSY, CONST_NUMBER},
-+#endif
-+#ifdef EBADFD
-+ {"EBADFD", NULL, EBADFD, CONST_NUMBER},
-+#endif
-+#ifdef EISDIR
-+ {"EISDIR", NULL, EISDIR, CONST_NUMBER},
-+#endif
-+#ifdef EADV
-+ {"EADV", NULL, EADV, CONST_NUMBER},
-+#endif
-+#ifdef ECONNRESET
-+ {"ECONNRESET", NULL, ECONNRESET, CONST_NUMBER},
-+#endif
-+#ifdef ENOSPC
-+ {"ENOSPC", NULL, ENOSPC, CONST_NUMBER},
-+#endif
-+#ifdef ETOOMANYREFS
-+ {"ETOOMANYREFS", NULL, ETOOMANYREFS, CONST_NUMBER},
-+#endif
-+#ifdef EXFULL
-+ {"EXFULL", NULL, EXFULL, CONST_NUMBER},
-+#endif
-+#ifdef EPROTOTYPE
-+ {"EPROTOTYPE", NULL, EPROTOTYPE, CONST_NUMBER},
-+#endif
-+#ifdef ESRCH
-+ {"ESRCH", NULL, ESRCH, CONST_NUMBER},
-+#endif
-+#ifdef EMSGSIZE
-+ {"EMSGSIZE", NULL, EMSGSIZE, CONST_NUMBER},
-+#endif
-+#ifdef EAFNOSUPPORT
-+ {"EAFNOSUPPORT", NULL, EAFNOSUPPORT, CONST_NUMBER},
-+#endif
-+#ifdef ESPIPE
-+ {"ESPIPE", NULL, ESPIPE, CONST_NUMBER},
-+#endif
-+#ifdef ENETDOWN
-+ {"ENETDOWN", NULL, ENETDOWN, CONST_NUMBER},
-+#endif
-+#ifdef ECHRNG
-+ {"ECHRNG", NULL, ECHRNG, CONST_NUMBER},
-+#endif
-+#ifdef ENOMEM
-+ {"ENOMEM", NULL, ENOMEM, CONST_NUMBER},
-+#endif
-+#ifdef ECONNREFUSED
-+ {"ECONNREFUSED", NULL, ECONNREFUSED, CONST_NUMBER},
-+#endif
-+#ifdef ETXTBSY
-+ {"ETXTBSY", NULL, ETXTBSY, CONST_NUMBER},
-+#endif
-+#ifdef EKEYEXPIRED
-+ {"EKEYEXPIRED", NULL, EKEYEXPIRED, CONST_NUMBER},
-+#endif
-+#ifdef ENOMEDIUM
-+ {"ENOMEDIUM", NULL, ENOMEDIUM, CONST_NUMBER},
-+#endif
-+#ifdef EUSERS
-+ {"EUSERS", NULL, EUSERS, CONST_NUMBER},
-+#endif
-+#ifdef EILSEQ
-+ {"EILSEQ", NULL, EILSEQ, CONST_NUMBER},
-+#endif
-+#ifdef ELIBEXEC
-+ {"ELIBEXEC", NULL, ELIBEXEC, CONST_NUMBER},
-+#endif
-+#ifdef EALREADY
-+ {"EALREADY", NULL, EALREADY, CONST_NUMBER},
-+#endif
-+#ifdef ENAMETOOLONG
-+ {"ENAMETOOLONG", NULL, ENAMETOOLONG, CONST_NUMBER},
-+#endif
-+#ifdef EXDEV
-+ {"EXDEV", NULL, EXDEV, CONST_NUMBER},
-+#endif
-+#ifdef EBADF
-+ {"EBADF", NULL, EBADF, CONST_NUMBER},
-+#endif
-+#ifdef EL2NSYNC
-+ {"EL2NSYNC", NULL, EL2NSYNC, CONST_NUMBER},
-+#endif
-+ {NULL, NULL, 0.0 , 0}
-+};
-
-+static const reg_impl obj_ZErrors_implements[] = {
-+ {NULL, NULL}
-+};
-
--static const luaL_reg obj_zmq_msg_t_pub_funcs[] = {
-+static const luaL_Reg obj_zmq_msg_t_pub_funcs[] = {
- {"init", zmq_msg_t__init__meth},
- {"init_size", zmq_msg_t__init_size__meth},
- {"init_data", zmq_msg_t__init_data__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_zmq_msg_t_methods[] = {
-+static const luaL_Reg obj_zmq_msg_t_methods[] = {
- {"close", zmq_msg_t__close__meth},
- {"move", zmq_msg_t__move__meth},
- {"copy", zmq_msg_t__copy__meth},
-@@ -3092,7 +6973,7 @@ static const luaL_reg obj_zmq_msg_t_methods[] = {
- {NULL, NULL}
- };
-
--static const luaL_reg obj_zmq_msg_t_metas[] = {
-+static const luaL_Reg obj_zmq_msg_t_metas[] = {
- {"__gc", zmq_msg_t__delete__meth},
- {"__tostring", zmq_msg_t____tostring__meth},
- {"__eq", obj_simple_udata_default_equal},
-@@ -3111,25 +6992,176 @@ static const obj_const obj_zmq_msg_t_constants[] = {
- {NULL, NULL, 0.0 , 0}
- };
-
--static const luaL_reg obj_ZMQ_Socket_pub_funcs[] = {
-+static const reg_impl obj_zmq_msg_t_implements[] = {
-+ { "BufferIF", &(zmq_msg_t_Buffer) },
-+
-+ { "MutableBufferIF", &(zmq_msg_t_MutableBuffer) },
-+
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZMQ_Socket_pub_funcs[] = {
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Socket_methods[] = {
-+static const luaL_Reg obj_ZMQ_Socket_methods[] = {
- {"close", ZMQ_Socket__close__meth},
- {"bind", ZMQ_Socket__bind__meth},
- {"connect", ZMQ_Socket__connect__meth},
- {"setopt", ZMQ_Socket__setopt__meth},
- {"getopt", ZMQ_Socket__getopt__meth},
-- {"events", ZMQ_Socket__events__meth},
- {"send_msg", ZMQ_Socket__send_msg__meth},
- {"send", ZMQ_Socket__send__meth},
- {"recv_msg", ZMQ_Socket__recv_msg__meth},
- {"recv", ZMQ_Socket__recv__meth},
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"hwm", ZMQ_Socket__hwm__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_hwm", ZMQ_Socket__set_hwm__meth},
-+#endif
-+#if (VERSION_2_0)
-+ {"swap", ZMQ_Socket__swap__meth},
-+#endif
-+#if (VERSION_2_0)
-+ {"set_swap", ZMQ_Socket__set_swap__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"affinity", ZMQ_Socket__affinity__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_affinity", ZMQ_Socket__set_affinity__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"identity", ZMQ_Socket__identity__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_identity", ZMQ_Socket__set_identity__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"subscribe", ZMQ_Socket__subscribe__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"unsubscribe", ZMQ_Socket__unsubscribe__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"rate", ZMQ_Socket__rate__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_rate", ZMQ_Socket__set_rate__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"recovery_ivl", ZMQ_Socket__recovery_ivl__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_recovery_ivl", ZMQ_Socket__set_recovery_ivl__meth},
-+#endif
-+#if (VERSION_2_0)
-+ {"mcast_loop", ZMQ_Socket__mcast_loop__meth},
-+#endif
-+#if (VERSION_2_0)
-+ {"set_mcast_loop", ZMQ_Socket__set_mcast_loop__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"sndbuf", ZMQ_Socket__sndbuf__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_sndbuf", ZMQ_Socket__set_sndbuf__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"rcvbuf", ZMQ_Socket__rcvbuf__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"set_rcvbuf", ZMQ_Socket__set_rcvbuf__meth},
-+#endif
-+#if (VERSION_2_0|VERSION_3_0)
-+ {"rcvmore", ZMQ_Socket__rcvmore__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"fd", ZMQ_Socket__fd__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"events", ZMQ_Socket__events__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"type", ZMQ_Socket__type__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"linger", ZMQ_Socket__linger__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"set_linger", ZMQ_Socket__set_linger__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"reconnect_ivl", ZMQ_Socket__reconnect_ivl__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"set_reconnect_ivl", ZMQ_Socket__set_reconnect_ivl__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"backlog", ZMQ_Socket__backlog__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"set_backlog", ZMQ_Socket__set_backlog__meth},
-+#endif
-+#if (VERSION_2_1)
-+ {"recovery_ivl_msec", ZMQ_Socket__recovery_ivl_msec__meth},
-+#endif
-+#if (VERSION_2_1)
-+ {"set_recovery_ivl_msec", ZMQ_Socket__set_recovery_ivl_msec__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"reconnect_ivl_max", ZMQ_Socket__reconnect_ivl_max__meth},
-+#endif
-+#if (VERSION_2_1|VERSION_3_0)
-+ {"set_reconnect_ivl_max", ZMQ_Socket__set_reconnect_ivl_max__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"maxmsgsize", ZMQ_Socket__maxmsgsize__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"set_maxmsgsize", ZMQ_Socket__set_maxmsgsize__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"sndhwm", ZMQ_Socket__sndhwm__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"set_sndhwm", ZMQ_Socket__set_sndhwm__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"rcvhwm", ZMQ_Socket__rcvhwm__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"set_rcvhwm", ZMQ_Socket__set_rcvhwm__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"multicast_hops", ZMQ_Socket__multicast_hops__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"set_multicast_hops", ZMQ_Socket__set_multicast_hops__meth},
-+#endif
-+#if (VERSION_2_2|VERSION_3_0)
-+ {"rcvtimeo", ZMQ_Socket__rcvtimeo__meth},
-+#endif
-+#if (VERSION_2_2|VERSION_3_0)
-+ {"set_rcvtimeo", ZMQ_Socket__set_rcvtimeo__meth},
-+#endif
-+#if (VERSION_2_2|VERSION_3_0)
-+ {"sndtimeo", ZMQ_Socket__sndtimeo__meth},
-+#endif
-+#if (VERSION_2_2|VERSION_3_0)
-+ {"set_sndtimeo", ZMQ_Socket__set_sndtimeo__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"ipv4only", ZMQ_Socket__ipv4only__meth},
-+#endif
-+#if (VERSION_3_0)
-+ {"set_ipv4only", ZMQ_Socket__set_ipv4only__meth},
-+#endif
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Socket_metas[] = {
-+static const luaL_Reg obj_ZMQ_Socket_metas[] = {
- {"__gc", ZMQ_Socket__close__meth},
- {"__tostring", obj_udata_default_tostring},
- {"__eq", obj_udata_default_equal},
-@@ -3148,23 +7180,27 @@ static const obj_const obj_ZMQ_Socket_constants[] = {
- {NULL, NULL, 0.0 , 0}
- };
-
--static const luaL_reg obj_ZMQ_Poller_pub_funcs[] = {
-+static const reg_impl obj_ZMQ_Socket_implements[] = {
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZMQ_Poller_pub_funcs[] = {
- {"new", ZMQ_Poller__new__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Poller_methods[] = {
-+static const luaL_Reg obj_ZMQ_Poller_methods[] = {
- {"close", ZMQ_Poller__close__meth},
- {"add", ZMQ_Poller__add__meth},
- {"modify", ZMQ_Poller__modify__meth},
- {"remove", ZMQ_Poller__remove__meth},
- {"poll", ZMQ_Poller__poll__meth},
-- {"next_revents", ZMQ_Poller__next_revents__meth},
-+ {"next_revents_idx", ZMQ_Poller__next_revents_idx__meth},
- {"count", ZMQ_Poller__count__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Poller_metas[] = {
-+static const luaL_Reg obj_ZMQ_Poller_metas[] = {
- {"__gc", ZMQ_Poller__close__meth},
- {"__tostring", obj_simple_udata_default_tostring},
- {"__eq", obj_simple_udata_default_equal},
-@@ -3183,18 +7219,22 @@ static const obj_const obj_ZMQ_Poller_constants[] = {
- {NULL, NULL, 0.0 , 0}
- };
-
--static const luaL_reg obj_ZMQ_Ctx_pub_funcs[] = {
-+static const reg_impl obj_ZMQ_Poller_implements[] = {
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZMQ_Ctx_pub_funcs[] = {
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Ctx_methods[] = {
-+static const luaL_Reg obj_ZMQ_Ctx_methods[] = {
- {"term", ZMQ_Ctx__term__meth},
- {"lightuserdata", ZMQ_Ctx__lightuserdata__meth},
- {"socket", ZMQ_Ctx__socket__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_Ctx_metas[] = {
-+static const luaL_Reg obj_ZMQ_Ctx_metas[] = {
- {"__gc", ZMQ_Ctx__term__meth},
- {"__tostring", obj_udata_default_tostring},
- {"__eq", obj_udata_default_equal},
-@@ -3213,17 +7253,21 @@ static const obj_const obj_ZMQ_Ctx_constants[] = {
- {NULL, NULL, 0.0 , 0}
- };
-
--static const luaL_reg obj_ZMQ_StopWatch_pub_funcs[] = {
-+static const reg_impl obj_ZMQ_Ctx_implements[] = {
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg obj_ZMQ_StopWatch_pub_funcs[] = {
- {"start", ZMQ_StopWatch__start__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_StopWatch_methods[] = {
-+static const luaL_Reg obj_ZMQ_StopWatch_methods[] = {
- {"stop", ZMQ_StopWatch__stop__meth},
- {NULL, NULL}
- };
-
--static const luaL_reg obj_ZMQ_StopWatch_metas[] = {
-+static const luaL_Reg obj_ZMQ_StopWatch_metas[] = {
- {"__gc", ZMQ_StopWatch__stop__meth},
- {"__tostring", obj_udata_default_tostring},
- {"__eq", obj_udata_default_equal},
-@@ -3242,87 +7286,217 @@ static const obj_const obj_ZMQ_StopWatch_constants[] = {
- {NULL, NULL, 0.0 , 0}
- };
-
--static const luaL_reg zmq_function[] = {
-+static const reg_impl obj_ZMQ_StopWatch_implements[] = {
-+ {NULL, NULL}
-+};
-+
-+static const luaL_Reg zmq_function[] = {
- {"version", zmq__version__func},
- {"init", zmq__init__func},
- {"init_ctx", zmq__init_ctx__func},
-+#if (VERSION_2_0)
- {"device", zmq__device__func},
-+#endif
- {"stopwatch_start", zmq__stopwatch_start__func},
- {"sleep", zmq__sleep__func},
-- {"dump_ffi", zmq__dump_ffi__func},
- {NULL, NULL}
- };
-
- static const obj_const zmq_constants[] = {
-- {"TYPE", NULL, 16, CONST_NUMBER},
-- {"RCVMORE", NULL, 13, CONST_NUMBER},
-- {"LINGER", NULL, 17, CONST_NUMBER},
-- {"SWAP", NULL, 3, CONST_NUMBER},
-- {"MSG_SHARED", NULL, 128, CONST_NUMBER},
-- {"SNDBUF", NULL, 11, CONST_NUMBER},
-- {"STREAMER", NULL, 1, CONST_NUMBER},
-- {"NOBLOCK", NULL, 1, CONST_NUMBER},
-- {"RCVBUF", NULL, 12, CONST_NUMBER},
-- {"FORWARDER", NULL, 2, CONST_NUMBER},
-- {"RATE", NULL, 8, CONST_NUMBER},
-- {"IDENTITY", NULL, 5, CONST_NUMBER},
-- {"SUB", NULL, 2, CONST_NUMBER},
-- {"FD", NULL, 14, CONST_NUMBER},
-- {"PUB", NULL, 1, CONST_NUMBER},
-- {"DELIMITER", NULL, 31, CONST_NUMBER},
-- {"BACKLOG", NULL, 19, CONST_NUMBER},
-- {"SNDMORE", NULL, 2, CONST_NUMBER},
-- {"POLLIN", NULL, 1, CONST_NUMBER},
-- {"REP", NULL, 4, CONST_NUMBER},
-- {"POLLERR", NULL, 4, CONST_NUMBER},
-- {"MAX_VSM_SIZE", NULL, 30, CONST_NUMBER},
-- {"PUSH", NULL, 8, CONST_NUMBER},
-- {"HWM", NULL, 1, CONST_NUMBER},
-- {"MSG_MORE", NULL, 1, CONST_NUMBER},
-- {"REQ", NULL, 3, CONST_NUMBER},
-- {"UNSUBSCRIBE", NULL, 7, CONST_NUMBER},
-- {"PULL", NULL, 7, CONST_NUMBER},
-- {"PAIR", NULL, 0, CONST_NUMBER},
-- {"QUEUE", NULL, 3, CONST_NUMBER},
-- {"EVENTS", NULL, 15, CONST_NUMBER},
-- {"XREQ", NULL, 5, CONST_NUMBER},
-- {"XREP", NULL, 6, CONST_NUMBER},
-- {"SUBSCRIBE", NULL, 6, CONST_NUMBER},
-- {"MCAST_LOOP", NULL, 10, CONST_NUMBER},
-- {"VSM", NULL, 32, CONST_NUMBER},
-- {"RECOVERY_IVL", NULL, 9, CONST_NUMBER},
-- {"RECONNECT_IVL", NULL, 18, CONST_NUMBER},
-- {"POLLOUT", NULL, 2, CONST_NUMBER},
-- {"AFFINITY", NULL, 4, CONST_NUMBER},
-+#ifdef ZMQ_TYPE
-+ {"TYPE", NULL, ZMQ_TYPE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RCVMORE
-+ {"RCVMORE", NULL, ZMQ_RCVMORE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_LINGER
-+ {"LINGER", NULL, ZMQ_LINGER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_REP
-+ {"REP", NULL, ZMQ_REP, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MSG_SHARED
-+ {"MSG_SHARED", NULL, ZMQ_MSG_SHARED, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_XSUB
-+ {"XSUB", NULL, ZMQ_XSUB, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_STREAMER
-+ {"STREAMER", NULL, ZMQ_STREAMER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RECONNECT_IVL_MSEC
-+ {"RECONNECT_IVL_MSEC", NULL, ZMQ_RECONNECT_IVL_MSEC, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MAX_VSM_SIZE
-+ {"MAX_VSM_SIZE", NULL, ZMQ_MAX_VSM_SIZE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_PAIR
-+ {"PAIR", NULL, ZMQ_PAIR, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_DEALER
-+ {"DEALER", NULL, ZMQ_DEALER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_ROUTER
-+ {"ROUTER", NULL, ZMQ_ROUTER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_NOBLOCK
-+ {"NOBLOCK", NULL, ZMQ_NOBLOCK, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RCVBUF
-+ {"RCVBUF", NULL, ZMQ_RCVBUF, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_FORWARDER
-+ {"FORWARDER", NULL, ZMQ_FORWARDER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RATE
-+ {"RATE", NULL, ZMQ_RATE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_IDENTITY
-+ {"IDENTITY", NULL, ZMQ_IDENTITY, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MSG_MORE
-+ {"MSG_MORE", NULL, ZMQ_MSG_MORE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MAXMSGSIZE
-+ {"MAXMSGSIZE", NULL, ZMQ_MAXMSGSIZE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_PULL
-+ {"PULL", NULL, ZMQ_PULL, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MULTICAST_HOPS
-+ {"MULTICAST_HOPS", NULL, ZMQ_MULTICAST_HOPS, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RCVHWM
-+ {"RCVHWM", NULL, ZMQ_RCVHWM, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SUB
-+ {"SUB", NULL, ZMQ_SUB, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_UNSUBSCRIBE
-+ {"UNSUBSCRIBE", NULL, ZMQ_UNSUBSCRIBE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_BACKLOG
-+ {"BACKLOG", NULL, ZMQ_BACKLOG, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_XREQ
-+ {"XREQ", NULL, ZMQ_XREQ, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_PUSH
-+ {"PUSH", NULL, ZMQ_PUSH, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_PUB
-+ {"PUB", NULL, ZMQ_PUB, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_DELIMITER
-+ {"DELIMITER", NULL, ZMQ_DELIMITER, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_EVENTS
-+ {"EVENTS", NULL, ZMQ_EVENTS, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SNDMORE
-+ {"SNDMORE", NULL, ZMQ_SNDMORE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RCVLABEL
-+ {"RCVLABEL", NULL, ZMQ_RCVLABEL, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SNDBUF
-+ {"SNDBUF", NULL, ZMQ_SNDBUF, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_FD
-+ {"FD", NULL, ZMQ_FD, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_POLLIN
-+ {"POLLIN", NULL, ZMQ_POLLIN, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_XPUB
-+ {"XPUB", NULL, ZMQ_XPUB, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_POLLERR
-+ {"POLLERR", NULL, ZMQ_POLLERR, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RCVTIMEO
-+ {"RCVTIMEO", NULL, ZMQ_RCVTIMEO, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SNDTIMEO
-+ {"SNDTIMEO", NULL, ZMQ_SNDTIMEO, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_HWM
-+ {"HWM", NULL, ZMQ_HWM, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SWAP
-+ {"SWAP", NULL, ZMQ_SWAP, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_REQ
-+ {"REQ", NULL, ZMQ_REQ, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RECONNECT_IVL_MAX
-+ {"RECONNECT_IVL_MAX", NULL, ZMQ_RECONNECT_IVL_MAX, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_AFFINITY
-+ {"AFFINITY", NULL, ZMQ_AFFINITY, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SNDLABEL
-+ {"SNDLABEL", NULL, ZMQ_SNDLABEL, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_QUEUE
-+ {"QUEUE", NULL, ZMQ_QUEUE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_VSM
-+ {"VSM", NULL, ZMQ_VSM, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SNDHWM
-+ {"SNDHWM", NULL, ZMQ_SNDHWM, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_XREP
-+ {"XREP", NULL, ZMQ_XREP, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_SUBSCRIBE
-+ {"SUBSCRIBE", NULL, ZMQ_SUBSCRIBE, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_MCAST_LOOP
-+ {"MCAST_LOOP", NULL, ZMQ_MCAST_LOOP, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_DONTWAIT
-+ {"DONTWAIT", NULL, ZMQ_DONTWAIT, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RECOVERY_IVL
-+ {"RECOVERY_IVL", NULL, ZMQ_RECOVERY_IVL, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_RECONNECT_IVL
-+ {"RECONNECT_IVL", NULL, ZMQ_RECONNECT_IVL, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_POLLOUT
-+ {"POLLOUT", NULL, ZMQ_POLLOUT, CONST_NUMBER},
-+#endif
-+#ifdef ZMQ_POLL_MSEC
-+ {"POLL_MSEC", NULL, ZMQ_POLL_MSEC, CONST_NUMBER},
-+#endif
- {NULL, NULL, 0.0 , 0}
- };
-
--static const ffi_export_symbol zmq_ffi_export[] = {
--{ "get_zmq_strerror", get_zmq_strerror },
--{ "simple_zmq_send", simple_zmq_send },
--{ "poller_find_sock_item", poller_find_sock_item },
--{ "poller_find_fd_item", poller_find_fd_item },
--{ "poller_get_free_item", poller_get_free_item },
--{ "poller_poll", poller_poll },
--{ "poller_remove_item", poller_remove_item },
-- {NULL, NULL}
--};
--
-
-
- static const reg_sub_module reg_sub_modules[] = {
-- { &(obj_type_zmq_msg_t), 0, obj_zmq_msg_t_pub_funcs, obj_zmq_msg_t_methods, obj_zmq_msg_t_metas, obj_zmq_msg_t_bases, obj_zmq_msg_t_fields, obj_zmq_msg_t_constants},
-- { &(obj_type_ZMQ_Socket), 0, obj_ZMQ_Socket_pub_funcs, obj_ZMQ_Socket_methods, obj_ZMQ_Socket_metas, obj_ZMQ_Socket_bases, obj_ZMQ_Socket_fields, obj_ZMQ_Socket_constants},
-- { &(obj_type_ZMQ_Poller), 0, obj_ZMQ_Poller_pub_funcs, obj_ZMQ_Poller_methods, obj_ZMQ_Poller_metas, obj_ZMQ_Poller_bases, obj_ZMQ_Poller_fields, obj_ZMQ_Poller_constants},
-- { &(obj_type_ZMQ_Ctx), 0, obj_ZMQ_Ctx_pub_funcs, obj_ZMQ_Ctx_methods, obj_ZMQ_Ctx_metas, obj_ZMQ_Ctx_bases, obj_ZMQ_Ctx_fields, obj_ZMQ_Ctx_constants},
-- { &(obj_type_ZMQ_StopWatch), 0, obj_ZMQ_StopWatch_pub_funcs, obj_ZMQ_StopWatch_methods, obj_ZMQ_StopWatch_metas, obj_ZMQ_StopWatch_bases, obj_ZMQ_StopWatch_fields, obj_ZMQ_StopWatch_constants},
-- {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL}
-+ { &(obj_type_ZErrors), REG_META, obj_ZErrors_pub_funcs, obj_ZErrors_methods, obj_ZErrors_metas, NULL, NULL, obj_ZErrors_constants, NULL, 0},
-+ { &(obj_type_zmq_msg_t), REG_OBJECT, obj_zmq_msg_t_pub_funcs, obj_zmq_msg_t_methods, obj_zmq_msg_t_metas, obj_zmq_msg_t_bases, obj_zmq_msg_t_fields, obj_zmq_msg_t_constants, obj_zmq_msg_t_implements, 0},
-+ { &(obj_type_ZMQ_Socket), REG_OBJECT, obj_ZMQ_Socket_pub_funcs, obj_ZMQ_Socket_methods, obj_ZMQ_Socket_metas, obj_ZMQ_Socket_bases, obj_ZMQ_Socket_fields, obj_ZMQ_Socket_constants, obj_ZMQ_Socket_implements, 0},
-+ { &(obj_type_ZMQ_Poller), REG_OBJECT, obj_ZMQ_Poller_pub_funcs, obj_ZMQ_Poller_methods, obj_ZMQ_Poller_metas, obj_ZMQ_Poller_bases, obj_ZMQ_Poller_fields, obj_ZMQ_Poller_constants, obj_ZMQ_Poller_implements, 0},
-+ { &(obj_type_ZMQ_Ctx), REG_OBJECT, obj_ZMQ_Ctx_pub_funcs, obj_ZMQ_Ctx_methods, obj_ZMQ_Ctx_metas, obj_ZMQ_Ctx_bases, obj_ZMQ_Ctx_fields, obj_ZMQ_Ctx_constants, obj_ZMQ_Ctx_implements, 0},
-+ { &(obj_type_ZMQ_StopWatch), REG_OBJECT, obj_ZMQ_StopWatch_pub_funcs, obj_ZMQ_StopWatch_methods, obj_ZMQ_StopWatch_metas, obj_ZMQ_StopWatch_bases, obj_ZMQ_StopWatch_fields, obj_ZMQ_StopWatch_constants, obj_ZMQ_StopWatch_implements, 0},
-+ {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0}
- };
-
-
-
-
-
-+#if LUAJIT_FFI
-+static const ffi_export_symbol zmq_ffi_export[] = {
-+ {NULL, { NULL } }
-+};
-+#endif
-+
-+
-
-
- static const luaL_Reg submodule_libs[] = {
-@@ -3355,20 +7529,29 @@ LUA_NOBJ_API int luaopen_zmq(lua_State *L) {
- const luaL_Reg *submodules = submodule_libs;
- int priv_table = -1;
-
--#if LUAJIT_FFI
-+ /* register interfaces */
-+ obj_register_interfaces(L, obj_interfaces);
-+
- /* private table to hold reference to object metatables. */
- lua_newtable(L);
- priv_table = lua_gettop(L);
--#endif
-+ lua_pushlightuserdata(L, obj_udata_private_key);
-+ lua_pushvalue(L, priv_table);
-+ lua_rawset(L, LUA_REGISTRYINDEX); /* store private table in registry. */
-
- /* create object cache. */
- create_object_instance_cache(L);
-
- /* module table. */
-+#if REG_MODULES_AS_GLOBALS
- luaL_register(L, "zmq", zmq_function);
-+#else
-+ lua_newtable(L);
-+ luaL_setfuncs(L, zmq_function, 0);
-+#endif
-
- /* register module constants. */
-- obj_type_register_constants(L, zmq_constants, -1);
-+ obj_type_register_constants(L, zmq_constants, -1, 0);
-
- for(; submodules->func != NULL ; submodules++) {
- lua_pushcfunction(L, submodules->func);
-@@ -3389,9 +7572,19 @@ LUA_NOBJ_API int luaopen_zmq(lua_State *L) {
- }
-
- #if LUAJIT_FFI
-- nobj_try_loading_ffi(L, "zmq", zmq_ffi_lua_code,
-- zmq_ffi_export, priv_table);
-+ if(nobj_check_ffi_support(L)) {
-+ nobj_try_loading_ffi(L, "zmq.nobj.ffi.lua", zmq_ffi_lua_code,
-+ zmq_ffi_export, priv_table);
-+ }
- #endif
-+
-+ /* Cache reference to zmq.ZErrors table for errno->string convertion. */
-+ lua_pushlightuserdata(L, zmq_ZErrors_key);
-+ lua_getfield(L, -2, "ZErrors");
-+ lua_rawset(L, LUA_REGISTRYINDEX);
-+
-+
-+
- return 1;
- }
-
-diff --git a/src/socket.nobj.lua b/src/socket.nobj.lua
-index 207f52b..ef7a0db 100644
---- a/src/socket.nobj.lua
-+++ b/src/socket.nobj.lua
-@@ -18,21 +18,416 @@
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- -- THE SOFTWARE.
-
-+-------------------------------------------------------------------------------------
-+--
-+-- Generate ZeroMQ socket option code customized for each version of zmq (2.0,2.1,3.x)
-+--
-+-------------------------------------------------------------------------------------
-+
-+local OPT_TYPES = {
-+NONE = "NONE",
-+INT = "int",
-+UINT32 = "uint32_t",
-+UINT64 = "uint64_t",
-+INT64 = "int64_t",
-+BLOB = "const char *",
-+FD = "int",
-+}
-+local get_set_prefix = {
-+rw = { c_get = "lzmq_socket_", get='', c_set = "lzmq_socket_set_", set='set_' },
-+r = { c_get = "lzmq_socket_", get='' },
-+w = { c_set = "lzmq_socket_", set='' },
-+}
-+
-+local socket_options = {
-+ { ver_def = 'VERSION_2_0', major = 2, minor = 0,
-+ [1] = { name="hwm", otype="UINT64", mode="rw", ltype="int" },
-+ [2] = { },
-+ [3] = { name="swap", otype="INT64", mode="rw", ltype="int" },
-+ [4] = { name="affinity", otype="UINT64", mode="rw", ltype="uint64_t" },
-+ [5] = { name="identity", otype="BLOB", mode="rw", ltype="const char *" },
-+ [6] = { name="subscribe", otype="BLOB", mode="w", ltype="const char *" },
-+ [7] = { name="unsubscribe", otype="BLOB", mode="w", ltype="const char *" },
-+ [8] = { name="rate", otype="INT64", mode="rw", ltype="int" },
-+ [9] = { name="recovery_ivl", otype="INT64", mode="rw", ltype="int" },
-+ [10] = { name="mcast_loop", otype="INT64", mode="rw", ltype="int" },
-+ [11] = { name="sndbuf", otype="UINT64", mode="rw", ltype="int" },
-+ [12] = { name="rcvbuf", otype="UINT64", mode="rw", ltype="int" },
-+ [13] = { name="rcvmore", otype="INT64", mode="r", ltype="int" },
-+ },
-+ { ver_def = 'VERSION_2_1', major = 2, minor = 1,
-+ [14] = { name="fd", otype="FD", mode="r", ltype="int" },
-+ [15] = { name="events", otype="UINT32", mode="r", ltype="int" },
-+ [16] = { name="type", otype="INT", mode="r", ltype="int" },
-+ [17] = { name="linger", otype="INT", mode="rw", ltype="int" },
-+ [18] = { name="reconnect_ivl", otype="INT", mode="rw", ltype="int" },
-+ [19] = { name="backlog", otype="INT", mode="rw", ltype="int" },
-+ [20] = { name="recovery_ivl_msec", otype="INT64", mode="rw", ltype="int64_t" },
-+ [21] = { name="reconnect_ivl_max", otype="INT", mode="rw", ltype="int" },
-+ },
-+ { ver_def = 'VERSION_2_2', major = 2, minor = 2,
-+ [22] = { },
-+ [23] = { },
-+ [24] = { },
-+ [25] = { },
-+ [26] = { },
-+ [27] = { name="rcvtimeo", otype="INT", mode="rw", ltype="int" },
-+ [28] = { name="sndtimeo", otype="INT", mode="rw", ltype="int" },
-+ },
-+ { ver_def = 'VERSION_3_0', major = 3, minor = 0,
-+ [1] = { name="hwm", otype="INT", mode="rw",
-+custom = [[
-+ZMQ_Error lzmq_socket_set_hwm(ZMQ_Socket *sock, int value) {
-+ int val;
-+ int rc;
-+ val = (int)value;
-+ rc = zmq_setsockopt(sock, ZMQ_SNDHWM, &value, sizeof(value));
-+ if(-1 == rc) return rc;
-+ val = (int)value;
-+ return zmq_setsockopt(sock, ZMQ_RCVHWM, &value, sizeof(value));
-+}
-+ZMQ_Error lzmq_socket_hwm(ZMQ_Socket *sock, int *value) {
-+ size_t val_len;
-+ int rc;
-+ val_len = sizeof(value);
-+ rc = zmq_getsockopt(sock, ZMQ_SNDHWM, value, &val_len);
-+ if(-1 == rc) return rc;
-+ val_len = sizeof(value);
-+ return zmq_getsockopt(sock, ZMQ_RCVHWM, value, &val_len);
-+}
-+
-+]] },
-+ [2] = { },
-+ [3] = { },
-+ [4] = { name="affinity", otype="UINT64", mode="rw", ltype="uint64_t" },
-+ [5] = { name="identity", otype="BLOB", mode="rw", ltype="const char *" },
-+ [6] = { name="subscribe", otype="BLOB", mode="w", ltype="const char *" },
-+ [7] = { name="unsubscribe", otype="BLOB", mode="w", ltype="const char *" },
-+ [8] = { name="rate", otype="INT", mode="rw", ltype="int" },
-+ [9] = { name="recovery_ivl", otype="INT", mode="rw", ltype="int" },
-+ [10] = { },
-+ [11] = { name="sndbuf", otype="INT", mode="rw", ltype="int" },
-+ [12] = { name="rcvbuf", otype="INT", mode="rw", ltype="int" },
-+ [13] = { name="rcvmore", otype="INT", mode="r", ltype="int" },
-+ [14] = { name="fd", otype="FD", mode="r", ltype="int" },
-+ [15] = { name="events", otype="INT", mode="r", ltype="int" },
-+ [16] = { name="type", otype="INT", mode="r", ltype="int" },
-+ [17] = { name="linger", otype="INT", mode="rw", ltype="int" },
-+ [18] = { name="reconnect_ivl", otype="INT", mode="rw", ltype="int" },
-+ [19] = { name="backlog", otype="INT", mode="rw", ltype="int" },
-+ [20] = { },
-+ [21] = { name="reconnect_ivl_max", otype="INT", mode="rw", ltype="int" },
-+ [22] = { name="maxmsgsize", otype="INT64", mode="rw", ltype="int64_t" },
-+ [23] = { name="sndhwm", otype="INT", mode="rw", ltype="int" },
-+ [24] = { name="rcvhwm", otype="INT", mode="rw", ltype="int" },
-+ [25] = { name="multicast_hops", otype="INT", mode="rw", ltype="int" },
-+ [26] = { },
-+ [27] = { name="rcvtimeo", otype="INT", mode="rw", ltype="int" },
-+ [28] = { name="sndtimeo", otype="INT", mode="rw", ltype="int" },
-+ [29] = { },
-+ [30] = { },
-+ [31] = { name="ipv4only", otype="INT", mode="rw", ltype="int" },
-+ },
-+}
-+local max_options = 50
-+
-+local function foreach_opt(func)
-+ for i=1,#socket_options do
-+ local ver_opts = socket_options[i]
-+ for num=1,max_options do
-+ local opt = ver_opts[num]
-+ if opt then
-+ func(num, opt, ver_opts)
-+ end
-+ end
-+ end
-+end
-+local add=function(t,val) return table.insert(t,val) end
-+local function template(data, templ)
-+ return templ:gsub("%${(.-)}", data)
-+end
-+
-+local socket_methods = {}
-+local ffi_opt_names = {}
-+local max_methods = 0
-+local function get_methods(opt, ver)
-+ local num = opt.num
-+ -- check if methods have been created
-+ local methods = socket_methods[num]
-+
-+ if not methods then
-+ add(ffi_opt_names, "\t\t[".. num .. "] = '" .. opt.name .. "',\n")
-+ -- need to create methods info.
-+ methods = {
-+ num=num,
-+ name=opt.name,
-+ get=opt.get, set=opt.set, c_get=opt.c_get, c_set=opt.c_set,
-+ ltype=opt.ltype, otype=opt.otype, mode=opt.mode,
-+ versions = {},
-+ }
-+
-+ -- initialize all version as not-supported.
-+ for i=1,#socket_options do
-+ local ver_opts = socket_options[i]
-+ methods[ver_opts.ver_def] = false
-+ end
-+
-+ if num > max_methods then max_methods = num end
-+
-+ socket_methods[num] = methods
-+ end
-+
-+ -- mark this version as supporting the option.
-+ methods[ver.ver_def] = true
-+ add(methods.versions, ver)
-+
-+ return methods
-+end
-+
-+-- do pre-processing of options.
-+foreach_opt(function(num, opt, ver)
-+ opt.num = num
-+ if not opt.name then
-+ opt.name = 'none'
-+ opt.otype = 'NONE'
-+ opt.DEF = 'unused'
-+ return
-+ end
-+ -- track max option number for each version.
-+ if not ver.max_opt or ver.max_opt < num then
-+ ver.max_opt = num
-+ end
-+ opt.DEF = "ZMQ_" .. opt.name:upper()
-+ -- ctype & ffi_type
-+ local ctype = OPT_TYPES[opt.otype]
-+ opt.ctype = ctype
-+ if opt.otype == 'BLOB' then
-+ opt.ffi_type = 'string'
-+ opt.set_len_param = ', size_t value_len'
-+ opt.set_val_name = 'value'
-+ opt.set_len_name = 'value_len'
-+ elseif ctype ~= 'NONE' then
-+ opt.ffi_type = ctype .. '[1]'
-+ opt.set_len_param = ''
-+ opt.set_val_name = '&value'
-+ opt.set_len_name = 'sizeof(value)'
-+ end
-+ -- getter/setter names
-+ for meth,prefix in pairs(get_set_prefix[opt.mode]) do
-+ opt[meth] = prefix .. opt.name
-+ end
-+ -- create common list of option get/set methods.
-+ local methods = get_methods(opt, ver)
-+end)
-+
-+local options_c_code = {}
-+local opt_types = {}
-+
-+local function if_def(def)
-+ local code = "#if " .. def .. "\n"
-+ add(options_c_code, code)
-+ add(opt_types, code)
-+end
-+local function endif(def)
-+ local code = "#endif /* #if " .. def .. " */\n"
-+ add(options_c_code, code)
-+ add(opt_types, code)
-+end
-+
-+-- build C code for socket options setters/getters
-+local last_ver
-+foreach_opt(function(num, opt, ver)
-+ if ver ~= last_ver then
-+ if last_ver then
-+ endif(last_ver.ver_def)
-+ end
-+ last_ver = ver
-+ if_def(ver.ver_def)
-+ add(opt_types, template(ver,[[
-+#define ${ver_def}_MAX_OPT ${max_opt}
-+]]))
-+ end
-+ add(opt_types, template(opt,[[
-+ OPT_TYPE_${otype}, /* ${num} ${DEF} */
-+]]))
-+ if opt.name == 'none' then return end
-+ -- generate setter
-+ local set = ''
-+ local get = ''
-+ if opt.c_set then
-+ if opt.otype == 'BLOB' then
-+ set = [[
-+LUA_NOBJ_API ZMQ_Error ${c_set}(ZMQ_Socket *sock, const char *value, size_t str_len) {
-+ return zmq_setsockopt(sock, ${DEF}, value, str_len);
-+]]
-+ elseif opt.ctype == opt.ltype then
-+ set = [[
-+LUA_NOBJ_API ZMQ_Error ${c_set}(ZMQ_Socket *sock, ${ltype} value) {
-+ return zmq_setsockopt(sock, ${DEF}, &value, sizeof(value));
-+]]
-+ else
-+ set = [[
-+LUA_NOBJ_API ZMQ_Error ${c_set}(ZMQ_Socket *sock, ${ltype} value) {
-+ ${ctype} val = (${ctype})value;
-+ return zmq_setsockopt(sock, ${DEF}, &val, sizeof(val));
-+]]
-+ end
-+ set = set .. "}\n\n"
-+ end
-+ -- generate getter
-+ if opt.c_get then
-+ if opt.otype == 'BLOB' then
-+ get = [[
-+LUA_NOBJ_API ZMQ_Error ${c_get}(ZMQ_Socket *sock, char *value, size_t *len) {
-+ return zmq_getsockopt(sock, ${DEF}, value, len);
-+]]
-+ elseif opt.ctype == opt.ltype then
-+ get = [[
-+LUA_NOBJ_API ZMQ_Error ${c_get}(ZMQ_Socket *sock, ${ltype} *value) {
-+ size_t val_len = sizeof(${ltype});
-+ return zmq_getsockopt(sock, ${DEF}, value, &val_len);
-+]]
-+ else
-+ get = [[
-+LUA_NOBJ_API ZMQ_Error ${c_get}(ZMQ_Socket *sock, ${ltype} *value) {
-+ ${ctype} val;
-+ size_t val_len = sizeof(val);
-+ int rc = zmq_getsockopt(sock, ${DEF}, &val, &val_len);
-+ *value = (${ltype})val;
-+ return rc;
-+]]
-+ end
-+ get = get .. "}\n\n"
-+ end
-+ local templ
-+ if opt.custom then
-+ templ = opt.custom
-+ else
-+ templ = set .. get
-+ end
-+ add(options_c_code, template(opt,templ))
-+end)
-+endif(last_ver.ver_def)
-+
-+add(opt_types, [[
-+#if VERSION_3_0
-+# define MAX_OPTS VERSION_3_0_MAX_OPT
-+#else
-+# if VERSION_2_2
-+# define MAX_OPTS VERSION_2_2_MAX_OPT
-+# elif VERSION_2_1
-+# define MAX_OPTS VERSION_2_1_MAX_OPT
-+# else
-+# define MAX_OPTS VERSION_2_0_MAX_OPT
-+# endif
-+#endif
-+};
-+
-+]])
-+
-+options_c_code = table.concat(options_c_code)
-+opt_types = table.concat(opt_types)
-+ffi_opt_names = table.concat(ffi_opt_names)
-+
-+local function tunpack(tab, idx, max)
-+ if idx == max then return tab[idx] end
-+ return tab[idx], tunpack(tab, idx + 1, max)
-+end
-+
-+local function build_meth_if_def(meth)
-+ local v = {}
-+ for i=1,#socket_options do
-+ local ver_opts = socket_options[i]
-+ if meth[ver_opts.ver_def] then
-+ v[#v+1] = ver_opts.ver_def
-+ end
-+ end
-+ return v
-+end
-+
-+local function build_option_methods()
-+ local m = {}
-+
-+ for i=1,max_methods do
-+ local meth = socket_methods[i]
-+ if meth then
-+ local ltype = meth.ltype
-+ local name
-+ -- get list of version defs for this method.
-+ local if_defs = build_meth_if_def(meth)
-+ -- generate getter method.
-+ name = meth.get
-+ if name then
-+ local args = { ltype, "&value" }
-+ local val_out = { ltype, "&value" }
-+ if meth.otype == 'BLOB' then
-+ val_out = { 'char *', "value", has_length = true }
-+ args = { 'char *', "value", "size_t", "&#value" }
-+ end
-+ m[#m+1] = method (name) { if_defs = if_defs,
-+ var_out(val_out),
-+ c_export_method_call "ZMQ_Error" (meth.c_get) (args),
-+ }
-+ end
-+ -- generate setter method.
-+ name = meth.set
-+ if name then
-+ local args = { ltype, "value" }
-+ if meth.otype == 'BLOB' then
-+ args = { ltype, "value", "size_t", "#value" }
-+ end
-+ m[#m+1] = method (name) { if_defs = if_defs,
-+ c_export_method_call "ZMQ_Error" (meth.c_set) (args),
-+ }
-+ end
-+ end
-+ end
-+
-+ return tunpack(m, 1, #m)
-+end
-+
-+-------------------------------------------------------------------------------------
-+--
-+-- ZeroMQ socket object.
-+--
-+-------------------------------------------------------------------------------------
-+
- object "ZMQ_Socket" {
- error_on_null = "get_zmq_strerror()",
-- c_source [[
--/* detect zmq version >= 2.1.0 */
--#define VERSION_2_1 0
--#if defined(ZMQ_VERSION)
--#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0))
--#undef VERSION_2_1
--#define VERSION_2_1 1
--#endif
--#endif
-+ ffi_source "ffi_pre_cdef" [[
-+
-+-- detect zmq version
-+local VERSION_2_0 = true
-+local VERSION_2_1 = false
-+local VERSION_2_2 = false
-+local VERSION_3_0 = false
-+local zver = _M.version()
-+if zver[1] == 3 then
-+ VERSION_2_0 = false
-+ VERSION_3_0 = true
-+elseif zver[1] == 2 and zver[2] == 2 then
-+ VERSION_2_2 = true
-+ VERSION_2_1 = true
-+elseif zver[1] == 2 and zver[2] == 1 then
-+ VERSION_2_1 = true
-+end
-+
-+if VERSION_2_0 then
-+ ffi.cdef[==[
-+typedef int ZMQ_Error;
-+typedef struct ZMQ_Socket ZMQ_Socket;
-+typedef struct zmq_msg_t zmq_msg_t;
-+
-+ZMQ_Error zmq_sendmsg(ZMQ_Socket *sock, zmq_msg_t *msg, int flags) __asm__("zmq_send");
-+ZMQ_Error zmq_recvmsg(ZMQ_Socket *sock, zmq_msg_t *msg, int flags) __asm__("zmq_recv");
-+]==]
-+end
-+]],
-+ c_source ([[
-
- /* detect really old ZeroMQ 2.0.x series. */
- #if !defined(ZMQ_RCVMORE)
--#error "Your version of ZeroMQ is too old. Please upgrade to version 2.1 or to the latest 2.0.x"
-+# error "Your version of ZeroMQ is too old. Please upgrade to version 2.1 or to the latest 2.0.x"
- #endif
-
- typedef struct ZMQ_Socket ZMQ_Socket;
-@@ -44,47 +439,23 @@ typedef SOCKET socket_t;
- typedef int socket_t;
- #endif
-
-+#if VERSION_2_0
-+# define zmq_sendmsg zmq_send
-+# define zmq_recvmsg zmq_recv
-+#endif
-+
- /* socket option types. */
- #define OPT_TYPE_NONE 0
- #define OPT_TYPE_INT 1
- #define OPT_TYPE_UINT32 2
- #define OPT_TYPE_UINT64 3
- #define OPT_TYPE_INT64 4
--#define OPT_TYPE_STR 5
-+#define OPT_TYPE_BLOB 5
- #define OPT_TYPE_FD 6
-
- static const int opt_types[] = {
-- OPT_TYPE_NONE, /* 0 unused */
-- OPT_TYPE_UINT64, /* 1 ZMQ_HWM */
-- OPT_TYPE_NONE, /* 2 unused */
-- OPT_TYPE_INT64, /* 3 ZMQ_SWAP */
-- OPT_TYPE_UINT64, /* 4 ZMQ_AFFINITY */
-- OPT_TYPE_STR, /* 5 ZMQ_IDENTITY */
-- OPT_TYPE_STR, /* 6 ZMQ_SUBSCRIBE */
-- OPT_TYPE_STR, /* 7 ZMQ_UNSUBSCRIBE */
-- OPT_TYPE_INT64, /* 8 ZMQ_RATE */
-- OPT_TYPE_INT64, /* 9 ZMQ_RECOVERY_IVL */
-- OPT_TYPE_INT64, /* 10 ZMQ_MCAST_LOOP */
-- OPT_TYPE_UINT64, /* 11 ZMQ_SNDBUF */
-- OPT_TYPE_UINT64, /* 12 ZMQ_RCVBUF */
-- OPT_TYPE_INT64, /* 13 ZMQ_RCVMORE */
--
--#if VERSION_2_1
-- OPT_TYPE_FD, /* 14 ZMQ_FD */
-- OPT_TYPE_UINT32, /* 15 ZMQ_EVENTS */
-- OPT_TYPE_INT, /* 16 ZMQ_TYPE */
-- OPT_TYPE_INT, /* 17 ZMQ_LINGER */
-- OPT_TYPE_INT, /* 18 ZMQ_RECONNECT_IVL */
-- OPT_TYPE_INT, /* 19 ZMQ_BACKLOG */
--#endif
--};
--#if VERSION_2_1
--#define MAX_OPTS ZMQ_BACKLOG
--#else
--#define MAX_OPTS ZMQ_RCVMORE
--#endif
--
--]],
-+ OPT_TYPE_NONE, /* 0 unused */
-+]] .. opt_types .. options_c_code),
-
- destructor "close" {
- c_method_call "ZMQ_Error" "zmq_close" {}
-@@ -99,37 +470,32 @@ static const int opt_types[] = {
- int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen);
- int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen);
- ]],
-- ffi_source[[
--local option_types = {
--[zmq.HWM] = 'uint64_t[1]',
--[zmq.SWAP] = 'int64_t[1]',
--[zmq.AFFINITY] = 'uint64_t[1]',
--[zmq.IDENTITY] = 'string',
--[zmq.SUBSCRIBE] = 'string',
--[zmq.UNSUBSCRIBE] = 'string',
--[zmq.RATE] = 'int64_t[1]',
--[zmq.RECOVERY_IVL] = 'int64_t[1]',
--[zmq.MCAST_LOOP] = 'int64_t[1]',
--[zmq.SNDBUF] = 'uint64_t[1]',
--[zmq.RCVBUF] = 'uint64_t[1]',
--[zmq.RCVMORE] = 'int64_t[1]',
--[zmq.FD] = 'int[1]',
--[zmq.EVENTS] = 'uint32_t[1]',
--[zmq.TYPE] = 'int[1]',
--[zmq.LINGER] = 'int[1]',
--[zmq.RECONNECT_IVL] = 'int[1]',
--[zmq.BACKLOG] = 'int[1]',
--}
--local option_len = {}
--local option_tmps = {}
--for k,v in pairs(option_types) do
-- if v ~= 'string' then
-- option_len[k] = ffi.sizeof(v)
-- option_tmps[k] = ffi.new(v, 0)
-- end
-+ ffi_source([[
-+local option_gets = {}
-+local option_sets = {}
-+
-+do
-+ local opt_name
-+ local methods = _meth.${object_name}
-+ setmetatable(option_gets,{__index = function(tab,opt)
-+ local opt_name = opt_name[opt]
-+ if not opt_name then return nil end
-+ local method = methods[opt_name]
-+ rawset(tab, opt, method)
-+ return method
-+ end})
-+ setmetatable(option_sets,{__index = function(tab,opt)
-+ local opt_name = opt_name[opt]
-+ if not opt_name then return nil end
-+ local method = methods['set_' .. opt_name] or methods[opt_name]
-+ rawset(tab, opt, method)
-+ return method
-+ end})
-+ opt_name = {
-+]] .. ffi_opt_names .. [[}
- end
-
--]],
-+]]),
- method "setopt" {
- var_in{ "uint32_t", "opt" },
- var_in{ "<any>", "val" },
-@@ -138,7 +504,7 @@ end
- size_t val_len;
- const void *val;
-
--#if VERSION_2_1
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
- socket_t fd_val;
- #endif
- int int_val;
-@@ -146,12 +512,26 @@ end
- uint64_t uint64_val;
- int64_t int64_val;
-
-+#if VERSION_3_0
-+ /* 3.0 backwards compatibility support for HWM. */
-+ if(${opt} == ZMQ_HWM) {
-+ int_val = luaL_checklong(L, ${val::idx});
-+ val = &int_val;
-+ val_len = sizeof(int_val);
-+ ${err} = zmq_setsockopt(${this}, ZMQ_SNDHWM, val, val_len);
-+ if(-1 != ${err}) {
-+ ${err} = zmq_setsockopt(${this}, ZMQ_RCVHWM, val, val_len);
-+ }
-+ goto finished;
-+ }
-+#endif
-+
- if(${opt} > MAX_OPTS) {
- return luaL_argerror(L, ${opt::idx}, "Invalid socket option.");
- }
-
- switch(opt_types[${opt}]) {
--#if VERSION_2_1
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
- case OPT_TYPE_FD:
- fd_val = luaL_checklong(L, ${val::idx});
- val = &fd_val;
-@@ -178,7 +558,7 @@ end
- val = &int64_val;
- val_len = sizeof(int64_val);
- break;
-- case OPT_TYPE_STR:
-+ case OPT_TYPE_BLOB:
- val = luaL_checklstring(L, ${val::idx}, &(val_len));
- break;
- default:
-@@ -187,20 +567,15 @@ end
- break;
- }
- ${err} = zmq_setsockopt(${this}, ${opt}, val, val_len);
-+finished:
- ]],
- ffi_source[[
-- local ctype = option_types[${opt}]
-- local tval
-- local tval_len = 0
-- if ctype == 'string' then
-- tval = tostring(${val})
-- tval_len = #${val}
-+ local set = option_sets[${opt}]
-+ if set then
-+ return set(${this},${val})
- else
-- tval = option_tmps[${opt}]
-- tval[0] = ${val}
-- tval_len = option_len[${opt}]
-+ error("Invalid socket option.")
- end
-- ${err} = C.zmq_setsockopt(${this}, ${opt}, tval, tval_len)
- ]],
- },
- ffi_source[[
-@@ -213,7 +588,7 @@ local tmp_val_len = ffi.new('size_t[1]', 4)
- c_source[[
- size_t val_len;
-
--#if VERSION_2_1
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
- socket_t fd_val;
- #endif
- int int_val;
-@@ -230,7 +605,7 @@ local tmp_val_len = ffi.new('size_t[1]', 4)
- }
-
- switch(opt_types[${opt}]) {
--#if VERSION_2_1
-+#if defined(VERSION_2_1) || defined(VERSION_3_0)
- case OPT_TYPE_FD:
- val_len = sizeof(fd_val);
- ${err} = zmq_getsockopt(${this}, ${opt}, &fd_val, &val_len);
-@@ -272,7 +647,7 @@ local tmp_val_len = ffi.new('size_t[1]', 4)
- return 1;
- }
- break;
-- case OPT_TYPE_STR:
-+ case OPT_TYPE_BLOB:
- val_len = STR_MAX;
- ${err} = zmq_getsockopt(${this}, ${opt}, str_val, &val_len);
- if(0 == ${err}) {
-@@ -289,62 +664,23 @@ local tmp_val_len = ffi.new('size_t[1]', 4)
- lua_pushnil(L);
- ]],
- ffi_source[[
-- local ctype = option_types[${opt}]
-- local val
-- local val_len = tmp_val_len
-- if ctype == 'string' then
-- val_len[0] = 255
-- val = ffi.new('uint8_t[?]', val_len[0])
-- ffi.fill(val, val_len[0])
-+ local get = option_gets[${opt}]
-+ if get then
-+ return get(${this})
- else
-- val = option_tmps[${opt}]
-- val[0] = 0
-- val_len[0] = option_len[${opt}]
-- end
-- ${err} = C.zmq_getsockopt(${this}, ${opt}, val, val_len)
-- if ${err} == 0 then
-- if ctype == 'string' then
-- val_len = val_len[0]
-- return ffi.string(val, val_len)
-- else
-- return tonumber(val[0])
-- end
-+ error("Invalid socket option.")
- end
- ]],
- },
-- ffi_source[[
---- temp. values for 'events' function.
--local events_tmp = ffi.new('uint32_t[1]', 0)
--local events_tmp_size = ffi.sizeof('uint32_t')
--local events_tmp_len = ffi.new('size_t[1]', events_tmp_size)
--local ZMQ_EVENTS = _M.EVENTS
--]],
-- method "events" {
-- var_out{ "uint32_t", "events" },
-- var_out{ "ZMQ_Error", "err" },
-- c_source[[
--#if VERSION_2_1
-- size_t val_len = sizeof(${events});
-- ${err} = zmq_getsockopt(${this}, ZMQ_EVENTS, &(${events}), &val_len);
--#else
-- luaL_error(L, "'events' method only supported in 0MQ version >= 2.1");
--#endif
--]],
-- ffi_source[[
-- events_tmp_len[0] = events_tmp_size
-- ${err} = C.zmq_getsockopt(${this}, ZMQ_EVENTS, events_tmp, events_tmp_len);
-- ${events} = events_tmp[0]
--]],
-- },
- --
- -- zmq_send
- --
- method "send_msg" {
-- c_method_call "ZMQ_Error" "zmq_send" { "zmq_msg_t *", "msg", "int", "flags?" },
-+ c_method_call "ZMQ_Error" "zmq_sendmsg" { "zmq_msg_t *", "msg", "int", "flags?" },
- },
- -- create helper function for `zmq_send`
- c_source[[
--static ZMQ_Error simple_zmq_send(ZMQ_Socket *sock, const char *data, size_t data_len, int flags) {
-+LUA_NOBJ_API ZMQ_Error simple_zmq_send(ZMQ_Socket *sock, const char *data, size_t data_len, int flags) {
- ZMQ_Error err;
- zmq_msg_t msg;
- /* initialize message */
-@@ -353,32 +689,22 @@ static ZMQ_Error simple_zmq_send(ZMQ_Socket *sock, const char *data, size_t data
- /* fill message */
- memcpy(zmq_msg_data(&msg), data, data_len);
- /* send message */
-- err = zmq_send(sock, &msg, flags);
-+ err = zmq_sendmsg(sock, &msg, flags);
- /* close message */
- zmq_msg_close(&msg);
- }
- return err;
- }
- ]],
-- -- export helper function.
-- ffi_export_function "ZMQ_Error" "simple_zmq_send"
-- "(ZMQ_Socket *sock, const char *data, size_t data_len, int flags)",
- method "send" {
-- var_in{ "const char *", "data" },
-- var_in{ "int", "flags?" },
-- var_out{ "ZMQ_Error", "err" },
-- c_source[[
-- ${err} = simple_zmq_send(${this}, ${data}, ${data_len}, ${flags});
--]],
-- ffi_source[[
-- ${err} = simple_zmq_send(${this}, ${data}, ${data_len}, ${flags});
--]],
-+ c_export_method_call "ZMQ_Error" "simple_zmq_send"
-+ { "const char *", "data", "size_t", "#data", "int", "flags?"}
- },
- --
- -- zmq_recv
- --
- method "recv_msg" {
-- c_method_call "ZMQ_Error" "zmq_recv" { "zmq_msg_t *", "msg", "int", "flags?" },
-+ c_method_call "ZMQ_Error" "zmq_recvmsg" { "zmq_msg_t *", "msg", "int", "flags?" },
- },
- ffi_source[[
- local tmp_msg = ffi.new('zmq_msg_t')
-@@ -393,8 +719,8 @@ local tmp_msg = ffi.new('zmq_msg_t')
- ${err} = zmq_msg_init(&msg);
- if(0 == ${err}) {
- /* receive message */
-- ${err} = zmq_recv(${this}, &msg, ${flags});
-- if(0 == ${err}) {
-+ ${err} = zmq_recvmsg(${this}, &msg, ${flags});
-+ if(${err} >= 0) {
- ${data} = zmq_msg_data(&msg);
- ${data_len} = zmq_msg_size(&msg);
- }
-@@ -412,8 +738,8 @@ local tmp_msg = ffi.new('zmq_msg_t')
- end
-
- -- receive message
-- ${err} = C.zmq_recv(${this}, msg, ${flags})
-- if 0 == ${err} then
-+ ${err} = C.zmq_recvmsg(${this}, msg, ${flags})
-+ if ${err} >= 0 then
- local data = ffi.string(C.zmq_msg_data(msg), C.zmq_msg_size(msg))
- -- close message
- C.zmq_msg_close(msg)
-@@ -425,5 +751,8 @@ local tmp_msg = ffi.new('zmq_msg_t')
- C.zmq_msg_close(msg)
- ]],
- },
-+
-+ -- build option set/get methods. THIS MUST BE LAST.
-+ build_option_methods(),
- }
-
-diff --git a/src/threads.lua b/src/threads.lua
-index 99257ea..e37838a 100644
---- a/src/threads.lua
-+++ b/src/threads.lua
-@@ -85,26 +85,28 @@ local function new_thread(ctx, action, action_arg, ...)
- }, thread_mt)
- end
-
--module(...)
-+local M = {}
-
--function set_bootstrap_prelude(code)
-+function M.set_bootstrap_prelude(code)
- bootstrap_code = bootstrap_pre .. code .. bootstrap_post
- end
-
--function runfile(ctx, file, ...)
-+function M.runfile(ctx, file, ...)
- return new_thread(ctx, 'runfile', file, ...)
- end
-
--function runstring(ctx, code, ...)
-+function M.runstring(ctx, code, ...)
- return new_thread(ctx, 'runstring', code, ...)
- end
-
- local parent_ctx = nil
--function set_parent_ctx(ctx)
-+function M.set_parent_ctx(ctx)
- parent_ctx = ctx
- end
-
--function get_parent_ctx(ctx)
-+function M.get_parent_ctx(ctx)
- return parent_ctx
- end
-
-+zmq.threads = M
-+return M
-diff --git a/ws/LICENSE_GPL.txt b/ws/LICENSE_GPL.txt
-new file mode 100644
-index 0000000..94a9ed0
---- /dev/null
-+++ b/ws/LICENSE_GPL.txt
-@@ -0,0 +1,674 @@
-+ GNU GENERAL PUBLIC LICENSE
-+ Version 3, 29 June 2007
-+
-+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
-+ Everyone is permitted to copy and distribute verbatim copies
-+ of this license document, but changing it is not allowed.
-+
-+ Preamble
-+
-+ The GNU General Public License is a free, copyleft license for
-+software and other kinds of works.
-+
-+ The licenses for most software and other practical works are designed
-+to take away your freedom to share and change the works. By contrast,
-+the GNU General Public License is intended to guarantee your freedom to
-+share and change all versions of a program--to make sure it remains free
-+software for all its users. We, the Free Software Foundation, use the
-+GNU General Public License for most of our software; it applies also to
-+any other work released this way by its authors. You can apply it to
-+your programs, too.
-+
-+ When we speak of free software, we are referring to freedom, not
-+price. Our General Public Licenses are designed to make sure that you
-+have the freedom to distribute copies of free software (and charge for
-+them if you wish), that you receive source code or can get it if you
-+want it, that you can change the software or use pieces of it in new
-+free programs, and that you know you can do these things.
-+
-+ To protect your rights, we need to prevent others from denying you
-+these rights or asking you to surrender the rights. Therefore, you have
-+certain responsibilities if you distribute copies of the software, or if
-+you modify it: responsibilities to respect the freedom of others.
-+
-+ For example, if you distribute copies of such a program, whether
-+gratis or for a fee, you must pass on to the recipients the same
-+freedoms that you received. You must make sure that they, too, receive
-+or can get the source code. And you must show them these terms so they
-+know their rights.
-+
-+ Developers that use the GNU GPL protect your rights with two steps:
-+(1) assert copyright on the software, and (2) offer you this License
-+giving you legal permission to copy, distribute and/or modify it.
-+
-+ For the developers' and authors' protection, the GPL clearly explains
-+that there is no warranty for this free software. For both users' and
-+authors' sake, the GPL requires that modified versions be marked as
-+changed, so that their problems will not be attributed erroneously to
-+authors of previous versions.
-+
-+ Some devices are designed to deny users access to install or run
-+modified versions of the software inside them, although the manufacturer
-+can do so. This is fundamentally incompatible with the aim of
-+protecting users' freedom to change the software. The systematic
-+pattern of such abuse occurs in the area of products for individuals to
-+use, which is precisely where it is most unacceptable. Therefore, we
-+have designed this version of the GPL to prohibit the practice for those
-+products. If such problems arise substantially in other domains, we
-+stand ready to extend this provision to those domains in future versions
-+of the GPL, as needed to protect the freedom of users.
-+
-+ Finally, every program is threatened constantly by software patents.
-+States should not allow patents to restrict development and use of
-+software on general-purpose computers, but in those that do, we wish to
-+avoid the special danger that patents applied to a free program could
-+make it effectively proprietary. To prevent this, the GPL assures that
-+patents cannot be used to render the program non-free.
-+
-+ The precise terms and conditions for copying, distribution and
-+modification follow.
-+
-+ TERMS AND CONDITIONS
-+
-+ 0. Definitions.
-+
-+ "This License" refers to version 3 of the GNU General Public License.
-+
-+ "Copyright" also means copyright-like laws that apply to other kinds of
-+works, such as semiconductor masks.
-+
-+ "The Program" refers to any copyrightable work licensed under this
-+License. Each licensee is addressed as "you". "Licensees" and
-+"recipients" may be individuals or organizations.
-+
-+ To "modify" a work means to copy from or adapt all or part of the work
-+in a fashion requiring copyright permission, other than the making of an
-+exact copy. The resulting work is called a "modified version" of the
-+earlier work or a work "based on" the earlier work.
-+
-+ A "covered work" means either the unmodified Program or a work based
-+on the Program.
-+
-+ To "propagate" a work means to do anything with it that, without
-+permission, would make you directly or secondarily liable for
-+infringement under applicable copyright law, except executing it on a
-+computer or modifying a private copy. Propagation includes copying,
-+distribution (with or without modification), making available to the
-+public, and in some countries other activities as well.
-+
-+ To "convey" a work means any kind of propagation that enables other
-+parties to make or receive copies. Mere interaction with a user through
-+a computer network, with no transfer of a copy, is not conveying.
-+
-+ An interactive user interface displays "Appropriate Legal Notices"
-+to the extent that it includes a convenient and prominently visible
-+feature that (1) displays an appropriate copyright notice, and (2)
-+tells the user that there is no warranty for the work (except to the
-+extent that warranties are provided), that licensees may convey the
-+work under this License, and how to view a copy of this License. If
-+the interface presents a list of user commands or options, such as a
-+menu, a prominent item in the list meets this criterion.
-+
-+ 1. Source Code.
-+
-+ The "source code" for a work means the preferred form of the work
-+for making modifications to it. "Object code" means any non-source
-+form of a work.
-+
-+ A "Standard Interface" means an interface that either is an official
-+standard defined by a recognized standards body, or, in the case of
-+interfaces specified for a particular programming language, one that
-+is widely used among developers working in that language.
-+
-+ The "System Libraries" of an executable work include anything, other
-+than the work as a whole, that (a) is included in the normal form of
-+packaging a Major Component, but which is not part of that Major
-+Component, and (b) serves only to enable use of the work with that
-+Major Component, or to implement a Standard Interface for which an
-+implementation is available to the public in source code form. A
-+"Major Component", in this context, means a major essential component
-+(kernel, window system, and so on) of the specific operating system
-+(if any) on which the executable work runs, or a compiler used to
-+produce the work, or an object code interpreter used to run it.
-+
-+ The "Corresponding Source" for a work in object code form means all
-+the source code needed to generate, install, and (for an executable
-+work) run the object code and to modify the work, including scripts to
-+control those activities. However, it does not include the work's
-+System Libraries, or general-purpose tools or generally available free
-+programs which are used unmodified in performing those activities but
-+which are not part of the work. For example, Corresponding Source
-+includes interface definition files associated with source files for
-+the work, and the source code for shared libraries and dynamically
-+linked subprograms that the work is specifically designed to require,
-+such as by intimate data communication or control flow between those
-+subprograms and other parts of the work.
-+
-+ The Corresponding Source need not include anything that users
-+can regenerate automatically from other parts of the Corresponding
-+Source.
-+
-+ The Corresponding Source for a work in source code form is that
-+same work.
-+
-+ 2. Basic Permissions.
-+
-+ All rights granted under this License are granted for the term of
-+copyright on the Program, and are irrevocable provided the stated
-+conditions are met. This License explicitly affirms your unlimited
-+permission to run the unmodified Program. The output from running a
-+covered work is covered by this License only if the output, given its
-+content, constitutes a covered work. This License acknowledges your
-+rights of fair use or other equivalent, as provided by copyright law.
-+
-+ You may make, run and propagate covered works that you do not
-+convey, without conditions so long as your license otherwise remains
-+in force. You may convey covered works to others for the sole purpose
-+of having them make modifications exclusively for you, or provide you
-+with facilities for running those works, provided that you comply with
-+the terms of this License in conveying all material for which you do
-+not control copyright. Those thus making or running the covered works
-+for you must do so exclusively on your behalf, under your direction
-+and control, on terms that prohibit them from making any copies of
-+your copyrighted material outside their relationship with you.
-+
-+ Conveying under any other circumstances is permitted solely under
-+the conditions stated below. Sublicensing is not allowed; section 10
-+makes it unnecessary.
-+
-+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-+
-+ No covered work shall be deemed part of an effective technological
-+measure under any applicable law fulfilling obligations under article
-+11 of the WIPO copyright treaty adopted on 20 December 1996, or
-+similar laws prohibiting or restricting circumvention of such
-+measures.
-+
-+ When you convey a covered work, you waive any legal power to forbid
-+circumvention of technological measures to the extent such circumvention
-+is effected by exercising rights under this License with respect to
-+the covered work, and you disclaim any intention to limit operation or
-+modification of the work as a means of enforcing, against the work's
-+users, your or third parties' legal rights to forbid circumvention of
-+technological measures.
-+
-+ 4. Conveying Verbatim Copies.
-+
-+ You may convey verbatim copies of the Program's source code as you
-+receive it, in any medium, provided that you conspicuously and
-+appropriately publish on each copy an appropriate copyright notice;
-+keep intact all notices stating that this License and any
-+non-permissive terms added in accord with section 7 apply to the code;
-+keep intact all notices of the absence of any warranty; and give all
-+recipients a copy of this License along with the Program.
-+
-+ You may charge any price or no price for each copy that you convey,
-+and you may offer support or warranty protection for a fee.
-+
-+ 5. Conveying Modified Source Versions.
-+
-+ You may convey a work based on the Program, or the modifications to
-+produce it from the Program, in the form of source code under the
-+terms of section 4, provided that you also meet all of these conditions:
-+
-+ a) The work must carry prominent notices stating that you modified
-+ it, and giving a relevant date.
-+
-+ b) The work must carry prominent notices stating that it is
-+ released under this License and any conditions added under section
-+ 7. This requirement modifies the requirement in section 4 to
-+ "keep intact all notices".
-+
-+ c) You must license the entire work, as a whole, under this
-+ License to anyone who comes into possession of a copy. This
-+ License will therefore apply, along with any applicable section 7
-+ additional terms, to the whole of the work, and all its parts,
-+ regardless of how they are packaged. This License gives no
-+ permission to license the work in any other way, but it does not
-+ invalidate such permission if you have separately received it.
-+
-+ d) If the work has interactive user interfaces, each must display
-+ Appropriate Legal Notices; however, if the Program has interactive
-+ interfaces that do not display Appropriate Legal Notices, your
-+ work need not make them do so.
-+
-+ A compilation of a covered work with other separate and independent
-+works, which are not by their nature extensions of the covered work,
-+and which are not combined with it such as to form a larger program,
-+in or on a volume of a storage or distribution medium, is called an
-+"aggregate" if the compilation and its resulting copyright are not
-+used to limit the access or legal rights of the compilation's users
-+beyond what the individual works permit. Inclusion of a covered work
-+in an aggregate does not cause this License to apply to the other
-+parts of the aggregate.
-+
-+ 6. Conveying Non-Source Forms.
-+
-+ You may convey a covered work in object code form under the terms
-+of sections 4 and 5, provided that you also convey the
-+machine-readable Corresponding Source under the terms of this License,
-+in one of these ways:
-+
-+ a) Convey the object code in, or embodied in, a physical product
-+ (including a physical distribution medium), accompanied by the
-+ Corresponding Source fixed on a durable physical medium
-+ customarily used for software interchange.
-+
-+ b) Convey the object code in, or embodied in, a physical product
-+ (including a physical distribution medium), accompanied by a
-+ written offer, valid for at least three years and valid for as
-+ long as you offer spare parts or customer support for that product
-+ model, to give anyone who possesses the object code either (1) a
-+ copy of the Corresponding Source for all the software in the
-+ product that is covered by this License, on a durable physical
-+ medium customarily used for software interchange, for a price no
-+ more than your reasonable cost of physically performing this
-+ conveying of source, or (2) access to copy the
-+ Corresponding Source from a network server at no charge.
-+
-+ c) Convey individual copies of the object code with a copy of the
-+ written offer to provide the Corresponding Source. This
-+ alternative is allowed only occasionally and noncommercially, and
-+ only if you received the object code with such an offer, in accord
-+ with subsection 6b.
-+
-+ d) Convey the object code by offering access from a designated
-+ place (gratis or for a charge), and offer equivalent access to the
-+ Corresponding Source in the same way through the same place at no
-+ further charge. You need not require recipients to copy the
-+ Corresponding Source along with the object code. If the place to
-+ copy the object code is a network server, the Corresponding Source
-+ may be on a different server (operated by you or a third party)
-+ that supports equivalent copying facilities, provided you maintain
-+ clear directions next to the object code saying where to find the
-+ Corresponding Source. Regardless of what server hosts the
-+ Corresponding Source, you remain obligated to ensure that it is
-+ available for as long as needed to satisfy these requirements.
-+
-+ e) Convey the object code using peer-to-peer transmission, provided
-+ you inform other peers where the object code and Corresponding
-+ Source of the work are being offered to the general public at no
-+ charge under subsection 6d.
-+
-+ A separable portion of the object code, whose source code is excluded
-+from the Corresponding Source as a System Library, need not be
-+included in conveying the object code work.
-+
-+ A "User Product" is either (1) a "consumer product", which means any
-+tangible personal property which is normally used for personal, family,
-+or household purposes, or (2) anything designed or sold for incorporation
-+into a dwelling. In determining whether a product is a consumer product,
-+doubtful cases shall be resolved in favor of coverage. For a particular
-+product received by a particular user, "normally used" refers to a
-+typical or common use of that class of product, regardless of the status
-+of the particular user or of the way in which the particular user
-+actually uses, or expects or is expected to use, the product. A product
-+is a consumer product regardless of whether the product has substantial
-+commercial, industrial or non-consumer uses, unless such uses represent
-+the only significant mode of use of the product.
-+
-+ "Installation Information" for a User Product means any methods,
-+procedures, authorization keys, or other information required to install
-+and execute modified versions of a covered work in that User Product from
-+a modified version of its Corresponding Source. The information must
-+suffice to ensure that the continued functioning of the modified object
-+code is in no case prevented or interfered with solely because
-+modification has been made.
-+
-+ If you convey an object code work under this section in, or with, or
-+specifically for use in, a User Product, and the conveying occurs as
-+part of a transaction in which the right of possession and use of the
-+User Product is transferred to the recipient in perpetuity or for a
-+fixed term (regardless of how the transaction is characterized), the
-+Corresponding Source conveyed under this section must be accompanied
-+by the Installation Information. But this requirement does not apply
-+if neither you nor any third party retains the ability to install
-+modified object code on the User Product (for example, the work has
-+been installed in ROM).
-+
-+ The requirement to provide Installation Information does not include a
-+requirement to continue to provide support service, warranty, or updates
-+for a work that has been modified or installed by the recipient, or for
-+the User Product in which it has been modified or installed. Access to a
-+network may be denied when the modification itself materially and
-+adversely affects the operation of the network or violates the rules and
-+protocols for communication across the network.
-+
-+ Corresponding Source conveyed, and Installation Information provided,
-+in accord with this section must be in a format that is publicly
-+documented (and with an implementation available to the public in
-+source code form), and must require no special password or key for
-+unpacking, reading or copying.
-+
-+ 7. Additional Terms.
-+
-+ "Additional permissions" are terms that supplement the terms of this
-+License by making exceptions from one or more of its conditions.
-+Additional permissions that are applicable to the entire Program shall
-+be treated as though they were included in this License, to the extent
-+that they are valid under applicable law. If additional permissions
-+apply only to part of the Program, that part may be used separately
-+under those permissions, but the entire Program remains governed by
-+this License without regard to the additional permissions.
-+
-+ When you convey a copy of a covered work, you may at your option
-+remove any additional permissions from that copy, or from any part of
-+it. (Additional permissions may be written to require their own
-+removal in certain cases when you modify the work.) You may place
-+additional permissions on material, added by you to a covered work,
-+for which you have or can give appropriate copyright permission.
-+
-+ Notwithstanding any other provision of this License, for material you
-+add to a covered work, you may (if authorized by the copyright holders of
-+that material) supplement the terms of this License with terms:
-+
-+ a) Disclaiming warranty or limiting liability differently from the
-+ terms of sections 15 and 16 of this License; or
-+
-+ b) Requiring preservation of specified reasonable legal notices or
-+ author attributions in that material or in the Appropriate Legal
-+ Notices displayed by works containing it; or
-+
-+ c) Prohibiting misrepresentation of the origin of that material, or
-+ requiring that modified versions of such material be marked in
-+ reasonable ways as different from the original version; or
-+
-+ d) Limiting the use for publicity purposes of names of licensors or
-+ authors of the material; or
-+
-+ e) Declining to grant rights under trademark law for use of some
-+ trade names, trademarks, or service marks; or
-+
-+ f) Requiring indemnification of licensors and authors of that
-+ material by anyone who conveys the material (or modified versions of
-+ it) with contractual assumptions of liability to the recipient, for
-+ any liability that these contractual assumptions directly impose on
-+ those licensors and authors.
-+
-+ All other non-permissive additional terms are considered "further
-+restrictions" within the meaning of section 10. If the Program as you
-+received it, or any part of it, contains a notice stating that it is
-+governed by this License along with a term that is a further
-+restriction, you may remove that term. If a license document contains
-+a further restriction but permits relicensing or conveying under this
-+License, you may add to a covered work material governed by the terms
-+of that license document, provided that the further restriction does
-+not survive such relicensing or conveying.
-+
-+ If you add terms to a covered work in accord with this section, you
-+must place, in the relevant source files, a statement of the
-+additional terms that apply to those files, or a notice indicating
-+where to find the applicable terms.
-+
-+ Additional terms, permissive or non-permissive, may be stated in the
-+form of a separately written license, or stated as exceptions;
-+the above requirements apply either way.
-+
-+ 8. Termination.
-+
-+ You may not propagate or modify a covered work except as expressly
-+provided under this License. Any attempt otherwise to propagate or
-+modify it is void, and will automatically terminate your rights under
-+this License (including any patent licenses granted under the third
-+paragraph of section 11).
-+
-+ However, if you cease all violation of this License, then your
-+license from a particular copyright holder is reinstated (a)
-+provisionally, unless and until the copyright holder explicitly and
-+finally terminates your license, and (b) permanently, if the copyright
-+holder fails to notify you of the violation by some reasonable means
-+prior to 60 days after the cessation.
-+
-+ Moreover, your license from a particular copyright holder is
-+reinstated permanently if the copyright holder notifies you of the
-+violation by some reasonable means, this is the first time you have
-+received notice of violation of this License (for any work) from that
-+copyright holder, and you cure the violation prior to 30 days after
-+your receipt of the notice.
-+
-+ Termination of your rights under this section does not terminate the
-+licenses of parties who have received copies or rights from you under
-+this License. If your rights have been terminated and not permanently
-+reinstated, you do not qualify to receive new licenses for the same
-+material under section 10.
-+
-+ 9. Acceptance Not Required for Having Copies.
-+
-+ You are not required to accept this License in order to receive or
-+run a copy of the Program. Ancillary propagation of a covered work
-+occurring solely as a consequence of using peer-to-peer transmission
-+to receive a copy likewise does not require acceptance. However,
-+nothing other than this License grants you permission to propagate or
-+modify any covered work. These actions infringe copyright if you do
-+not accept this License. Therefore, by modifying or propagating a
-+covered work, you indicate your acceptance of this License to do so.
-+
-+ 10. Automatic Licensing of Downstream Recipients.
-+
-+ Each time you convey a covered work, the recipient automatically
-+receives a license from the original licensors, to run, modify and
-+propagate that work, subject to this License. You are not responsible
-+for enforcing compliance by third parties with this License.
-+
-+ An "entity transaction" is a transaction transferring control of an
-+organization, or substantially all assets of one, or subdividing an
-+organization, or merging organizations. If propagation of a covered
-+work results from an entity transaction, each party to that
-+transaction who receives a copy of the work also receives whatever
-+licenses to the work the party's predecessor in interest had or could
-+give under the previous paragraph, plus a right to possession of the
-+Corresponding Source of the work from the predecessor in interest, if
-+the predecessor has it or can get it with reasonable efforts.
-+
-+ You may not impose any further restrictions on the exercise of the
-+rights granted or affirmed under this License. For example, you may
-+not impose a license fee, royalty, or other charge for exercise of
-+rights granted under this License, and you may not initiate litigation
-+(including a cross-claim or counterclaim in a lawsuit) alleging that
-+any patent claim is infringed by making, using, selling, offering for
-+sale, or importing the Program or any portion of it.
-+
-+ 11. Patents.
-+
-+ A "contributor" is a copyright holder who authorizes use under this
-+License of the Program or a work on which the Program is based. The
-+work thus licensed is called the contributor's "contributor version".
-+
-+ A contributor's "essential patent claims" are all patent claims
-+owned or controlled by the contributor, whether already acquired or
-+hereafter acquired, that would be infringed by some manner, permitted
-+by this License, of making, using, or selling its contributor version,
-+but do not include claims that would be infringed only as a
-+consequence of further modification of the contributor version. For
-+purposes of this definition, "control" includes the right to grant
-+patent sublicenses in a manner consistent with the requirements of
-+this License.
-+
-+ Each contributor grants you a non-exclusive, worldwide, royalty-free
-+patent license under the contributor's essential patent claims, to
-+make, use, sell, offer for sale, import and otherwise run, modify and
-+propagate the contents of its contributor version.
-+
-+ In the following three paragraphs, a "patent license" is any express
-+agreement or commitment, however denominated, not to enforce a patent
-+(such as an express permission to practice a patent or covenant not to
-+sue for patent infringement). To "grant" such a patent license to a
-+party means to make such an agreement or commitment not to enforce a
-+patent against the party.
-+
-+ If you convey a covered work, knowingly relying on a patent license,
-+and the Corresponding Source of the work is not available for anyone
-+to copy, free of charge and under the terms of this License, through a
-+publicly available network server or other readily accessible means,
-+then you must either (1) cause the Corresponding Source to be so
-+available, or (2) arrange to deprive yourself of the benefit of the
-+patent license for this particular work, or (3) arrange, in a manner
-+consistent with the requirements of this License, to extend the patent
-+license to downstream recipients. "Knowingly relying" means you have
-+actual knowledge that, but for the patent license, your conveying the
-+covered work in a country, or your recipient's use of the covered work
-+in a country, would infringe one or more identifiable patents in that
-+country that you have reason to believe are valid.
-+
-+ If, pursuant to or in connection with a single transaction or
-+arrangement, you convey, or propagate by procuring conveyance of, a
-+covered work, and grant a patent license to some of the parties
-+receiving the covered work authorizing them to use, propagate, modify
-+or convey a specific copy of the covered work, then the patent license
-+you grant is automatically extended to all recipients of the covered
-+work and works based on it.
-+
-+ A patent license is "discriminatory" if it does not include within
-+the scope of its coverage, prohibits the exercise of, or is
-+conditioned on the non-exercise of one or more of the rights that are
-+specifically granted under this License. You may not convey a covered
-+work if you are a party to an arrangement with a third party that is
-+in the business of distributing software, under which you make payment
-+to the third party based on the extent of your activity of conveying
-+the work, and under which the third party grants, to any of the
-+parties who would receive the covered work from you, a discriminatory
-+patent license (a) in connection with copies of the covered work
-+conveyed by you (or copies made from those copies), or (b) primarily
-+for and in connection with specific products or compilations that
-+contain the covered work, unless you entered into that arrangement,
-+or that patent license was granted, prior to 28 March 2007.
-+
-+ Nothing in this License shall be construed as excluding or limiting
-+any implied license or other defenses to infringement that may
-+otherwise be available to you under applicable patent law.
-+
-+ 12. No Surrender of Others' Freedom.
-+
-+ If conditions are imposed on you (whether by court order, agreement or
-+otherwise) that contradict the conditions of this License, they do not
-+excuse you from the conditions of this License. If you cannot convey a
-+covered work so as to satisfy simultaneously your obligations under this
-+License and any other pertinent obligations, then as a consequence you may
-+not convey it at all. For example, if you agree to terms that obligate you
-+to collect a royalty for further conveying from those to whom you convey
-+the Program, the only way you could satisfy both those terms and this
-+License would be to refrain entirely from conveying the Program.
-+
-+ 13. Use with the GNU Affero General Public License.
-+
-+ Notwithstanding any other provision of this License, you have
-+permission to link or combine any covered work with a work licensed
-+under version 3 of the GNU Affero General Public License into a single
-+combined work, and to convey the resulting work. The terms of this
-+License will continue to apply to the part which is the covered work,
-+but the special requirements of the GNU Affero General Public License,
-+section 13, concerning interaction through a network will apply to the
-+combination as such.
-+
-+ 14. Revised Versions of this License.
-+
-+ The Free Software Foundation may publish revised and/or new versions of
-+the GNU General Public License from time to time. Such new versions will
-+be similar in spirit to the present version, but may differ in detail to
-+address new problems or concerns.
-+
-+ Each version is given a distinguishing version number. If the
-+Program specifies that a certain numbered version of the GNU General
-+Public License "or any later version" applies to it, you have the
-+option of following the terms and conditions either of that numbered
-+version or of any later version published by the Free Software
-+Foundation. If the Program does not specify a version number of the
-+GNU General Public License, you may choose any version ever published
-+by the Free Software Foundation.
-+
-+ If the Program specifies that a proxy can decide which future
-+versions of the GNU General Public License can be used, that proxy's
-+public statement of acceptance of a version permanently authorizes you
-+to choose that version for the Program.
-+
-+ Later license versions may give you additional or different
-+permissions. However, no additional obligations are imposed on any
-+author or copyright holder as a result of your choosing to follow a
-+later version.
-+
-+ 15. Disclaimer of Warranty.
-+
-+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-+
-+ 16. Limitation of Liability.
-+
-+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-+SUCH DAMAGES.
-+
-+ 17. Interpretation of Sections 15 and 16.
-+
-+ If the disclaimer of warranty and limitation of liability provided
-+above cannot be given local legal effect according to their terms,
-+reviewing courts shall apply local law that most closely approximates
-+an absolute waiver of all civil liability in connection with the
-+Program, unless a warranty or assumption of liability accompanies a
-+copy of the Program in return for a fee.
-+
-+ END OF TERMS AND CONDITIONS
-+
-+ How to Apply These Terms to Your New Programs
-+
-+ If you develop a new program, and you want it to be of the greatest
-+possible use to the public, the best way to achieve this is to make it
-+free software which everyone can redistribute and change under these terms.
-+
-+ To do so, attach the following notices to the program. It is safest
-+to attach them to the start of each source file to most effectively
-+state the exclusion of warranty; and each file should have at least
-+the "copyright" line and a pointer to where the full notice is found.
-+
-+ <one line to give the program's name and a brief idea of what it does.>
-+ Copyright (C) <year> <name of author>
-+
-+ This program is free software: you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation, either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+Also add information on how to contact you by electronic and paper mail.
-+
-+ If the program does terminal interaction, make it output a short
-+notice like this when it starts in an interactive mode:
-+
-+ <program> Copyright (C) <year> <name of author>
-+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-+ This is free software, and you are welcome to redistribute it
-+ under certain conditions; type `show c' for details.
-+
-+The hypothetical commands `show w' and `show c' should show the appropriate
-+parts of the General Public License. Of course, your program's commands
-+might be different; for a GUI interface, you would use an "about box".
-+
-+ You should also get your employer (if you work as a programmer) or school,
-+if any, to sign a "copyright disclaimer" for the program, if necessary.
-+For more information on this, and how to apply and follow the GNU GPL, see
-+<http://www.gnu.org/licenses/>.
-+
-+ The GNU General Public License does not permit incorporating your program
-+into proprietary programs. If your program is a subroutine library, you
-+may consider it more useful to permit linking proprietary applications with
-+the library. If this is what you want to do, use the GNU Lesser General
-+Public License instead of this License. But first, please read
-+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-diff --git a/ws/dissector.lua b/ws/dissector.lua
-new file mode 100644
-index 0000000..0431c67
---- /dev/null
-+++ b/ws/dissector.lua
-@@ -0,0 +1,306 @@
-+-- Copyright (c) 2011, Robert G. Jakabosky <bobby@sharedrealm.com> All rights reserved.
-+
-+-- cache globals to local for speed.
-+local format=string.format
-+local tostring=tostring
-+local tonumber=tonumber
-+local sqrt=math.sqrt
-+local pairs=pairs
-+
-+-- wireshark API globals
-+local Pref = Pref
-+local Proto = Proto
-+local ProtoField = ProtoField
-+local DissectorTable = DissectorTable
-+local ByteArray = ByteArray
-+local PI_MALFORMED = PI_MALFORMED
-+local PI_ERROR = PI_ERROR
-+
-+-- zmq protocol example
-+-- declare our protocol
-+local zmq_proto = Proto("zmq","ZMQ","ZeroMQ Protocol")
-+
-+-- setup preferences
-+zmq_proto.prefs["tcp_port_start"] =
-+ Pref.string("TCP port range start", "5555", "First TCP port to decode as this protocol")
-+zmq_proto.prefs["tcp_port_end"] =
-+ Pref.string("TCP port range end", "5555", "Last TCP port to decode as this protocol")
-+-- current preferences settings.
-+local current_settings = {
-+tcp_port_start = -1,
-+tcp_port_end = -1,
-+}
-+
-+-- setup protocol fields.
-+zmq_proto.fields = {}
-+local fds = zmq_proto.fields
-+fds.frame = ProtoField.new("Frame", "zmq.frame", "FT_BYTES", nil, "BASE_NONE")
-+fds.length = ProtoField.new("Frame Length", "zmq.frame.len", "FT_UINT64", nil, "BASE_DEC")
-+fds.length8 = ProtoField.new("Frame 8bit Length", "zmq.frame.len8", "FT_UINT8", nil, "BASE_DEC")
-+fds.length64 = ProtoField.new("Frame 64bit Length", "zmq.frame.len64", "FT_UINT64", nil, "BASE_DEC")
-+fds.flags = ProtoField.new("Frame Flags", "zmq.frame.flags", "FT_UINT8", nil, "BASE_HEX", "0xFF")
-+fds.flags_more = ProtoField.new("More", "zmq.frame.flags.more", "FT_UINT8", nil, "BASE_HEX", "0x01")
-+fds.body = ProtoField.new("Frame body", "zmq.frame.body", "FT_BYTES", nil, "BASE_NONE")
-+
-+-- un-register zmq to handle tcp port range
-+local function unregister_tcp_port_range(start_port, end_port)
-+ if not start_port or start_port <= 0 or not end_port or end_port <= 0 then
-+ return
-+ end
-+ local tcp_port_table = DissectorTable.get("tcp.port")
-+ for port = start_port,end_port do
-+ tcp_port_table:remove(port,zmq_proto)
-+ end
-+end
-+
-+-- register zmq to handle tcp port range
-+local function register_tcp_port_range(start_port, end_port)
-+ if not start_port or start_port <= 0 or not end_port or end_port <= 0 then
-+ return
-+ end
-+ local tcp_port_table = DissectorTable.get("tcp.port")
-+ for port = start_port,end_port do
-+ tcp_port_table:add(port,zmq_proto)
-+ end
-+end
-+
-+-- handle preferences changes.
-+function zmq_proto.init(arg1, arg2)
-+ local old_start, old_end
-+ local new_start, new_end
-+ -- check if preferences have changed.
-+ for pref_name,old_v in pairs(current_settings) do
-+ local new_v = zmq_proto.prefs[pref_name]
-+ if new_v ~= old_v then
-+ if pref_name == "tcp_port_start" then
-+ old_start = old_v
-+ new_start = new_v
-+ elseif pref_name == "tcp_port_end" then
-+ old_end = old_v
-+ new_end = new_v
-+ end
-+ -- save new value.
-+ current_settings[pref_name] = new_v
-+ end
-+ end
-+ -- un-register old port range
-+ if old_start and old_end then
-+ unregister_tcp_port_range(tonumber(old_start), tonumber(old_end))
-+ end
-+ -- register new port range.
-+ if new_start and new_end then
-+ register_tcp_port_range(tonumber(new_start), tonumber(new_end))
-+ end
-+end
-+
-+-- parse flag bits.
-+local BITS = {
-+ MORE = 0x01,
-+ RESERVED = 0x7E,
-+}
-+local flag_names = {"MORE"}
-+local bits_lookup = {}
-+local bits_list = {
-+ {},
-+ {MORE = true},
-+ {MORE = true, RESERVED = true},
-+ {RESERVED = true},
-+}
-+local function parse_flags(flags)
-+ return bits_lookup[flags] or bits_lookup[1]
-+end
-+
-+-- make bits object
-+local function make_bits(bits)
-+ local proxy = newproxy(true)
-+ local meta = getmetatable(proxy)
-+ meta.__index = bits
-+ meta.__tostring = function()
-+ return bits.flags
-+ end
-+ -- combind bits into string description.
-+ local flags = nil
-+ for i=1,#flag_names do
-+ local name = flag_names[i]
-+ if bits[name] then
-+ if flags then
-+ flags = flags .. ',' .. name
-+ else
-+ flags = name
-+ end
-+ end
-+ end
-+ -- combind bits into one byte value.
-+ local byte = 0x00
-+ for k,v in pairs(bits) do
-+ local bit = assert(BITS[k], "Invalid bit name.")
-+ byte = byte + BITS[k]
-+ end
-+ bits.flags = flags or ''
-+ bits.byte = byte
-+ return proxy
-+end
-+-- make bits objects in bis_lookup
-+for i=1,#bits_list do
-+ local bits = bits_list[i]
-+ bits = make_bits(bits)
-+ bits_lookup[bits.byte] = bits
-+end
-+
-+local function zmq_dissect_frame(buffer, pinfo, frame_tree, tap)
-+ local rang,offset
-+ -- Frame length
-+ offset = 0
-+ local len_off = offset
-+ local len8_rang = buffer(offset,1)
-+ local len_rang = len8_rang
-+ local frame_len = len8_rang:uint()
-+ -- 8bit length field
-+ local ti = frame_tree:add(fds.length8, len8_rang)
-+ ti:set_hidden()
-+ offset = offset + 1
-+ if frame_len == 255 then
-+ local len64_rang = buffer(offset, 8)
-+ len_rang = buffer(len_off, 9)
-+ frame_len = tonumber(tostring(len64_rang:uint64()))
-+ -- 64bit length field.
-+ local ti = frame_tree:add(fds.length64, len64_rang)
-+ ti:set_hidden()
-+ offset = offset + 8
-+ local ti = frame_tree:add(fds.length, len_rang)
-+ ti:set_text(format("Frame Length: %d", frame_length))
-+ else
-+ frame_tree:add(fds.length, len_rang)
-+ end
-+ -- Frame flags
-+ rang = buffer(offset,1)
-+ local flags = rang:uint()
-+ local flags_bits = parse_flags(flags)
-+ local flags_list = flags_bits.flags
-+ local flags_tree = frame_tree:add(fds.flags, rang)
-+ flags_tree:set_text(format('Flags: 0x%02X (%s)', flags, flags_list))
-+ flags_tree:add(fds.flags_more, rang)
-+ offset = offset + 1
-+ if flags_bits.MORE then
-+ tap.more = tap.more + 1
-+ else
-+ -- if the 'more' flag is not set then this is the last frame in a message.
-+ tap.msgs = tap.msgs + 1
-+ end
-+ -- Frame body
-+ local body_len = frame_len - 1
-+ local body = ''
-+ if body_len > 0 then
-+ tap.body_bytes = tap.body_bytes + body_len
-+ rang = buffer(offset, body_len)
-+ local ti = frame_tree:add_le(fds.body, rang)
-+ if body_len <= 4 then
-+ body = format("%08x", rang:uint())
-+ else
-+ body = tostring(rang)
-+ end
-+ ti:set_text(format("%s", body))
-+ end
-+ offset = offset + body_len
-+ -- frame summary
-+ if body_len > 0 then
-+ if flags_bits.MORE then
-+ frame_tree:set_text(format("Frame: [MORE] Body[%u]=%s", body_len, body))
-+ else
-+ frame_tree:set_text(format("Frame: Body[%u]=%s", body_len, body))
-+ end
-+ else
-+ if flags_bits.MORE then
-+ frame_tree:set_text(format("Frame: [MORE] No data"))
-+ else
-+ frame_tree:set_text(format("Frame: No data"))
-+ end
-+ end
-+end
-+
-+local DESEGMENT_ONE_MORE_SEGMENT = 0x0fffffff
-+local DESEGMENT_UNTIL_FIN = 0x0ffffffe
-+
-+-- packet dissector
-+function zmq_proto.dissector(tvb,pinfo,tree)
-+ local offset = 0
-+ local tvb_length = tvb:len()
-+ local reported_length = tvb:reported_len()
-+ local length_remaining
-+ local zmq_tree
-+ local rang
-+ local frames = 0
-+ local tap = {}
-+
-+ tap.frames = 0
-+ tap.msgs = 0
-+ tap.more = 0
-+ tap.body_bytes = 0
-+
-+ while(offset < reported_length and offset < tvb_length) do
-+ length_remaining = tvb_length - offset
-+ -- check for fixed part of PDU
-+ if length_remaining < 2 then
-+ pinfo.desegment_offset = offset
-+ pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
-+ break
-+ end
-+ -- decode frame length
-+ -- decode single byte frame length
-+ rang = tvb(offset, 1)
-+ local frame_len = rang:le_uint()
-+ local pdu_len = frame_len + 1
-+ if frame_len == 255 then
-+ -- make sure there is enough bytes
-+ if length_remaining < 10 then
-+ pinfo.desegment_offset = offset
-+ pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
-+ break
-+ end
-+ -- decode extra long frame length.
-+ rang = tvb(offset + 1, 8)
-+ frame_len = tonumber(tostring(rang:uint64()))
-+ pdu_len = frame_len + 9
-+ end
-+ -- provide hints to tcp
-+ if not pinfo.visited then
-+ local remaining_bytes = reported_length - offset
-+ if pdu_len > remaining_bytes then
-+ pinfo.want_pdu_tracking = 2
-+ pinfo.bytes_until_next_pdu = pdu_len - remaining_bytes
-+ end
-+ end
-+ -- check if we need more bytes to dissect this frame.
-+ if length_remaining < pdu_len then
-+ pinfo.desegment_offset = offset
-+ pinfo.desegment_len = (pdu_len - length_remaining)
-+ break
-+ end
-+ -- dissect zmq frame
-+ if not zmq_tree then
-+ zmq_tree = tree:add(zmq_proto,tvb(),"ZMQ frames")
-+ end
-+ rang = tvb(offset, pdu_len)
-+ local frame_tree = zmq_tree:add(fds.frame, rang)
-+ zmq_dissect_frame(rang:tvb(), pinfo, frame_tree, tap)
-+ frames = frames + 1
-+ -- step to next frame.
-+ local offset_before = offset
-+ offset = offset + pdu_len
-+ if offset < offset_before then break end
-+ end
-+ if zmq_tree then
-+ zmq_tree:set_text(format("ZMQ frames=%u", frames))
-+ end
-+ if frames > 0 then
-+ tap.frames = frames
-+ pinfo.tap_data = tap
-+ end
-+ -- Info column
-+ pinfo.cols.protocol = "ZMQ"
-+ pinfo.cols.info = format('ZMQ frames=%u',frames)
-+end
-+
-+-- register zmq to handle tcp ports 5550-5560
-+register_tcp_port_range(5550,5560)
-+
-diff --git a/ws/init.lua b/ws/init.lua
-new file mode 100644
-index 0000000..0282fba
---- /dev/null
-+++ b/ws/init.lua
-@@ -0,0 +1,16 @@
-+
-+local prequire = function(name)
-+ local status, result1 = pcall(require, name)
-+ if not status then
-+ debug("Failed to load " .. name .. ": " .. result1)
-+ end
-+ return result1
-+end
-+
-+prequire("zmq.ws.dissector")
-+
-+-- if running from wireshark, register all taps.
-+if gui_enabled() then
-+ prequire("zmq.ws.stats_tap")
-+end
-+
-diff --git a/ws/stats_tap.lua b/ws/stats_tap.lua
-new file mode 100644
-index 0000000..1d39f16
---- /dev/null
-+++ b/ws/stats_tap.lua
-@@ -0,0 +1,58 @@
-+-- Copyright (c) 2011, Robert G. Jakabosky <bobby@sharedrealm.com> All rights reserved.
-+
-+local tap = require"zmq.ws.tap"
-+
-+local format = string.format
-+
-+local stats_tap_mt = {}
-+stats_tap_mt.__index = stats_tap_mt
-+
-+function stats_tap_mt:packet(pinfo, tvb, tree, data)
-+ -- count all ZeroMQ packets
-+ self.count = self.count + 1
-+ data = data or pinfo.tap_data
-+ if not data then
-+ return
-+ end
-+ -- frames
-+ self.frames = self.frames + (data.frames or 0)
-+ -- frames with more flag set
-+ self.more = self.more + (data.more or 0)
-+ -- whole messages.
-+ self.msgs = self.msgs + (data.msgs or 0)
-+ -- total bytes in frame bodies.
-+ self.body_bytes = self.body_bytes + (data.body_bytes or 0)
-+end
-+
-+function stats_tap_mt:draw()
-+ return format([[
-+ZeroMQ Packets: %d
-+Frames: %d
-+Messages: %d
-+Flags: More: %d
-+Payload bytes: %d
-+]],
-+ self.count,
-+ self.frames,
-+ self.msgs,
-+ self.more,
-+ self.body_bytes)
-+end
-+
-+function stats_tap_mt:reset()
-+ self.count = 0
-+ self.frames = 0
-+ self.msgs = 0
-+ self.more = 0
-+ self.body_bytes = 0
-+end
-+
-+local function create_stats_tap()
-+ local tap = setmetatable({}, stats_tap_mt)
-+
-+ tap:reset() -- initialize tap.
-+ return tap, 'zmq', 'lua'
-+end
-+
-+tap("ZeroMQ stats tap", create_stats_tap)
-+
-diff --git a/ws/tap.lua b/ws/tap.lua
-new file mode 100644
-index 0000000..096332d
---- /dev/null
-+++ b/ws/tap.lua
-@@ -0,0 +1,84 @@
-+-- Copyright (c) 2011, Robert G. Jakabosky <bobby@sharedrealm.com> All rights reserved.
-+
-+local gui_enabled = gui_enabled
-+local register_menu = register_menu
-+local MENU_TOOLS_UNSORTED = MENU_TOOLS_UNSORTED
-+
-+local win_instances = 0
-+
-+local function create_window_tap(name, create)
-+ win_instances = win_instances + 1
-+
-+ local td, tap_filter, tap_type = create()
-+
-+ -- tap's output window.
-+ local win = TextWindow.new(name .. " " .. win_instances)
-+
-+ -- this tap will be local to the menu_function that called it
-+ local tap = Listener.new(tap_type, tap_filter)
-+
-+ -- callback to remove the tap when the text window closes
-+ function remove_tap()
-+ if tap and tap.remove then
-+ tap:remove()
-+ end
-+ end
-+
-+ -- make sure the tap doesn't hang around after the window was closed
-+ win:set_atclose(remove_tap)
-+
-+ -- this function will be called for every packet
-+ function tap.packet(pinfo,tvb, tree, tapdata)
-+ return td:packet(pinfo, tvb, tree, tapdata)
-+ end
-+
-+ -- this function will be called once every few seconds to redraw the window
-+ function tap.draw()
-+ local text = td:draw()
-+ win:set(text)
-+ end
-+
-+ -- this function will be called at the end of the capture run.
-+ function tap.reset()
-+ return td:reset()
-+ end
-+end
-+
-+local function create_tshark_tap(name, create)
-+
-+ local td, tap_filter, tap_type = create()
-+
-+ -- this tap will be local to the menu_function that called it
-+ local tap = Listener.new(tap_type, tap_filter)
-+
-+ -- this function will be called for every packet
-+ function tap.packet(pinfo,tvb,tapdata)
-+ return td:packet(pinfo, tvb, tapdata)
-+ end
-+
-+ -- this function will be called once every few seconds to redraw the window
-+ function tap.draw()
-+ local text = td:draw()
-+ debug(name .. " results:\n" .. text)
-+ end
-+
-+ -- this function will be called at the end of the capture run.
-+ function tap.reset()
-+ return td:reset()
-+ end
-+end
-+
-+return function (name, create)
-+ if gui_enabled() then
-+ -- menu callback.
-+ local create_tap = function()
-+ create_window_tap(name, create)
-+ end
-+ -- register menu item if running from wireshark
-+ register_menu(name, create_tap, MENU_TOOLS_UNSORTED)
-+ else
-+ -- we are running from tshark, create a non-gui tap now.
-+ create_tshark_tap(name, create)
-+ end
-+end
-+
-diff --git a/zmq.nobj.lua b/zmq.nobj.lua
-index 83c0aa5..3be6e76 100644
---- a/zmq.nobj.lua
-+++ b/zmq.nobj.lua
-@@ -23,110 +23,157 @@ set_variable_format "%s%d"
-
- c_module "zmq" {
- -- module settings.
-+module_globals = true, -- support old code that doesn't do: local zmq = require"zmq"
- use_globals = false,
- hide_meta_info = true,
- luajit_ffi = true,
--
--sys_include "string.h",
--include "zmq.h",
-+-- needed for functions exported from module.
-+luajit_ffi_load_cmodule = true,
-
- ffi_load {
- "zmq", -- default lib name.
- Windows = "libzmq", -- lib name for on windows.
- },
-
--c_source[[
--/*
-- * This wrapper function is to make the EAGAIN/ETERM error messages more like
-- * what is returned by LuaSocket.
-- */
--static const char *get_zmq_strerror() {
-- int err = zmq_errno();
-- switch(err) {
-- case EAGAIN:
-- return "timeout";
-- break;
--#if defined(ETERM)
-- case ETERM:
-- return "closed";
-- break;
-+sys_include "string.h",
-+include "zmq.h",
-+
-+c_source "typedefs" [[
-+/* detect zmq version */
-+#define VERSION_2_0 1
-+#define VERSION_2_1 0
-+#define VERSION_2_2 0
-+#define VERSION_3_0 0
-+#if defined(ZMQ_VERSION_MAJOR)
-+# if (ZMQ_VERSION_MAJOR == 2) && (ZMQ_VERSION_MINOR == 2)
-+# undef VERSION_2_2
-+# define VERSION_2_2 1
-+# undef VERSION_2_1
-+# define VERSION_2_1 1
-+# endif
-+# if (ZMQ_VERSION_MAJOR == 2) && (ZMQ_VERSION_MINOR == 1)
-+# undef VERSION_2_1
-+# define VERSION_2_1 1
-+# endif
-+# if (ZMQ_VERSION_MAJOR == 3)
-+# undef VERSION_2_0
-+# define VERSION_2_0 0
-+# undef VERSION_3_0
-+# define VERSION_3_0 1
-+# endif
- #endif
-- default:
-- break;
-- }
-- return zmq_strerror(err);
--}
-
--]],
-+/* make sure ZMQ_DONTWAIT & ZMQ_NOBLOCK are both defined. */
-+#ifndef ZMQ_DONTWAIT
-+# define ZMQ_DONTWAIT ZMQ_NOBLOCK
-+#endif
-+#ifndef ZMQ_NOBLOCK
-+# define ZMQ_NOBLOCK ZMQ_DONTWAIT
-+#endif
-
---- export helper function 'get_zmq_strerror' to FFI code.
--ffi_export_function "const char *" "get_zmq_strerror" "()",
--ffi_source[[
--local C_get_zmq_strerror = get_zmq_strerror
---- make nicer wrapper for exported error function.
--local function get_zmq_strerror()
-- return ffi.string(C_get_zmq_strerror())
--end
-+/* make sure DEALER/ROUTER & XREQ/XREP are all defined. */
-+#ifndef ZMQ_DEALER
-+# define ZMQ_DEALER ZMQ_XREQ
-+#endif
-+#ifndef ZMQ_ROUTER
-+# define ZMQ_ROUTER ZMQ_XREP
-+#endif
-+#ifndef ZMQ_XREQ
-+# define ZMQ_XREQ ZMQ_DEALER
-+#endif
-+#ifndef ZMQ_XREP
-+# define ZMQ_XREP ZMQ_ROUTER
-+#endif
-+
-+#if VERSION_2_0
-+# define ZMQ_POLL_MSEC 1000 // zmq_poll is usec
-+#elif VERSION_3_0
-+# define ZMQ_POLL_MSEC 1 // zmq_poll is msec
-+# ifndef ZMQ_HWM
-+# define ZMQ_HWM 1 // backwards compatibility
-+# endif
-+#endif
- ]],
-
- --
- -- Module constants
- --
--constants {
--MAX_VSM_SIZE = 30,
-+export_definitions {
-+MAX_VSM_SIZE = "ZMQ_MAX_VSM_SIZE",
-
- -- message types
--DELIMITER = 31,
--VSM = 32,
-+DELIMITER = "ZMQ_DELIMITER",
-+VSM = "ZMQ_VSM",
-
- -- message flags
--MSG_MORE = 1,
--MSG_SHARED = 128,
-+MSG_MORE = "ZMQ_MSG_MORE",
-+MSG_SHARED = "ZMQ_MSG_SHARED",
-
- -- socket types
--PAIR = 0,
--PUB = 1,
--SUB = 2,
--REQ = 3,
--REP = 4,
--XREQ = 5,
--XREP = 6,
--PULL = 7,
--PUSH = 8,
-+PAIR = "ZMQ_PAIR",
-+PUB = "ZMQ_PUB",
-+SUB = "ZMQ_SUB",
-+REQ = "ZMQ_REQ",
-+REP = "ZMQ_REP",
-+PULL = "ZMQ_PULL",
-+PUSH = "ZMQ_PUSH",
-+
-+DEALER = "ZMQ_DEALER",
-+ROUTER = "ZMQ_ROUTER",
-+XREQ = "ZMQ_XREQ",
-+XREP = "ZMQ_XREP",
-+
-+-- new 3.1 socket types
-+XPUB = "ZMQ_XPUB",
-+XSUB = "ZMQ_XSUB",
-
- -- socket options
--HWM = 1,
--SWAP = 3,
--AFFINITY = 4,
--IDENTITY = 5,
--SUBSCRIBE = 6,
--UNSUBSCRIBE = 7,
--RATE = 8,
--RECOVERY_IVL = 9,
--MCAST_LOOP = 10,
--SNDBUF = 11,
--RCVBUF = 12,
--RCVMORE = 13,
--FD = 14,
--EVENTS = 15,
--TYPE = 16,
--LINGER = 17,
--RECONNECT_IVL = 18,
--BACKLOG = 19,
-+HWM = "ZMQ_HWM",
-+SWAP = "ZMQ_SWAP",
-+AFFINITY = "ZMQ_AFFINITY",
-+IDENTITY = "ZMQ_IDENTITY",
-+SUBSCRIBE = "ZMQ_SUBSCRIBE",
-+UNSUBSCRIBE = "ZMQ_UNSUBSCRIBE",
-+RATE = "ZMQ_RATE",
-+RECOVERY_IVL = "ZMQ_RECOVERY_IVL",
-+MCAST_LOOP = "ZMQ_MCAST_LOOP",
-+SNDBUF = "ZMQ_SNDBUF",
-+RCVBUF = "ZMQ_RCVBUF",
-+RCVMORE = "ZMQ_RCVMORE",
-+FD = "ZMQ_FD",
-+EVENTS = "ZMQ_EVENTS",
-+TYPE = "ZMQ_TYPE",
-+LINGER = "ZMQ_LINGER",
-+RECONNECT_IVL = "ZMQ_RECONNECT_IVL",
-+RECONNECT_IVL_MSEC= "ZMQ_RECONNECT_IVL_MSEC",
-+BACKLOG = "ZMQ_BACKLOG",
-+RECONNECT_IVL_MAX = "ZMQ_RECONNECT_IVL_MAX",
-+MAXMSGSIZE = "ZMQ_MAXMSGSIZE",
-+SNDHWM = "ZMQ_SNDHWM",
-+RCVHWM = "ZMQ_RCVHWM",
-+MULTICAST_HOPS = "ZMQ_MULTICAST_HOPS",
-+RCVTIMEO = "ZMQ_RCVTIMEO",
-+SNDTIMEO = "ZMQ_SNDTIMEO",
-+RCVLABEL = "ZMQ_RCVLABEL",
-
- -- send/recv flags
--NOBLOCK = 1,
--SNDMORE = 2,
-+NOBLOCK = "ZMQ_NOBLOCK",
-+DONTWAIT = "ZMQ_DONTWAIT",
-+SNDMORE = "ZMQ_SNDMORE",
-+SNDLABEL = "ZMQ_SNDLABEL",
-
- -- poll events
--POLLIN = 1,
--POLLOUT = 2,
--POLLERR = 4,
-+POLLIN = "ZMQ_POLLIN",
-+POLLOUT = "ZMQ_POLLOUT",
-+POLLERR = "ZMQ_POLLERR",
-+
-+-- poll milliseconds.
-+POLL_MSEC = "ZMQ_POLL_MSEC",
-
- -- devices
--STREAMER = 1,
--FORWARDER = 2,
--QUEUE = 3,
-+STREAMER = "ZMQ_STREAMER",
-+FORWARDER = "ZMQ_FORWARDER",
-+QUEUE = "ZMQ_QUEUE",
- },
-
-
-@@ -159,6 +206,7 @@ c_function "version" {
- ]],
- },
- c_function "init" {
-+ var_in{ "int", "io_threads?", default = "1" },
- c_call "!ZMQ_Ctx *" "zmq_init" { "int", "io_threads" },
- },
- c_function "init_ctx" {
-@@ -174,15 +222,15 @@ c_function "init_ctx" {
- ffi_source[[
- local p_type = type(${ptr})
- if p_type == 'userdata' then
-- ${ctx} = ffi.cast('void *', ${ptr});
-- elseif p_type == 'cdata' then
-- ${ctx} = ${ptr};
-+ ${ctx} = ffi.cast('ZMQ_Ctx *', ${ptr});
-+ elseif p_type == 'cdata' and ffi.istype('void *', ${ptr}) then
-+ ${ctx} = ffi.cast('ZMQ_Ctx *', ${ptr});
- else
- return error("expected lightuserdata/cdata<void *>");
- end
- ]],
- },
--c_function "device" {
-+c_function "device" { if_defs = "VERSION_2_0",
- c_call "ZMQ_Error" "zmq_device"
- { "int", "device", "ZMQ_Socket *", "insock", "ZMQ_Socket *", "outsock" },
- },
-@@ -197,16 +245,5 @@ c_function "stopwatch_start" {
- c_function "sleep" {
- c_call "void" "zmq_sleep" { "int", "seconds_" },
- },
----
---- This dump function is for getting a copy of the FFI-based bindings code and is
---- only for debugging.
----
--c_function "dump_ffi" {
-- var_out{ "const char *", "ffi_code", has_length = true, },
-- c_source[[
-- ${ffi_code} = ${module_c_name}_ffi_lua_code;
-- ${ffi_code_len} = sizeof(${module_c_name}_ffi_lua_code) - 1;
--]],
--},
- }
-