summaryrefslogtreecommitdiffstats
path: root/src/console/zmq/backend/cffi/_cffi.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/console/zmq/backend/cffi/_cffi.py')
-rwxr-xr-xsrc/console/zmq/backend/cffi/_cffi.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/console/zmq/backend/cffi/_cffi.py b/src/console/zmq/backend/cffi/_cffi.py
new file mode 100755
index 00000000..c73ebf83
--- /dev/null
+++ b/src/console/zmq/backend/cffi/_cffi.py
@@ -0,0 +1,127 @@
+# coding: utf-8
+"""The main CFFI wrapping of libzmq"""
+
+# Copyright (C) PyZMQ Developers
+# Distributed under the terms of the Modified BSD License.
+
+
+import json
+import os
+from os.path import dirname, join
+from cffi import FFI
+
+from zmq.utils.constant_names import all_names, no_prefix
+
+
+base_zmq_version = (3,2,2)
+
+def load_compiler_config():
+ """load pyzmq compiler arguments"""
+ import zmq
+ zmq_dir = dirname(zmq.__file__)
+ zmq_parent = dirname(zmq_dir)
+
+ fname = join(zmq_dir, 'utils', 'compiler.json')
+ if os.path.exists(fname):
+ with open(fname) as f:
+ cfg = json.load(f)
+ else:
+ cfg = {}
+
+ cfg.setdefault("include_dirs", [])
+ cfg.setdefault("library_dirs", [])
+ cfg.setdefault("runtime_library_dirs", [])
+ cfg.setdefault("libraries", ["zmq"])
+
+ # cast to str, because cffi can't handle unicode paths (?!)
+ cfg['libraries'] = [str(lib) for lib in cfg['libraries']]
+ for key in ("include_dirs", "library_dirs", "runtime_library_dirs"):
+ # interpret paths relative to parent of zmq (like source tree)
+ abs_paths = []
+ for p in cfg[key]:
+ if p.startswith('zmq'):
+ p = join(zmq_parent, p)
+ abs_paths.append(str(p))
+ cfg[key] = abs_paths
+ return cfg
+
+
+def zmq_version_info():
+ """Get libzmq version as tuple of ints"""
+ major = ffi.new('int*')
+ minor = ffi.new('int*')
+ patch = ffi.new('int*')
+
+ C.zmq_version(major, minor, patch)
+
+ return (int(major[0]), int(minor[0]), int(patch[0]))
+
+
+cfg = load_compiler_config()
+ffi = FFI()
+
+def _make_defines(names):
+ _names = []
+ for name in names:
+ define_line = "#define %s ..." % (name)
+ _names.append(define_line)
+
+ return "\n".join(_names)
+
+c_constant_names = []
+for name in all_names:
+ if no_prefix(name):
+ c_constant_names.append(name)
+ else:
+ c_constant_names.append("ZMQ_" + name)
+
+# load ffi definitions
+here = os.path.dirname(__file__)
+with open(os.path.join(here, '_cdefs.h')) as f:
+ _cdefs = f.read()
+
+with open(os.path.join(here, '_verify.c')) as f:
+ _verify = f.read()
+
+ffi.cdef(_cdefs)
+ffi.cdef(_make_defines(c_constant_names))
+
+try:
+ C = ffi.verify(_verify,
+ modulename='_cffi_ext',
+ libraries=cfg['libraries'],
+ include_dirs=cfg['include_dirs'],
+ library_dirs=cfg['library_dirs'],
+ runtime_library_dirs=cfg['runtime_library_dirs'],
+ )
+ _version_info = zmq_version_info()
+except Exception as e:
+ raise ImportError("PyZMQ CFFI backend couldn't find zeromq: %s\n"
+ "Please check that you have zeromq headers and libraries." % e)
+
+if _version_info < (3,2,2):
+ raise ImportError("PyZMQ CFFI backend requires zeromq >= 3.2.2,"
+ " but found %i.%i.%i" % _version_info
+ )
+
+nsp = new_sizet_pointer = lambda length: ffi.new('size_t*', length)
+
+new_uint64_pointer = lambda: (ffi.new('uint64_t*'),
+ nsp(ffi.sizeof('uint64_t')))
+new_int64_pointer = lambda: (ffi.new('int64_t*'),
+ nsp(ffi.sizeof('int64_t')))
+new_int_pointer = lambda: (ffi.new('int*'),
+ nsp(ffi.sizeof('int')))
+new_binary_data = lambda length: (ffi.new('char[%d]' % (length)),
+ nsp(ffi.sizeof('char') * length))
+
+value_uint64_pointer = lambda val : (ffi.new('uint64_t*', val),
+ ffi.sizeof('uint64_t'))
+value_int64_pointer = lambda val: (ffi.new('int64_t*', val),
+ ffi.sizeof('int64_t'))
+value_int_pointer = lambda val: (ffi.new('int*', val),
+ ffi.sizeof('int'))
+value_binary_data = lambda val, length: (ffi.new('char[%d]' % (length + 1), val),
+ ffi.sizeof('char') * length)
+
+IPC_PATH_MAX_LEN = C.get_ipc_path_max_len()