# Path: src/zugbruecke/core/lib.py
# def get_hash_of_string(str_in):
# 
# 	return hashlib.sha256(str_in.encode('utf-8')).hexdigest()
# 
# Path: src/zugbruecke/core/routine_server.py
# class routine_server_class():
# 
# 
# 	def __init__(self, parent_dll, routine_name, routine_handler):
# 
# 		# Store handle on parent dll
# 		self.dll = parent_dll
# 
# 		# Store pointer to zugbruecke session
# 		self.session = self.dll.session
# 
# 		# Get handle on log
# 		self.log = self.dll.log
# 
# 		# Store my own name
# 		self.name = routine_name
# 
# 		# Required by arg definitions and contents
# 		self.data = self.session.data
# 
# 		# Set routine handler
# 		self.handler = routine_handler
# 
# 
# 	def __call__(self, arg_message_list, arg_memory_list):
# 		"""
# 		TODO: Optimize for speed!
# 		"""
# 
# 		# Log status
# 		self.log.out('[routine-server] Trying call routine "%s" ...' % self.name)
# 
# 		try:
# 
# 			# Unpack passed arguments, handle pointers and structs ...
# 			args_list = self.data.arg_list_unpack(arg_message_list, self.argtypes_d)
# 
# 			# Unpack pointer data
# 			self.data.server_unpack_memory_list(args_list, arg_memory_list, self.memsync_d)
# 
# 			# Default return value
# 			return_value = None
# 
# 		except Exception as e:
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 		try:
# 
# 			# Call into dll
# 			return_value = self.handler(*tuple(args_list))
# 
# 		except Exception as e:
# 
# 			# Log status
# 			self.log.out('[routine-server] ... call failed!')
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			# Pack return package and return it
# 			return {
# 				'args': arg_message_list,
# 				'return_value': return_value,
# 				'memory': arg_memory_list,
# 				'success': False,
# 				'exception': e
# 				}
# 
# 		try:
# 
# 			# Pack memory for return
# 			self.data.server_pack_memory_list(args_list, return_value, arg_memory_list, self.memsync_d)
# 
# 			# Get new arg message list
# 			arg_message_list = self.data.arg_list_pack(args_list, self.argtypes_d)
# 
# 			# Get new return message list
# 			return_message = self.data.return_msg_pack(return_value, self.restype_d)
# 
# 			# Log status
# 			self.log.out('[routine-server] ... done.')
# 
# 			# Pack return package and return it
# 			return {
# 				'args': arg_message_list,
# 				'return_value': return_message,
# 				'memory': arg_memory_list,
# 				'success': True,
# 				'exception': None
# 				}
# 
# 		except Exception as e:
# 
# 			# Log status
# 			self.log.out('[routine-server] ... packing call failed!')
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 
# 	def __configure__(self, argtypes_d, restype_d, memsync_d):
# 
# 		# Store argtype definition dict
# 		self.argtypes_d = argtypes_d
# 
# 		# Store return value definition dict
# 		self.restype_d = restype_d
# 
# 		# Store memory sync instructions
# 		self.memsync_d = self.data.unpack_definition_memsync(memsync_d)
# 
# 		try:
# 
# 			# Parse and apply argtype definition dict to actual ctypes routine
# 			_argtypes = self.data.unpack_definition_argtypes(argtypes_d)
# 			# Only configure if there are definitions, otherwise calls with int parameters without definition fail
# 			if len(_argtypes) > 0:
# 				self.handler.argtypes = _argtypes
# 
# 			# Parse and apply restype definition dict to actual ctypes routine
# 			self.handler.restype = self.data.unpack_definition_returntype(restype_d)
# 
# 		except Exception as e:
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 		# Log status
# 		self.log.out(' memsync: \n%s' % pf(self.memsync_d))
# 		self.log.out(' argtypes: \n%s' % pf(self.handler.argtypes))
# 		self.log.out(' argtypes_d: \n%s' % pf(self.argtypes_d))
# 		self.log.out(' restype: \n%s' % pf(self.handler.restype))
# 		self.log.out(' restype_d: \n%s' % pf(self.restype_d))


import traceback
from .lib import get_hash_of_string
from .routine_server import routine_server_class




# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# DLL SERVER CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class dll_server_class(): # Representing one idividual dll to be called into


	def __init__(self, parent_session, dll_name, dll_type, handler):

		# Store dll parameters name, path and type
		self.name = dll_name
		self.calling_convention = dll_type

		# Store pointer to _server_ session
		self.session = parent_session

		# Get handle on log
		self.log = self.session.log

		# Store handler on dll
		self.handler = handler

		# Start dict for dll routines
		self.routines = {}

		# Hash my own path as unique ID

