Documentation update

This commit is contained in:
Dirk Alders 2021-01-01 20:16:12 +01:00
parent b1a3f75e61
commit eff44b7988
91 changed files with 21130 additions and 251 deletions

View File

@ -15,12 +15,15 @@ socket_protocol (Socket Protocol)
**Submodules:**
* :class:`socket_protocol.struct_json_protocol`
* :class:`socket_protocol.pure_json_protocol`
* :class:`socket_protocol.struct_json_protocol`
**Unittest:**
See also the :download:`unittest <../../socket_protocol/_testresults_/unittest.pdf>` documentation.
See also the :download:`unittest <../pylibs/socket_protocol/_testresults_/unittest.pdf>` documentation.
**Module Documentation:**
"""
__DEPENDENCIES__ = ['stringtools']
@ -43,14 +46,14 @@ except ImportError:
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
__DESCRIPTION__ = """The Module {\\tt %s} is designed to pack and unpack data for serial transportation.
__DESCRIPTION__ = """The Module {\\tt %s} is designed for point to point communication for client-server issues.
For more Information read the sphinx documentation.""" % __name__.replace('_', '\_')
"""The Module Description"""
__INTERPRETER__ = (2, 3)
"""The Tested Interpreter-Versions"""
class callback_storage(dict):
class _callback_storage(dict):
DEFAULT_CHANNEL_NAME = 'all_others'
def __init__(self, channel_name):
@ -95,6 +98,19 @@ class callback_storage(dict):
class data_storage(dict):
"""
:param status: The message status.
:type status: int
:param service_id: The Service-ID.
:type service_id: int
:param data_id: The Data-ID.
:type data_id: int
:param data: The transfered data.
:type data: any
This is a storage object for socket_protocol messages.
"""
KEY_STATUS = 'status'
KEY_SERVICE_ID = 'service_id'
KEY_DATA_ID = 'data_id'
@ -104,69 +120,108 @@ class data_storage(dict):
dict.__init__(self, *args, **kwargs)
def get_status(self, default=None):
"""
:param default: The default value, if no data is available.
This Method returns the message status.
"""
return self.get(self.KEY_STATUS, default)
def get_service_id(self, default=None):
"""
:param default: The default value, if no data is available.
This Method returns the message Service-ID.
"""
return self.get(self.KEY_SERVICE_ID, default)
def get_data_id(self, default=None):
"""
:param default: The default value, if no data is available.
This Method returns the message Data-ID.
"""
return self.get(self.KEY_DATA_ID, default)
def get_data(self, default=None):
"""
:param default: The default value, if no data is available.
This Method returns the message data.
"""
return self.get(self.KEY_DATA, default)
class struct_json_protocol(object):
class pure_json_protocol(object):
"""
:param comm_instance: a communication instance supportin at least these functions: :func:`register_callback`, :func:`register_disconnect_callback`, :func:`send`.
:param comm_instance: A communication instance.
:type comm_instance: instance
:param secret: A secret (e.g. created by ``binascii.hexlify(os.urandom(24))``).
:param secret: An optinal secret (e.g. created by ``binascii.hexlify(os.urandom(24))``).
:type secret: str
:param auto_auth: An optional parameter (True) to enable automatic authentification, otherwise you need to do it manually, if needed.
:type auto_auth: bool
:param channel_name: An optional parameter to set a channel name for logging of the communication.
:type channel_name: str
This communication protocol supports to transfer a Service-ID, Data-ID and Data. The transmitted data is shorter than :class:`pure_json_protocol`.
.. hint:: This `class` supports to transfer a Service-ID, Data-ID and Data.
.. note::
This class is here for compatibility reasons. Usage of :class:`pure_json_protocol` is recommended.
* The Service-ID is designed to identify the type of the communication (e.g. READ_REQUEST, WRITE_REQUEST, READ_RESPONSE, WRITE_RESPONSE, ...)
* The Data-ID is designed to identify the requests / responses using the same Service_ID.
**Example:**
.. note:: The :class:`comm_instance` needs to have at least the following interface:
Server:
* A Method :func:`comm_instance.init_channel_name` to set the channel name if needed.
* A Constant :const:`comm_instance.IS_CLIENT` to identify that the :class:`comm_instance` is a client (True) or a server (False).
* A Method :func:`comm_instance.is_connected` to identify if the instance is connected (True) or not (False).
* A Method :func:`comm_instance.reconnect` to initiate a reconnect.
* A Method :func:`comm_instance.register_callback` to register a data available callback.
* A Method :func:`comm_instance.register_connect_callback` to register a connect callback.
* A Method :func:`comm_instance.register_disconnect_callback` to register a disconnect callback.
* A Method :func:`comm_instance.send` to send data via the :class:`comm_instance`.
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_server.py
.. note:: The parameter :const:`auto_auth` is only relevant, if a secret is given and the :class:`comm_instance` is a client. The authentification is initiated directly after the connection is established.
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_server.log
.. note:: The :const:`channel_name`-exchange will be initiated by the client directly after the the connection is established.
Client:
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_client.py
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_client.log
* If a channel_name is given at both communication sides and they are different, the client name is taken over and the server will log a warning message.
"""
DEFAULT_CHANNEL_NAME = 'all_others'
SID_AUTH_SEED_REQUEST = 1
"""SID for requesting a seed for authentification"""
SID_AUTH_KEY_REQUEST = 2
"""SID for requesting a key for the given seed"""
SID_AUTH_KEY_CHECK_REQUEST = 3
"""SID for request for checking a key"""
SID_AUTH_KEY_CHECK_RESPONSE = 4
"""SID for the authentification response"""
SID_CHANNEL_NAME_REQUEST = 5
"""SID for requesting a channel name exchange"""
SID_CHANNEL_NAME_RESPONSE = 6
"""SID for the channel name response"""
SID_READ_REQUEST = 10
"""SID for a read data request"""
SID_READ_RESPONSE = 11
"""SID for read data response"""
SID_WRITE_REQUEST = 20
"""SID for a write data request"""
SID_WRITE_RESPONSE = 21
"""SID for a write data response"""
SID_EXECUTE_REQUEST = 30
"""SID for a execute request"""
SID_EXECUTE_RESPONSE = 31
"""SID for a execute response"""
SID_RESPONSE_DICT = {SID_AUTH_SEED_REQUEST: SID_AUTH_KEY_REQUEST,
SID__RESPONSE_DICT = {SID_AUTH_SEED_REQUEST: SID_AUTH_KEY_REQUEST,
SID_AUTH_KEY_REQUEST: SID_AUTH_KEY_CHECK_REQUEST,
SID_AUTH_KEY_CHECK_REQUEST: SID_AUTH_KEY_CHECK_RESPONSE,
SID_CHANNEL_NAME_REQUEST: SID_CHANNEL_NAME_RESPONSE,
SID_READ_REQUEST: SID_READ_RESPONSE,
SID_WRITE_REQUEST: SID_WRITE_RESPONSE,
SID_EXECUTE_REQUEST: SID_EXECUTE_RESPONSE}
"""Dictionary to get the SID for the response by the key which is the SID for the request"""
SID_AUTH_LIST = [
SID__NO_AUTH_LIST = [
SID_AUTH_SEED_REQUEST,
SID_AUTH_KEY_REQUEST,
SID_AUTH_KEY_CHECK_REQUEST,
@ -174,37 +229,51 @@ class struct_json_protocol(object):
SID_CHANNEL_NAME_REQUEST,
SID_CHANNEL_NAME_RESPONSE
]
"""List of SIDs without need of an authentification"""
STATUS_OKAY = 0
"""Status for 'okay'"""
STATUS_BUFFERING_UNHANDLED_REQUEST = 1
"""Status for 'unhandled request'"""
STATUS_AUTH_REQUIRED = 2
"""Status for 'authentification is required'"""
STATUS_SERVICE_OR_DATA_UNKNOWN = 3
"""Status for 'service or data unknown'"""
STATUS_CHECKSUM_ERROR = 4
"""Status for 'checksum error'"""
STATUS_OPERATION_NOT_PERMITTED = 5
STATUS_NAMES = {STATUS_OKAY: 'Okay',
"""Status for 'operation not permitted'"""
STATUS__NAMES = {STATUS_OKAY: 'Okay',
STATUS_BUFFERING_UNHANDLED_REQUEST: 'Request has no callback. Data buffered.',
STATUS_AUTH_REQUIRED: 'Authentification required',
STATUS_SERVICE_OR_DATA_UNKNOWN: 'Service or Data unknown',
STATUS_CHECKSUM_ERROR: 'Checksum Error',
STATUS_OPERATION_NOT_PERMITTED: 'Operation not permitted'}
"""Status names for previous defined states"""
AUTH_STATE_UNKNOWN_CLIENT = 0
"""Authentification Status for 'Unknown Client'"""
AUTH_STATE_SEED_REQUESTED = 1
"""Authentification Status for 'Seed was requested'"""
AUTH_STATE_SEED_TRANSFERRED = 2
"""Authentification Status for 'Seed has been sent'"""
AUTH_STATE_KEY_TRANSFERRED = 3
"""Authentification Status for 'Key has been sent'"""
AUTH_STATE_TRUSTED_CLIENT = 4
AUTH_STATUS_NAMES = {AUTH_STATE_UNKNOWN_CLIENT: 'Unknown Client',
"""Authentification Status for 'Trusted Connection'"""
AUTH_STATE__NAMES = {AUTH_STATE_UNKNOWN_CLIENT: 'Unknown Client',
AUTH_STATE_SEED_REQUESTED: 'Seed was requested',
AUTH_STATE_SEED_TRANSFERRED: 'Seed has been sent',
AUTH_STATE_KEY_TRANSFERRED: 'Key has been sent',
AUTH_STATE_TRUSTED_CLIENT: 'Trusted Client'}
AUTH_STATE_TRUSTED_CLIENT: 'Trusted Connection'}
"""Authentification Status names for previous defined authentification states"""
def __init__(self, comm_instance, secret=None, auto_auth=False, channel_name=None):
self.__comm_inst__ = comm_instance
self.__secret__ = secret
self.__auto_auth__ = auto_auth
#
self.__callbacks__ = callback_storage(channel_name)
self.__callbacks__ = _callback_storage(channel_name)
self.__init_channel_name__(channel_name)
#
self.__clean_receive_buffer__()
@ -220,13 +289,76 @@ class struct_json_protocol(object):
self.__comm_inst__.register_connect_callback(self.__connection_established__)
self.__comm_inst__.register_disconnect_callback(self.__authentification_state_reset__)
def __init_channel_name__(self, channel_name):
self.__comm_inst__.init_channel_name(channel_name)
self.__callbacks__.init_channel_name(channel_name)
if channel_name is None:
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + self.DEFAULT_CHANNEL_NAME)
def __analyse_frame__(self, frame):
if sys.version_info >= (3, 0):
return data_storage(json.loads(frame[:-4].decode('utf-8')))
else:
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
return data_storage(json.loads(frame[:-4]))
def __authentificate_check_key__(self, msg):
key = msg.get_data()
if key == self.__authentificate_salt_and_hash__(self.__seed__):
self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
self.logger.info("%s Got correct key, sending positive authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, True
else:
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
self.logger.info("%s Got incorrect key, sending negative authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, False
def __authentificate_create_key__(self, msg):
self.logger.info("%s Got seed, sending key for authentification", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_KEY_TRANSFERRED
seed = msg.get_data()
key = self.__authentificate_salt_and_hash__(seed)
return self.STATUS_OKAY, key
def __authentificate_create_seed__(self, msg):
self.logger.info("%s Got seed request, sending seed for authentification", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_SEED_TRANSFERRED
if sys.version_info >= (3, 0):
self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
else:
self.__seed__ = binascii.hexlify(os.urandom(32))
return self.STATUS_OKAY, self.__seed__
def __authentificate_process_feedback__(self, msg):
feedback = msg.get_data()
if feedback:
self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
self.logger.info("%s Got positive authentification feedback", self.__log_prefix__())
else:
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
self.logger.warning("%s Got negative authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, None
def __authentificate_salt_and_hash__(self, seed):
if sys.version_info >= (3, 0):
return hashlib.sha512(bytes(seed, 'utf-8') + self.__secret__).hexdigest()
else:
return hashlib.sha512(seed.encode('utf-8') + self.__secret__.encode('utf-8')).hexdigest()
def __authentification_state_reset__(self):
self.logger.info("%s Resetting authentification state to AUTH_STATE_UNKNOWN_CLIENT", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
def __buffer_received_data__(self, msg):
if not msg.get_service_id() in self.__msg_buffer__:
self.__msg_buffer__[msg.get_service_id()] = {}
if not msg.get_data_id() in self.__msg_buffer__[msg.get_service_id()]:
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()] = []
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
self.logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.__log_prefix__())
def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
data_frame = json.dumps(self.__mk_msg__(status, service_id, data_id, data))
if sys.version_info >= (3, 0):
data_frame = bytes(data_frame, 'utf-8')
checksum = self.__calc_chksum__(data_frame)
return data_frame + checksum
def __calc_chksum__(self, raw_data):
return struct.pack('>I', binascii.crc32(raw_data) & 0xffffffff)
@property
def __channel_name__(self):
@ -234,24 +366,12 @@ class struct_json_protocol(object):
if cn != self.DEFAULT_CHANNEL_NAME:
return cn
def __log_prefix__(self):
return ' SP client:' if self.__comm_inst__.IS_CLIENT else ' SP server:'
def connected(self):
return self.__comm_inst__.is_connected()
def connection_established(self):
return self.connected() and (self.__secret__ is None or self.check_authentification_state())
def reconnect(self):
return self.__comm_inst__.reconnect()
def __connection_established__(self):
self.__clean_receive_buffer__()
if not self.__comm_inst__.IS_CLIENT:
self.send(self.SID_CHANNEL_NAME_REQUEST, 0, self.__channel_name__)
if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
self.authentificate()
def __channel_name_response__(self, msg):
data = msg.get_data()
if self.__channel_name__ is None and data is not None:
self.__init_channel_name__(data)
self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
return self.STATUS_OKAY, None
def __channel_name_request__(self, msg):
data = msg.get_data()
@ -266,49 +386,12 @@ class struct_json_protocol(object):
self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
return self.STATUS_OKAY, None
def __channel_name_response__(self, msg):
data = msg.get_data()
if self.__channel_name__ is None and data is not None:
self.__init_channel_name__(data)
self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
return self.STATUS_OKAY, None
def __authentification_state_reset__(self):
self.logger.info("%s Resetting authentification state to AUTH_STATE_UNKNOWN_CLIENT", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
def __analyse_frame__(self, frame):
status, service_id, data_id = struct.unpack('>III', frame[0:12])
if sys.version_info >= (3, 0):
data = json.loads(frame[12:-1].decode('utf-8'))
else:
data = json.loads(frame[12:-1])
return self.__mk_msg__(status, service_id, data_id, data)
def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
frame = struct.pack('>III', status, service_id, data_id)
if sys.version_info >= (3, 0):
frame += bytes(json.dumps(data), 'utf-8')
frame += self.__calc_chksum__(frame)
else:
frame += json.dumps(data)
frame += self.__calc_chksum__(frame)
return frame
def __calc_chksum__(self, raw_data):
chksum = 0
for b in raw_data:
if sys.version_info >= (3, 0):
chksum ^= b
else:
chksum ^= ord(b)
if sys.version_info >= (3, 0):
return bytes([chksum])
else:
return chr(chksum)
def __check_frame_checksum__(self, frame):
return self.__calc_chksum__(frame[:-1]) == frame[-1:]
return self.__calc_chksum__(frame[:-4]) == frame[-4:]
def __clean_receive_buffer__(self):
self.logger.debug("%s Cleaning up receive-buffer", self.__log_prefix__())
self.__msg_buffer__ = {}
def __data_available_callback__(self, comm_inst):
frame = comm_inst.receive()
@ -325,14 +408,14 @@ class struct_json_protocol(object):
repr(msg.get_data())
)
callback, args, kwargs = self.__callbacks__.get(msg.get_service_id(), msg.get_data_id())
if msg.get_service_id() in self.SID_RESPONSE_DICT.keys():
if msg.get_service_id() in self.SID__RESPONSE_DICT.keys():
#
# REQUEST RECEIVED
#
if self.__secret__ is not None and not self.check_authentification_state() and msg.get_service_id() not in self.SID_AUTH_LIST:
if self.__secret__ is not None and not self.check_authentification_state() and msg.get_service_id() not in self.SID__NO_AUTH_LIST:
status = self.STATUS_AUTH_REQUIRED
data = None
self.logger.warning("%s Received message needs authentification: %s. Sending negative response.", self.__log_prefix__(), self.AUTH_STATUS_NAMES.get(self.__authentification_state__, 'Unknown authentification status!'))
self.logger.warning("%s Received message needs authentification: %s. Sending negative response.", self.__log_prefix__(), self.AUTH_STATE__NAMES.get(self.__authentification_state__, 'Unknown authentification status!'))
elif callback is None:
self.logger.warning("%s Received message with no registered callback. Sending negative response.", self.__log_prefix__())
status = self.STATUS_BUFFERING_UNHANDLED_REQUEST
@ -343,13 +426,13 @@ class struct_json_protocol(object):
status, data = callback(msg, *args, **kwargs)
except TypeError:
raise TypeError('Check return value of callback function {callback_name} for service_id {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
self.send(self.SID_RESPONSE_DICT[msg.get_service_id()], msg.get_data_id(), data, status=status)
self.send(self.SID__RESPONSE_DICT[msg.get_service_id()], msg.get_data_id(), data, status=status)
else:
#
# RESPONSE RECEIVED
#
if msg.get_status() not in [self.STATUS_OKAY]:
self.logger.warning("%s Received message has a peculiar status: %s", self.__log_prefix__(), self.STATUS_NAMES.get(msg.get_status(), 'Unknown status response!'))
self.logger.warning("%s Received message has a peculiar status: %s", self.__log_prefix__(), self.STATUS__NAMES.get(msg.get_status(), 'Unknown status response!'))
if callback is None:
status = self.STATUS_OKAY
data = None
@ -361,83 +444,27 @@ class struct_json_protocol(object):
except TypeError:
raise TypeError('Check return value of callback function {callback_name} for service_id {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
def __buffer_received_data__(self, msg):
if not msg.get_service_id() in self.__msg_buffer__:
self.__msg_buffer__[msg.get_service_id()] = {}
if not msg.get_data_id() in self.__msg_buffer__[msg.get_service_id()]:
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()] = []
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
self.logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.__log_prefix__())
def __connection_established__(self):
self.__clean_receive_buffer__()
if not self.__comm_inst__.IS_CLIENT:
self.send(self.SID_CHANNEL_NAME_REQUEST, 0, self.__channel_name__)
if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
self.authentificate()
def __clean_receive_buffer__(self):
self.logger.debug("%s Cleaning up receive-buffer", self.__log_prefix__())
self.__msg_buffer__ = {}
def __init_channel_name__(self, channel_name):
self.__comm_inst__.init_channel_name(channel_name)
self.__callbacks__.init_channel_name(channel_name)
if channel_name is None:
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + self.DEFAULT_CHANNEL_NAME)
else:
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
def receive(self, service_id, data_id, timeout=1):
data = None
cnt = 0
while data is None and cnt < timeout * 10:
try:
data = self.__msg_buffer__.get(service_id, {}).get(data_id, []).pop(0)
except IndexError:
data = None
cnt += 1
time.sleep(0.1)
if data is None and cnt >= timeout * 10:
self.logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.', self.__log_prefix__(), repr(timeout), repr(service_id), repr(data_id))
return data
def __log_prefix__(self):
return ' SP client:' if self.__comm_inst__.IS_CLIENT else ' SP server:'
def __mk_msg__(self, status, service_id, data_id, data):
return data_storage({data_storage.KEY_DATA_ID: data_id, data_storage.KEY_SERVICE_ID: service_id, data_storage.KEY_STATUS: status, data_storage.KEY_DATA: data})
def send(self, service_id, data_id, data, status=STATUS_OKAY, timeout=2, log_lvl=logging.INFO):
"""
:param service_id: The Service-ID for the message. See class definitions starting with ``SERVICE_``.
:type service_id: int
:param data_id: The Data-ID for the message.
:type data_id: int
:param data: The data to be transfered. The data needs to be json compatible.
:type data: str
:param status: The Status for the message. All requests should have ``STATUS_OKAY``.
:type status: int
:param timeout: The timeout for sending data (e.g. time to establish new connection).
:type timeout: float
:param rx_log_lvl: The log level to log outgoing TX-data
:type rx_log_lvl: int
:return: True if data had been sent, otherwise False.
:rtype: bool
This methods sends out a message with the given content.
"""
self.logger.log(log_lvl, '%s TX -> status: %d, service_id: %d, data_id: %d, data: "%s"', self.__log_prefix__(), status, service_id, data_id, repr(data))
return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
def register_callback(self, service_id, data_id, callback, *args, **kwargs):
"""
:param service_id: The Service-ID for the message. See class definitions starting with ``SID_``.
:type service_id: int
:param data_id: The Data-ID for the message.
:type data_id: int
:returns: True, if registration was successfull; False, if registration failed (e.g. existance of a callback for this configuration)
:rtype: bool
This method registers a callback for the given parameters. Givin ``None`` means, that all Service-IDs or all Data-IDs are used.
If a message hitting these parameters has been received, the callback will be executed.
.. note:: The :func:`callback` is priorised in the following order:
* Callbacks with defined Service-ID and Data-ID.
* Callbacks with a defined Data-ID.
* Callbacks with a defined Service-ID.
* Unspecific Callbacks
.. note:: The :func:`callback` is executed with these arguments:
:param msg: A :class:`dict` containing all message information.
:returns: status (see class definition starting with ``STATUS_``), response_data (JSON compatible object)
"""
self.__callbacks__.add(service_id, data_id, callback, *args, **kwargs)
def authentificate(self, timeout=2):
"""
:param timeout: The timeout for the authentification (requesting seed, sending key and getting authentification_feedback).
@ -472,92 +499,145 @@ class struct_json_protocol(object):
"""
return self.__authentification_state__ == self.AUTH_STATE_TRUSTED_CLIENT
def __authentificate_salt_and_hash__(self, seed):
if sys.version_info >= (3, 0):
return hashlib.sha512(bytes(seed, 'utf-8') + self.__secret__).hexdigest()
else:
return hashlib.sha512(seed.encode('utf-8') + self.__secret__.encode('utf-8')).hexdigest()
def __authentificate_create_seed__(self, msg):
self.logger.info("%s Got seed request, sending seed for authentification", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_SEED_TRANSFERRED
if sys.version_info >= (3, 0):
self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
else:
self.__seed__ = binascii.hexlify(os.urandom(32))
return self.STATUS_OKAY, self.__seed__
def __authentificate_create_key__(self, msg):
self.logger.info("%s Got seed, sending key for authentification", self.__log_prefix__())
self.__authentification_state__ = self.AUTH_STATE_KEY_TRANSFERRED
seed = msg.get_data()
key = self.__authentificate_salt_and_hash__(seed)
return self.STATUS_OKAY, key
def __authentificate_check_key__(self, msg):
key = msg.get_data()
if key == self.__authentificate_salt_and_hash__(self.__seed__):
self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
self.logger.info("%s Got correct key, sending positive authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, True
else:
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
self.logger.info("%s Got incorrect key, sending negative authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, False
def __authentificate_process_feedback__(self, msg):
feedback = msg.get_data()
if feedback:
self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
self.logger.info("%s Got positive authentification feedback", self.__log_prefix__())
else:
self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
self.logger.warning("%s Got negative authentification feedback", self.__log_prefix__())
return self.STATUS_OKAY, None
class pure_json_protocol(struct_json_protocol):
def connection_established(self):
"""
:param comm_instance: a communication instance supportin at least these functions: :func:`register_callback`, :func:`register_disconnect_callback`, :func:`send`.
:type comm_instance: instance
:param secret: A secret (e.g. created by ``binascii.hexlify(os.urandom(24))``).
:type secret: str
:return: True, if the connection is established (incl. authentification, if a secret has been given)
:rtype: bool
"""
return self.is_connected() and (self.__secret__ is None or self.check_authentification_state())
This communication protocol supports to transfer a Service-ID, Data-ID and Data.
def is_connected(self):
"""
:return: True if the :class:`comm_instance` is connected, otherwise False..
:rtype: bool
**Example:**
This methods returns the return value of :func:`comm_instance.is_connected`.
"""
return self.__comm_inst__.is_connected()
Server:
def receive(self, service_id, data_id, timeout=1):
"""
:param service_id: The Service-ID for the message. See class definitions starting with ``SID_``.
:type service_id: int
:param data_id: The Data-ID for the message.
:type data_id: int
:param timeout: The timeout for receiving.
:type timeout: float
:returns: The received data storage object or None, if no data was received.
:rtype: data_storage
"""
data = None
cnt = 0
while data is None and cnt < timeout * 10:
try:
data = self.__msg_buffer__.get(service_id, {}).get(data_id, []).pop(0)
except IndexError:
data = None
cnt += 1
time.sleep(0.1)
if data is None and cnt >= timeout * 10:
self.logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.', self.__log_prefix__(), repr(timeout), repr(service_id), repr(data_id))
return data
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__pure_json_protocol_server.py
def reconnect(self):
"""
This methods initiates a reconnect by calling :func:`comm_instance.reconnect`.
"""
return self.__comm_inst__.reconnect()
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__pure_json_protocol_server.log
def register_callback(self, service_id, data_id, callback, *args, **kwargs):
"""
:param service_id: The Service-ID for the message. See class definitions starting with ``SID_``.
:type service_id: int
:param data_id: The Data-ID for the message.
:type data_id: int
:returns: True, if registration was successfull; False, if registration failed (e.g. existance of a callback for this configuration)
:rtype: bool
This method registers a callback for the given parameters. Givin ``None`` means, that all Service-IDs or all Data-IDs are used.
If a message hitting these parameters has been received, the callback will be executed.
.. note:: The :func:`callback` is priorised in the following order:
* Callbacks with defined Service-ID and Data-ID.
* Callbacks with a defined Data-ID.
* Callbacks with a defined Service-ID.
* Unspecific Callbacks
.. note:: The :func:`callback` is executed with these arguments:
:param msg: A :class:`data_storage` object containing all message information.
:returns: (:const:`status`, :const:`response_data`)
* :const:`status`: A status as defined as a constant of this class :const:`STA_*` to be used as status for the response.
* :const:`response_data`: A JSON iterable object to be used as data for the response.
.. note:: Only callbacks defined in :const:`pure_json_protocol.SID__RESPONSE_DICT` will send a response, using a Service-ID given in the dict and the same Data-ID to the client.
"""
self.__callbacks__.add(service_id, data_id, callback, *args, **kwargs)
def send(self, service_id, data_id, data, status=STATUS_OKAY, timeout=2, log_lvl=logging.INFO):
"""
:param service_id: The Service-ID for the message. See class definitions starting with ``SERVICE_``.
:type service_id: int
:param data_id: The Data-ID for the message.
:type data_id: int
:param data: The data to be transfered. The data needs to be json compatible.
:type data: str
:param status: The Status for the message. All requests should have ``STATUS_OKAY``.
:type status: int
:param timeout: The timeout for sending data (e.g. time to establish new connection).
:type timeout: float
:param rx_log_lvl: The log level to log outgoing TX-data
:type rx_log_lvl: int
:return: True if data had been sent, otherwise False.
:rtype: bool
This methods sends out a message with the given content.
"""
self.logger.log(log_lvl, '%s TX -> status: %d, service_id: %d, data_id: %d, data: "%s"', self.__log_prefix__(), status, service_id, data_id, repr(data))
return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
Client:
class struct_json_protocol(pure_json_protocol):
"""
This Class has the same functionality like :class:`pure_json_protocol`. The message length is less than for :class:`pure_json_protocol`, but the functionality and compatibility is reduced.
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__pure_json_protocol_client.py
.. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__pure_json_protocol_client.log
.. note::
This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of :class:`pure_json_protocol` is recommended.
"""
def __init__(self, *args, **kwargs):
struct_json_protocol.__init__(self, *args, **kwargs)
def __build_frame__(self, service_id, data_id, data, status=struct_json_protocol.STATUS_OKAY):
data_frame = json.dumps(self.__mk_msg__(status, service_id, data_id, data))
if sys.version_info >= (3, 0):
data_frame = bytes(data_frame, 'utf-8')
checksum = self.__calc_chksum__(data_frame)
return data_frame + checksum
pure_json_protocol.__init__(self, *args, **kwargs)
def __analyse_frame__(self, frame):
status, service_id, data_id = struct.unpack('>III', frame[0:12])
if sys.version_info >= (3, 0):
return data_storage(json.loads(frame[:-4].decode('utf-8')))
data = json.loads(frame[12:-1].decode('utf-8'))
else:
return data_storage(json.loads(frame[:-4]))
data = json.loads(frame[12:-1])
return self.__mk_msg__(status, service_id, data_id, data)
def __build_frame__(self, service_id, data_id, data, status=pure_json_protocol.STATUS_OKAY):
frame = struct.pack('>III', status, service_id, data_id)
if sys.version_info >= (3, 0):
frame += bytes(json.dumps(data), 'utf-8')
frame += self.__calc_chksum__(frame)
else:
frame += json.dumps(data)
frame += self.__calc_chksum__(frame)
return frame
def __calc_chksum__(self, raw_data):
return struct.pack('>I', binascii.crc32(raw_data) & 0xffffffff)
chksum = 0
for b in raw_data:
if sys.version_info >= (3, 0):
chksum ^= b
else:
chksum ^= ord(b)
if sys.version_info >= (3, 0):
return bytes([chksum])
else:
return chr(chksum)
def __check_frame_checksum__(self, frame):
return self.__calc_chksum__(frame[:-4]) == frame[-4:]
return self.__calc_chksum__(frame[:-1]) == frame[-1:]

4
_docs_/.buildinfo Normal file
View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 84bc88da236ad2fe1e0ad2143091c944
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -0,0 +1,23 @@
.. socket_protocol documentation master file, created by
sphinx-quickstart on Fri Jan 1 19:56:01 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to socket_protocol's documentation!
===========================================
.. automodule:: socket_protocol
:members:
.. toctree::
:maxdepth: 2
:caption: Contents:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

676
_docs_/_static/basic.css Normal file
View File

@ -0,0 +1,676 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- figures --------------------------------------------------------------- */
div.figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption {
padding: 0.3em;
}
div.figure p.caption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist td {
vertical-align: top;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
div.code-block-caption {
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
div.code-block-caption + div > div.highlight > pre {
margin-top: 0;
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
padding: 1em 1em 0;
}
div.literal-block-wrapper div.highlight {
margin: 0;
}
code.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
code.descclassname {
background-color: transparent;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: relative;
left: 0px;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View File

@ -0,0 +1 @@
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

315
_docs_/_static/doctools.js Normal file
View File

@ -0,0 +1,315 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keyup(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box or textarea
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View File

@ -0,0 +1,10 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
};

BIN
_docs_/_static/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

10365
_docs_/_static/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});

View File

@ -0,0 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);

4
_docs_/_static/js/html5shiv.min.js vendored Normal file
View File

@ -0,0 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);

4
_docs_/_static/js/modernizr.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n('<span class="toctree-expand"></span>'),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}t.length>0&&($(".wy-menu-vertical .current").removeClass("current"),t.addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l1").parent().addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l2").addClass("current"),t.closest("li.toctree-l3").addClass("current"),t.closest("li.toctree-l4").addClass("current"),t.closest("li.toctree-l5").addClass("current"),t[0].scrollIntoView())}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);

View File

@ -0,0 +1,297 @@
/*
* language_data.js
* ~~~~~~~~~~~~~~~~
*
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
/* Non-minified version JS is _stemmer.js if file is provided */
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}

BIN
_docs_/_static/minus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
_docs_/_static/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

View File

@ -0,0 +1,69 @@
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */

View File

@ -0,0 +1,481 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
// query found in terms
term: 5
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
if (suffix === undefined) {
suffix = '.txt';
}
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
}
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var score = 0;
var parts = fullname.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullname == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
return results;
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {}
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

1692
_docs_/_static/underscore.js Normal file

File diff suppressed because it is too large Load Diff

353
_docs_/genindex.html Normal file
View File

@ -0,0 +1,353 @@
<!DOCTYPE html>
<html class="writer-html4" lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index &mdash; socket_protocol documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home" alt="Documentation Home"> socket_protocol
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"></div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">socket_protocol</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Index</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#A"><strong>A</strong></a>
| <a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#G"><strong>G</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
</div>
<h2 id="A">A</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE__NAMES">AUTH_STATE__NAMES (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE_KEY_TRANSFERRED">AUTH_STATE_KEY_TRANSFERRED (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE_SEED_REQUESTED">AUTH_STATE_SEED_REQUESTED (socket_protocol.pure_json_protocol attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE_SEED_TRANSFERRED">AUTH_STATE_SEED_TRANSFERRED (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE_TRUSTED_CLIENT">AUTH_STATE_TRUSTED_CLIENT (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.AUTH_STATE_UNKNOWN_CLIENT">AUTH_STATE_UNKNOWN_CLIENT (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.authentificate">authentificate() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.check_authentification_state">check_authentification_state() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.connection_established">connection_established() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.data_storage">data_storage (class in socket_protocol)</a>
</li>
</ul></td>
</tr></table>
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.data_storage.get_data">get_data() (socket_protocol.data_storage method)</a>
</li>
<li><a href="index.html#socket_protocol.data_storage.get_data_id">get_data_id() (socket_protocol.data_storage method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.data_storage.get_service_id">get_service_id() (socket_protocol.data_storage method)</a>
</li>
<li><a href="index.html#socket_protocol.data_storage.get_status">get_status() (socket_protocol.data_storage method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="I">I</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.is_connected">is_connected() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol">pure_json_protocol (class in socket_protocol)</a>
</li>
</ul></td>
</tr></table>
<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.receive">receive() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.reconnect">reconnect() (socket_protocol.pure_json_protocol method)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.register_callback">register_callback() (socket_protocol.pure_json_protocol method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.send">send() (socket_protocol.pure_json_protocol method)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID__NO_AUTH_LIST">SID__NO_AUTH_LIST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID__RESPONSE_DICT">SID__RESPONSE_DICT (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_REQUEST">SID_AUTH_KEY_CHECK_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_RESPONSE">SID_AUTH_KEY_CHECK_RESPONSE (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_AUTH_KEY_REQUEST">SID_AUTH_KEY_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_AUTH_SEED_REQUEST">SID_AUTH_SEED_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_REQUEST">SID_CHANNEL_NAME_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_RESPONSE">SID_CHANNEL_NAME_RESPONSE (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_EXECUTE_REQUEST">SID_EXECUTE_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_EXECUTE_RESPONSE">SID_EXECUTE_RESPONSE (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_READ_REQUEST">SID_READ_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_READ_RESPONSE">SID_READ_RESPONSE (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_WRITE_REQUEST">SID_WRITE_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.SID_WRITE_RESPONSE">SID_WRITE_RESPONSE (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#module-socket_protocol">socket_protocol (module)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS__NAMES">STATUS__NAMES (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_AUTH_REQUIRED">STATUS_AUTH_REQUIRED (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_BUFFERING_UNHANDLED_REQUEST">STATUS_BUFFERING_UNHANDLED_REQUEST (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_CHECKSUM_ERROR">STATUS_CHECKSUM_ERROR (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_OKAY">STATUS_OKAY (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_OPERATION_NOT_PERMITTED">STATUS_OPERATION_NOT_PERMITTED (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.pure_json_protocol.STATUS_SERVICE_OR_DATA_UNKNOWN">STATUS_SERVICE_OR_DATA_UNKNOWN (socket_protocol.pure_json_protocol attribute)</a>
</li>
<li><a href="index.html#socket_protocol.struct_json_protocol">struct_json_protocol (class in socket_protocol)</a>
</li>
</ul></td>
</tr></table>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2021, Dirk Alders
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

722
_docs_/index.html Normal file
View File

@ -0,0 +1,722 @@
<!DOCTYPE html>
<html class="writer-html4" lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to socket_protocols documentation! &mdash; socket_protocol documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="#" class="icon icon-home" alt="Documentation Home"> socket_protocol
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"><ul>
<li><a class="reference internal" href="#">Welcome to socket_protocols documentation!</a><ul>
<li><a class="reference internal" href="#socket-protocol-socket-protocol">socket_protocol (Socket Protocol)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
</div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="#">socket_protocol</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="#" class="icon icon-home"></a> &raquo;</li>
<li>Welcome to socket_protocols documentation!</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/index.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="module-socket_protocol">
<span id="welcome-to-socket-protocol-s-documentation"></span><h1>Welcome to socket_protocols documentation!<a class="headerlink" href="#module-socket_protocol" title="Permalink to this headline"></a></h1>
<div class="section" id="socket-protocol-socket-protocol">
<h2>socket_protocol (Socket Protocol)<a class="headerlink" href="#socket-protocol-socket-protocol" title="Permalink to this headline"></a></h2>
<p><strong>Author:</strong></p>
<ul class="simple">
<li>Dirk Alders &lt;<a class="reference external" href="mailto:sudo-dirk&#37;&#52;&#48;mount-mockery&#46;de">sudo-dirk<span>&#64;</span>mount-mockery<span>&#46;</span>de</a>&gt;</li>
</ul>
<p><strong>Description:</strong></p>
<blockquote>
<div>This Module supports point to point communication for client-server issues.</div></blockquote>
<p><strong>Submodules:</strong></p>
<ul class="simple">
<li><a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket_protocol.pure_json_protocol</span></code></a></li>
<li><a class="reference internal" href="#socket_protocol.struct_json_protocol" title="socket_protocol.struct_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket_protocol.struct_json_protocol</span></code></a></li>
</ul>
<p><strong>Unittest:</strong></p>
<blockquote>
<div>See also the <a class="reference download internal" download="" href="_downloads/f482679fb1771f4d05403bb87fd0cc34/unittest.pdf"><code class="xref download docutils literal notranslate"><span class="pre">unittest</span></code></a> documentation.</div></blockquote>
<p><strong>Module Documentation:</strong></p>
<dl class="class">
<dt id="socket_protocol.data_storage">
<em class="property">class </em><code class="descclassname">socket_protocol.</code><code class="descname">data_storage</code><span class="sig-paren">(</span><em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.data_storage" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>status</strong> (<em>int</em>) The message status.</li>
<li><strong>service_id</strong> (<em>int</em>) The Service-ID.</li>
<li><strong>data_id</strong> (<em>int</em>) The Data-ID.</li>
<li><strong>data</strong> (<em>any</em>) The transfered data.</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>This is a storage object for socket_protocol messages.</p>
<dl class="method">
<dt id="socket_protocol.data_storage.get_data">
<code class="descname">get_data</code><span class="sig-paren">(</span><em>default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.data_storage.get_data" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>default</strong> The default value, if no data is available.</td>
</tr>
</tbody>
</table>
<p>This Method returns the message data.</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.data_storage.get_data_id">
<code class="descname">get_data_id</code><span class="sig-paren">(</span><em>default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.data_storage.get_data_id" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>default</strong> The default value, if no data is available.</td>
</tr>
</tbody>
</table>
<p>This Method returns the message Data-ID.</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.data_storage.get_service_id">
<code class="descname">get_service_id</code><span class="sig-paren">(</span><em>default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.data_storage.get_service_id" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>default</strong> The default value, if no data is available.</td>
</tr>
</tbody>
</table>
<p>This Method returns the message Service-ID.</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.data_storage.get_status">
<code class="descname">get_status</code><span class="sig-paren">(</span><em>default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.data_storage.get_status" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>default</strong> The default value, if no data is available.</td>
</tr>
</tbody>
</table>
<p>This Method returns the message status.</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="socket_protocol.pure_json_protocol">
<em class="property">class </em><code class="descclassname">socket_protocol.</code><code class="descname">pure_json_protocol</code><span class="sig-paren">(</span><em>comm_instance</em>, <em>secret=None</em>, <em>auto_auth=False</em>, <em>channel_name=None</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>comm_instance</strong> (<em>instance</em>) A communication instance.</li>
<li><strong>secret</strong> (<em>str</em>) An optinal secret (e.g. created by <code class="docutils literal notranslate"><span class="pre">binascii.hexlify(os.urandom(24))</span></code>).</li>
<li><strong>auto_auth</strong> (<em>bool</em>) An optional parameter (True) to enable automatic authentification, otherwise you need to do it manually, if needed.</li>
<li><strong>channel_name</strong> (<em>str</em>) An optional parameter to set a channel name for logging of the communication.</li>
</ul>
</td>
</tr>
</tbody>
</table>
<div class="admonition hint">
<p class="first admonition-title">Hint</p>
<p>This <cite>class</cite> supports to transfer a Service-ID, Data-ID and Data.</p>
<ul class="last simple">
<li>The Service-ID is designed to identify the type of the communication (e.g. READ_REQUEST, WRITE_REQUEST, READ_RESPONSE, WRITE_RESPONSE, …)</li>
<li>The Data-ID is designed to identify the requests / responses using the same Service_ID.</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The <code class="xref py py-class docutils literal notranslate"><span class="pre">comm_instance</span></code> needs to have at least the following interface:</p>
<ul class="last simple">
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.init_channel_name()</span></code> to set the channel name if needed.</li>
<li>A Constant <code class="xref py py-const docutils literal notranslate"><span class="pre">comm_instance.IS_CLIENT</span></code> to identify that the <code class="xref py py-class docutils literal notranslate"><span class="pre">comm_instance</span></code> is a client (True) or a server (False).</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.is_connected()</span></code> to identify if the instance is connected (True) or not (False).</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.reconnect()</span></code> to initiate a reconnect.</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.register_callback()</span></code> to register a data available callback.</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.register_connect_callback()</span></code> to register a connect callback.</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.register_disconnect_callback()</span></code> to register a disconnect callback.</li>
<li>A Method <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.send()</span></code> to send data via the <code class="xref py py-class docutils literal notranslate"><span class="pre">comm_instance</span></code>.</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The parameter <code class="xref py py-const docutils literal notranslate"><span class="pre">auto_auth</span></code> is only relevant, if a secret is given and the <code class="xref py py-class docutils literal notranslate"><span class="pre">comm_instance</span></code> is a client. The authentification is initiated directly after the connection is established.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The <code class="xref py py-const docutils literal notranslate"><span class="pre">channel_name</span></code>-exchange will be initiated by the client directly after the the connection is established.</p>
<ul class="last simple">
<li>If a channel_name is given at both communication sides and they are different, the client name is taken over and the server will log a warning message.</li>
</ul>
</div>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE_KEY_TRANSFERRED">
<code class="descname">AUTH_STATE_KEY_TRANSFERRED</code><em class="property"> = 3</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE_KEY_TRANSFERRED" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status for Key has been sent</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE_SEED_REQUESTED">
<code class="descname">AUTH_STATE_SEED_REQUESTED</code><em class="property"> = 1</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE_SEED_REQUESTED" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status for Seed was requested</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE_SEED_TRANSFERRED">
<code class="descname">AUTH_STATE_SEED_TRANSFERRED</code><em class="property"> = 2</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE_SEED_TRANSFERRED" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status for Seed has been sent</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE_TRUSTED_CLIENT">
<code class="descname">AUTH_STATE_TRUSTED_CLIENT</code><em class="property"> = 4</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE_TRUSTED_CLIENT" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status for Trusted Connection</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE_UNKNOWN_CLIENT">
<code class="descname">AUTH_STATE_UNKNOWN_CLIENT</code><em class="property"> = 0</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE_UNKNOWN_CLIENT" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status for Unknown Client</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.AUTH_STATE__NAMES">
<code class="descname">AUTH_STATE__NAMES</code><em class="property"> = {0: 'Unknown Client', 1: 'Seed was requested', 2: 'Seed has been sent', 3: 'Key has been sent', 4: 'Trusted Connection'}</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.AUTH_STATE__NAMES" title="Permalink to this definition"></a></dt>
<dd><p>Authentification Status names for previous defined authentification states</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_REQUEST">
<code class="descname">SID_AUTH_KEY_CHECK_REQUEST</code><em class="property"> = 3</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for request for checking a key</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_RESPONSE">
<code class="descname">SID_AUTH_KEY_CHECK_RESPONSE</code><em class="property"> = 4</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_AUTH_KEY_CHECK_RESPONSE" title="Permalink to this definition"></a></dt>
<dd><p>SID for the authentification response</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_AUTH_KEY_REQUEST">
<code class="descname">SID_AUTH_KEY_REQUEST</code><em class="property"> = 2</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_AUTH_KEY_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for requesting a key for the given seed</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_AUTH_SEED_REQUEST">
<code class="descname">SID_AUTH_SEED_REQUEST</code><em class="property"> = 1</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_AUTH_SEED_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for requesting a seed for authentification</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_REQUEST">
<code class="descname">SID_CHANNEL_NAME_REQUEST</code><em class="property"> = 5</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for requesting a channel name exchange</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_RESPONSE">
<code class="descname">SID_CHANNEL_NAME_RESPONSE</code><em class="property"> = 6</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_CHANNEL_NAME_RESPONSE" title="Permalink to this definition"></a></dt>
<dd><p>SID for the channel name response</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_EXECUTE_REQUEST">
<code class="descname">SID_EXECUTE_REQUEST</code><em class="property"> = 30</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_EXECUTE_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for a execute request</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_EXECUTE_RESPONSE">
<code class="descname">SID_EXECUTE_RESPONSE</code><em class="property"> = 31</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_EXECUTE_RESPONSE" title="Permalink to this definition"></a></dt>
<dd><p>SID for a execute response</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_READ_REQUEST">
<code class="descname">SID_READ_REQUEST</code><em class="property"> = 10</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_READ_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for a read data request</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_READ_RESPONSE">
<code class="descname">SID_READ_RESPONSE</code><em class="property"> = 11</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_READ_RESPONSE" title="Permalink to this definition"></a></dt>
<dd><p>SID for read data response</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_WRITE_REQUEST">
<code class="descname">SID_WRITE_REQUEST</code><em class="property"> = 20</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_WRITE_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>SID for a write data request</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID_WRITE_RESPONSE">
<code class="descname">SID_WRITE_RESPONSE</code><em class="property"> = 21</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID_WRITE_RESPONSE" title="Permalink to this definition"></a></dt>
<dd><p>SID for a write data response</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID__NO_AUTH_LIST">
<code class="descname">SID__NO_AUTH_LIST</code><em class="property"> = [1, 2, 3, 4, 5, 6]</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID__NO_AUTH_LIST" title="Permalink to this definition"></a></dt>
<dd><p>List of SIDs without need of an authentification</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.SID__RESPONSE_DICT">
<code class="descname">SID__RESPONSE_DICT</code><em class="property"> = {1: 2, 2: 3, 3: 4, 5: 6, 10: 11, 20: 21, 30: 31}</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.SID__RESPONSE_DICT" title="Permalink to this definition"></a></dt>
<dd><p>Dictionary to get the SID for the response by the key which is the SID for the request</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_AUTH_REQUIRED">
<code class="descname">STATUS_AUTH_REQUIRED</code><em class="property"> = 2</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_AUTH_REQUIRED" title="Permalink to this definition"></a></dt>
<dd><p>Status for authentification is required</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_BUFFERING_UNHANDLED_REQUEST">
<code class="descname">STATUS_BUFFERING_UNHANDLED_REQUEST</code><em class="property"> = 1</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_BUFFERING_UNHANDLED_REQUEST" title="Permalink to this definition"></a></dt>
<dd><p>Status for unhandled request</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_CHECKSUM_ERROR">
<code class="descname">STATUS_CHECKSUM_ERROR</code><em class="property"> = 4</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_CHECKSUM_ERROR" title="Permalink to this definition"></a></dt>
<dd><p>Status for checksum error</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_OKAY">
<code class="descname">STATUS_OKAY</code><em class="property"> = 0</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_OKAY" title="Permalink to this definition"></a></dt>
<dd><p>Status for okay</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_OPERATION_NOT_PERMITTED">
<code class="descname">STATUS_OPERATION_NOT_PERMITTED</code><em class="property"> = 5</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_OPERATION_NOT_PERMITTED" title="Permalink to this definition"></a></dt>
<dd><p>Status for operation not permitted</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS_SERVICE_OR_DATA_UNKNOWN">
<code class="descname">STATUS_SERVICE_OR_DATA_UNKNOWN</code><em class="property"> = 3</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS_SERVICE_OR_DATA_UNKNOWN" title="Permalink to this definition"></a></dt>
<dd><p>Status for service or data unknown</p>
</dd></dl>
<dl class="attribute">
<dt id="socket_protocol.pure_json_protocol.STATUS__NAMES">
<code class="descname">STATUS__NAMES</code><em class="property"> = {0: 'Okay', 1: 'Request has no callback. Data buffered.', 2: 'Authentification required', 3: 'Service or Data unknown', 4: 'Checksum Error', 5: 'Operation not permitted'}</em><a class="headerlink" href="#socket_protocol.pure_json_protocol.STATUS__NAMES" title="Permalink to this definition"></a></dt>
<dd><p>Status names for previous defined states</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.authentificate">
<code class="descname">authentificate</code><span class="sig-paren">(</span><em>timeout=2</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.authentificate" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>timeout</strong> (<em>float</em>) The timeout for the authentification (requesting seed, sending key and getting authentification_feedback).</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">True, if authentification was successfull; False, if not.</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">bool</td>
</tr>
</tbody>
</table>
<p>This method authetificates the client at the server.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">An authentification will only processed, if a secret had been given on initialisation.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Client and Server needs to use the same secret.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.check_authentification_state">
<code class="descname">check_authentification_state</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.check_authentification_state" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">True, if authentification state is okay, otherwise False</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">bool</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.connection_established">
<code class="descname">connection_established</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.connection_established" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">True, if the connection is established (incl. authentification, if a secret has been given)</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">bool</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.is_connected">
<code class="descname">is_connected</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.is_connected" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">True if the <code class="xref py py-class docutils literal notranslate"><span class="pre">comm_instance</span></code> is connected, otherwise False..</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">bool</td>
</tr>
</tbody>
</table>
<p>This methods returns the return value of <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.is_connected()</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.receive">
<code class="descname">receive</code><span class="sig-paren">(</span><em>service_id</em>, <em>data_id</em>, <em>timeout=1</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.receive" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>service_id</strong> (<em>int</em>) The Service-ID for the message. See class definitions starting with <code class="docutils literal notranslate"><span class="pre">SID_</span></code>.</li>
<li><strong>data_id</strong> (<em>int</em>) The Data-ID for the message.</li>
<li><strong>timeout</strong> (<em>float</em>) The timeout for receiving.</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The received data storage object or None, if no data was received.</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last"><a class="reference internal" href="#socket_protocol.data_storage" title="socket_protocol.data_storage">data_storage</a></p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.reconnect">
<code class="descname">reconnect</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.reconnect" title="Permalink to this definition"></a></dt>
<dd><p>This methods initiates a reconnect by calling <code class="xref py py-func docutils literal notranslate"><span class="pre">comm_instance.reconnect()</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.register_callback">
<code class="descname">register_callback</code><span class="sig-paren">(</span><em>service_id</em>, <em>data_id</em>, <em>callback</em>, <em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.register_callback" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>service_id</strong> (<em>int</em>) The Service-ID for the message. See class definitions starting with <code class="docutils literal notranslate"><span class="pre">SID_</span></code>.</li>
<li><strong>data_id</strong> (<em>int</em>) The Data-ID for the message.</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">True, if registration was successfull; False, if registration failed (e.g. existance of a callback for this configuration)</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">bool</p>
</td>
</tr>
</tbody>
</table>
<p>This method registers a callback for the given parameters. Givin <code class="docutils literal notranslate"><span class="pre">None</span></code> means, that all Service-IDs or all Data-IDs are used.
If a message hitting these parameters has been received, the callback will be executed.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The <code class="xref py py-func docutils literal notranslate"><span class="pre">callback()</span></code> is priorised in the following order:</p>
<ul class="last simple">
<li>Callbacks with defined Service-ID and Data-ID.</li>
<li>Callbacks with a defined Data-ID.</li>
<li>Callbacks with a defined Service-ID.</li>
<li>Unspecific Callbacks</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The <code class="xref py py-func docutils literal notranslate"><span class="pre">callback()</span></code> is executed with these arguments:</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">param msg:</th><td class="field-body">A <a class="reference internal" href="#socket_protocol.data_storage" title="socket_protocol.data_storage"><code class="xref py py-class docutils literal notranslate"><span class="pre">data_storage</span></code></a> object containing all message information.</td>
</tr>
<tr class="field-even field"><th class="field-name">returns:</th><td class="field-body">(<code class="xref py py-const docutils literal notranslate"><span class="pre">status</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">response_data</span></code>)</td>
</tr>
</tbody>
</table>
<ul class="last simple">
<li><code class="xref py py-const docutils literal notranslate"><span class="pre">status</span></code>: A status as defined as a constant of this class <code class="xref py py-const docutils literal notranslate"><span class="pre">STA_*</span></code> to be used as status for the response.</li>
<li><code class="xref py py-const docutils literal notranslate"><span class="pre">response_data</span></code>: A JSON iterable object to be used as data for the response.</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Only callbacks defined in <a class="reference internal" href="#socket_protocol.pure_json_protocol.SID__RESPONSE_DICT" title="socket_protocol.pure_json_protocol.SID__RESPONSE_DICT"><code class="xref py py-const docutils literal notranslate"><span class="pre">pure_json_protocol.SID__RESPONSE_DICT</span></code></a> will send a response, using a Service-ID given in the dict and the same Data-ID to the client.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="socket_protocol.pure_json_protocol.send">
<code class="descname">send</code><span class="sig-paren">(</span><em>service_id</em>, <em>data_id</em>, <em>data</em>, <em>status=0</em>, <em>timeout=2</em>, <em>log_lvl=20</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.pure_json_protocol.send" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>service_id</strong> (<em>int</em>) The Service-ID for the message. See class definitions starting with <code class="docutils literal notranslate"><span class="pre">SERVICE_</span></code>.</li>
<li><strong>data_id</strong> (<em>int</em>) The Data-ID for the message.</li>
<li><strong>data</strong> (<em>str</em>) The data to be transfered. The data needs to be json compatible.</li>
<li><strong>status</strong> (<em>int</em>) The Status for the message. All requests should have <code class="docutils literal notranslate"><span class="pre">STATUS_OKAY</span></code>.</li>
<li><strong>timeout</strong> (<em>float</em>) The timeout for sending data (e.g. time to establish new connection).</li>
<li><strong>rx_log_lvl</strong> (<em>int</em>) The log level to log outgoing TX-data</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">True if data had been sent, otherwise False.</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">bool</p>
</td>
</tr>
</tbody>
</table>
<p>This methods sends out a message with the given content.</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="socket_protocol.struct_json_protocol">
<em class="property">class </em><code class="descclassname">socket_protocol.</code><code class="descname">struct_json_protocol</code><span class="sig-paren">(</span><em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.struct_json_protocol" title="Permalink to this definition"></a></dt>
<dd><p>This Class has the same functionality like <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>. The message length is less than for <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>, but the functionality and compatibility is reduced.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a> is recommended.</p>
</div>
</dd></dl>
</div>
<div class="toctree-wrapper compound">
</div>
</div>
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
</ul>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2021, Dirk Alders
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

BIN
_docs_/objects.inv Normal file

Binary file not shown.

216
_docs_/py-modindex.html Normal file
View File

@ -0,0 +1,216 @@
<!DOCTYPE html>
<html class="writer-html4" lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Module Index &mdash; socket_protocol documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<script type="text/javascript">
DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
</script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home" alt="Documentation Home"> socket_protocol
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"></div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">socket_protocol</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Python Module Index</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-s"><strong>s</strong></a>
</div>
<table class="indextable modindextable">
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-s"><td></td><td>
<strong>s</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="index.html#module-socket_protocol"><code class="xref">socket_protocol</code></a></td><td>
<em></em></td></tr>
</table>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2021, Dirk Alders
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

214
_docs_/search.html Normal file
View File

@ -0,0 +1,214 @@
<!DOCTYPE html>
<html class="writer-html4" lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search &mdash; socket_protocol documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home" alt="Documentation Home"> socket_protocol
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="#" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"></div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">socket_protocol</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Search</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<noscript>
<div id="fallback" class="admonition warning">
<p class="last">
Please activate JavaScript to enable the search functionality.
</p>
</div>
</noscript>
<div id="search-results">
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2021, Dirk Alders
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
</body>
</html>

1
_docs_/searchindex.js Normal file
View File

@ -0,0 +1 @@
Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:55},filenames:["index.rst"],objects:{"":{socket_protocol:[0,0,0,"-"]},"socket_protocol.data_storage":{get_data:[0,2,1,""],get_data_id:[0,2,1,""],get_service_id:[0,2,1,""],get_status:[0,2,1,""]},"socket_protocol.pure_json_protocol":{AUTH_STATE_KEY_TRANSFERRED:[0,3,1,""],AUTH_STATE_SEED_REQUESTED:[0,3,1,""],AUTH_STATE_SEED_TRANSFERRED:[0,3,1,""],AUTH_STATE_TRUSTED_CLIENT:[0,3,1,""],AUTH_STATE_UNKNOWN_CLIENT:[0,3,1,""],AUTH_STATE__NAMES:[0,3,1,""],SID_AUTH_KEY_CHECK_REQUEST:[0,3,1,""],SID_AUTH_KEY_CHECK_RESPONSE:[0,3,1,""],SID_AUTH_KEY_REQUEST:[0,3,1,""],SID_AUTH_SEED_REQUEST:[0,3,1,""],SID_CHANNEL_NAME_REQUEST:[0,3,1,""],SID_CHANNEL_NAME_RESPONSE:[0,3,1,""],SID_EXECUTE_REQUEST:[0,3,1,""],SID_EXECUTE_RESPONSE:[0,3,1,""],SID_READ_REQUEST:[0,3,1,""],SID_READ_RESPONSE:[0,3,1,""],SID_WRITE_REQUEST:[0,3,1,""],SID_WRITE_RESPONSE:[0,3,1,""],SID__NO_AUTH_LIST:[0,3,1,""],SID__RESPONSE_DICT:[0,3,1,""],STATUS_AUTH_REQUIRED:[0,3,1,""],STATUS_BUFFERING_UNHANDLED_REQUEST:[0,3,1,""],STATUS_CHECKSUM_ERROR:[0,3,1,""],STATUS_OKAY:[0,3,1,""],STATUS_OPERATION_NOT_PERMITTED:[0,3,1,""],STATUS_SERVICE_OR_DATA_UNKNOWN:[0,3,1,""],STATUS__NAMES:[0,3,1,""],authentificate:[0,2,1,""],check_authentification_state:[0,2,1,""],connection_established:[0,2,1,""],is_connected:[0,2,1,""],receive:[0,2,1,""],reconnect:[0,2,1,""],register_callback:[0,2,1,""],send:[0,2,1,""]},socket_protocol:{data_storage:[0,1,1,""],pure_json_protocol:[0,1,1,""],struct_json_protocol:[0,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute"},terms:{"class":0,"default":0,"float":0,"function":0,"int":0,"new":0,"return":0,"true":0,IDs:0,The:0,after:0,alder:0,all:0,also:0,ani:0,arg:0,argument:0,auth_state__nam:0,auth_state_key_transf:0,auth_state_seed_request:0,auth_state_seed_transf:0,auth_state_trusted_cli:0,auth_state_unknown_cli:0,authentif:0,authentification_feedback:0,authetif:0,author:0,auto_auth:0,automat:0,avail:0,been:0,binascii:0,bool:0,both:0,buffer:0,call:0,callback:0,channel:0,channel_nam:0,check:0,check_authentification_st:0,checksum:0,client:0,comm_inst:0,commun:0,compat:0,configur:0,connect:0,connection_establish:0,constant:0,contain:0,content:0,creat:0,data:0,data_id:0,data_storag:0,defin:0,definit:0,deprec:0,descript:0,design:0,dict:0,dictionari:0,differ:0,directli:0,dirk:0,disconnect:0,enabl:0,error:0,establish:0,exchang:0,execut:0,exist:0,fail:0,fals:0,follow:0,get:0,get_data:0,get_data_id:0,get_service_id:0,get_statu:0,given:0,givin:0,had:0,has:0,have:0,here:0,hexlifi:0,hit:0,identifi:0,incl:0,index:0,inform:0,init_channel_nam:0,initi:0,initialis:0,instanc:0,interfac:0,is_client:0,is_connect:0,issu:0,iter:0,json:0,kei:0,kwarg:0,least:0,length:0,less:0,level:0,like:0,list:0,log:0,log_lvl:0,manual:0,mean:0,messag:0,method:0,mockeri:0,modul:0,mount:0,msg:0,name:0,need:0,none:0,object:0,okai:0,old:0,onli:0,oper:0,optin:0,option:0,order:0,otherwis:0,out:0,outgo:0,over:0,page:0,param:0,paramet:0,permit:0,point:0,previou:0,prioris:0,process:0,pure_json_protocol:0,read:0,read_request:0,read_respons:0,reason:0,receiv:0,recommend:0,reconnect:0,reduc:0,regist:0,register_callback:0,register_connect_callback:0,register_disconnect_callback:0,registr:0,relev:0,request:0,requir:0,respons:0,response_data:0,rx_log_lvl:0,same:0,search:0,secret:0,see:0,seed:0,send:0,sent:0,server:0,servic:0,service_:0,service_id:0,set:0,should:0,sid:0,sid_:0,sid__no_auth_list:0,sid__response_dict:0,sid_auth_key_check_request:0,sid_auth_key_check_respons:0,sid_auth_key_request:0,sid_auth_seed_request:0,sid_channel_name_request:0,sid_channel_name_respons:0,sid_execute_request:0,sid_execute_respons:0,sid_read_request:0,sid_read_respons:0,sid_write_request:0,sid_write_respons:0,side:0,sta_:0,start:0,state:0,statu:0,status__nam:0,status_auth_requir:0,status_buffering_unhandled_request:0,status_checksum_error:0,status_okai:0,status_operation_not_permit:0,status_service_or_data_unknown:0,storag:0,str:0,struct_json_protocol:0,submodul:0,successful:0,sudo:0,support:0,taken:0,than:0,thei:0,thi:0,time:0,timeout:0,transfer:0,trust:0,type:0,unhandl:0,unittest:0,unknown:0,unspecif:0,urandom:0,usag:0,use:0,used:0,using:0,valu:0,via:0,warn:0,which:0,without:0,write:0,write_request:0,write_respons:0,you:0},titles:["Welcome to socket_protocol\u2019s documentation!"],titleterms:{document:0,indic:0,protocol:0,socket:0,socket_protocol:0,tabl:0,welcom:0}})