summaryrefslogtreecommitdiffstats
path: root/python/libknot/__init__.py.in
diff options
context:
space:
mode:
Diffstat (limited to 'python/libknot/__init__.py.in')
-rw-r--r--python/libknot/__init__.py.in95
1 files changed, 95 insertions, 0 deletions
diff --git a/python/libknot/__init__.py.in b/python/libknot/__init__.py.in
new file mode 100644
index 0000000..554cbe6
--- /dev/null
+++ b/python/libknot/__init__.py.in
@@ -0,0 +1,95 @@
+"""Python libknot interface."""
+
+import ctypes
+import sys
+
+
+class KnotLookup(ctypes.Structure):
+ """Libknot lookup return structure."""
+
+ _fields_ = [('id', ctypes.c_int), ('name', ctypes.c_char_p)]
+
+
+class KnotRdataDescriptor(ctypes.Structure):
+ """Rdata descriptor structure."""
+
+ _fields_ = [('block_types', ctypes.c_int * 8), ('name', ctypes.c_char_p)]
+
+
+class Knot(object):
+ """Basic libknot interface."""
+
+ LIBKNOT = None
+ LIBKNOT_VERSION = "@libknot_SOVERSION@"
+
+ RCODE_NAMES = None
+
+ STRERROR = None
+ RDATA_DESC = None
+
+ @classmethod
+ def __init__(cls, path: str = None) -> None:
+ """Loads shared libknot library.
+ An explicit library path can be specified.
+ """
+
+ if cls.LIBKNOT:
+ return
+
+ if path is None:
+ version = ""
+ try:
+ version = ".%u" % int(cls.LIBKNOT_VERSION)
+ except Exception:
+ pass
+
+ if sys.platform == "darwin":
+ path = "libknot%s.dylib" % version
+ else:
+ path = "libknot.so%s" % version
+
+ cls.LIBKNOT = ctypes.cdll.LoadLibrary(path)
+
+ cls.RCODE_NAMES = (KnotLookup * 32).in_dll(cls.LIBKNOT, "knot_rcode_names")
+
+ cls.STRERROR = cls.LIBKNOT.knot_strerror
+ cls.STRERROR.restype = ctypes.c_char_p
+ cls.STRERROR.argtypes = [ctypes.c_int]
+
+ cls.RDATA_DESC = cls.LIBKNOT.knot_get_rdata_descriptor
+ cls.RDATA_DESC.restype = ctypes.POINTER(KnotRdataDescriptor)
+ cls.RDATA_DESC.argtypes = [ctypes.c_ushort]
+
+ @classmethod
+ def rclass_str(cls, rclass: int) -> str:
+ """Returns RRCLASS in text form."""
+
+ if (rclass == 1):
+ return "IN"
+ elif (rclass == 3):
+ return "CH"
+ elif (rclass == 254):
+ return "NONE"
+ elif (rclass == 255):
+ return "ANY"
+ else:
+ return "CLASS%i" % rclass
+
+ @classmethod
+ def rtype_str(cls, rtype: int) -> str:
+ """Returns RRTYPE in text form."""
+
+ descr = cls.RDATA_DESC(rtype).contents.name
+ if descr:
+ return descr.decode()
+ else:
+ return "TYPE%i" % rtype
+
+ @classmethod
+ def rcode_str(cls, rcode: int) -> str:
+ """Returns RCODE in text form."""
+
+ for item in cls.RCODE_NAMES:
+ if item.name and item.id == rcode:
+ return item.name.decode()
+ return "RCODE%i" % rcode