# Path: src/zugbruecke/core/lib.py
# def get_hash_of_string(str_in):
# 
# 	return hashlib.sha256(str_in.encode('utf-8')).hexdigest()
# 
# Path: src/zugbruecke/core/routine_server.py
# class routine_server_class():
# 
# 
# 	def __init__(self, parent_dll, routine_name, routine_handler):
# 
# 		# Store handle on parent dll
# 		self.dll = parent_dll
# 
# 		# Store pointer to zugbruecke session
# 		self.session = self.dll.session
# 
# 		# Get handle on log
# 		self.log = self.dll.log
# 
# 		# Store my own name
# 		self.name = routine_name
# 
# 		# Required by arg definitions and contents
# 		self.data = self.session.data
# 
# 		# Set routine handler
# 		self.handler = routine_handler
# 
# 
# 	def __call__(self, arg_message_list, arg_memory_list):
# 		"""
# 		TODO: Optimize for speed!
# 		"""
# 
# 		# Log status
# 		self.log.out('[routine-server] Trying call routine "%s" ...' % self.name)
# 
# 		try:
# 
# 			# Unpack passed arguments, handle pointers and structs ...
# 			args_list = self.data.arg_list_unpack(arg_message_list, self.argtypes_d)
# 
# 			# Unpack pointer data
# 			self.data.server_unpack_memory_list(args_list, arg_memory_list, self.memsync_d)
# 
# 			# Default return value
# 			return_value = None
# 
# 		except Exception as e:
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 		try:
# 
# 			# Call into dll
# 			return_value = self.handler(*tuple(args_list))
# 
# 		except Exception as e:
# 
# 			# Log status
# 			self.log.out('[routine-server] ... call failed!')
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			# Pack return package and return it
# 			return {
# 				'args': arg_message_list,
# 				'return_value': return_value,
# 				'memory': arg_memory_list,
# 				'success': False,
# 				'exception': e
# 				}
# 
# 		try:
# 
# 			# Pack memory for return
# 			self.data.server_pack_memory_list(args_list, return_value, arg_memory_list, self.memsync_d)
# 
# 			# Get new arg message list
# 			arg_message_list = self.data.arg_list_pack(args_list, self.argtypes_d)
# 
# 			# Get new return message list
# 			return_message = self.data.return_msg_pack(return_value, self.restype_d)
# 
# 			# Log status
# 			self.log.out('[routine-server] ... done.')
# 
# 			# Pack return package and return it
# 			return {
# 				'args': arg_message_list,
# 				'return_value': return_message,
# 				'memory': arg_memory_list,
# 				'success': True,
# 				'exception': None
# 				}
# 
# 		except Exception as e:
# 
# 			# Log status
# 			self.log.out('[routine-server] ... packing call failed!')
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 
# 	def __configure__(self, argtypes_d, restype_d, memsync_d):
# 
# 		# Store argtype definition dict
# 		self.argtypes_d = argtypes_d
# 
# 		# Store return value definition dict
# 		self.restype_d = restype_d
# 
# 		# Store memory sync instructions
# 		self.memsync_d = self.data.unpack_definition_memsync(memsync_d)
# 
# 		try:
# 
# 			# Parse and apply argtype definition dict to actual ctypes routine
# 			_argtypes = self.data.unpack_definition_argtypes(argtypes_d)
# 			# Only configure if there are definitions, otherwise calls with int parameters without definition fail
# 			if len(_argtypes) > 0:
# 				self.handler.argtypes = _argtypes
# 
# 			# Parse and apply restype definition dict to actual ctypes routine
# 			self.handler.restype = self.data.unpack_definition_returntype(restype_d)
# 
# 		except Exception as e:
# 
# 			# Push traceback to log
# 			self.log.err(traceback.format_exc())
# 
# 			raise e
# 
# 		# Log status
# 		self.log.out(' memsync: \n%s' % pf(self.memsync_d))
# 		self.log.out(' argtypes: \n%s' % pf(self.handler.argtypes))
# 		self.log.out(' argtypes_d: \n%s' % pf(self.argtypes_d))
# 		self.log.out(' restype: \n%s' % pf(self.handler.restype))
# 		self.log.out(' restype_d: \n%s' % pf(self.restype_d))


# Path: src/zugbruecke/core/dll_server.py
import traceback
from .lib import get_hash_of_string
from .routine_server import routine_server_class





# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# DLL SERVER CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class dll_server_class(): # Representing one idividual dll to be called into


	def __init__(self, parent_session, dll_name, dll_type, handler):

		# Store dll parameters name, path and type
		self.name = dll_name
		self.calling_convention = dll_type

		# Store pointer to _server_ session
		self.session = parent_session

		# Get handle on log
		self.log = self.session.log

		# Store handler on dll
		self.handler = handler

		# Start dict for dll routines
		self.routines = {}

		# Hash my own path as unique ID

		self.hash_id = get_hash_of_string(self.name)