# ==================================================================================
import ctypes
import json
+from contextlib import contextmanager
# Subpackage that creates and publishes a reference to the C shared library.
# Intended to be private; RMR-python and xapp-frame-py users should not need this.
rmr_c_lib = ctypes.CDLL("librmr_si.so", mode=ctypes.RTLD_GLOBAL)
_rmr_get_consts = rmr_c_lib.rmr_get_consts
_rmr_get_consts.argtypes = []
-_rmr_get_consts.restype = ctypes.c_char_p
+_rmr_get_consts.restype = ctypes.POINTER(ctypes.c_char)
+
+_rmr_free_consts = rmr_c_lib.rmr_free_consts
+_rmr_free_consts.argtypes = [ctypes.POINTER(ctypes.c_char)]
+_rmr_free_consts.restype = None
+
+
+@contextmanager
+def _rmr_get_consts_decorator():
+ ptr = _rmr_get_consts()
+ try:
+ yield ptr
+ finally:
+ _rmr_free_consts(ptr)
def get_constants(cache={}):
if cache:
return cache
- js = _rmr_get_consts() # read json string
- cache = json.loads(str(js.decode())) # create constants value object as a hash
+ # read pointer to json data
+ with _rmr_get_consts_decorator() as ptr:
+ js = ctypes.cast(ptr, ctypes.c_char_p).value # cast it to python string
+ cache = json.loads(str(js.decode())) # create constants value object as a hash
+
return cache
def state_to_status(stateno):
"""
- Converts a msg state integer to a status string.
+ Converts a msg state integer to a status string and caches for subsequent calls.
Returns "UNKNOWN STATE" if the int value is not known.
"""
- sdict = get_mapping_dict()
- return sdict.get(stateno, "UNKNOWN STATE")
+ try:
+ return state_to_status.sdict.get(stateno, "UNKNOWN STATE")
+ except AttributeError: # sdict does not exist on first call
+ state_to_status.sdict = get_mapping_dict()
+
+ return state_to_status.sdict.get(stateno, "UNKNOWN STATE")