CoAP/coapthon/messages/option.py

138 lines
3.7 KiB
Python
Raw Normal View History

2018-01-23 11:31:46 +01:00
from coapthon import defines
from coapthon.utils import byte_len
__author__ = 'Giacomo Tanganelli'
class Option(object):
"""
Class to handle the CoAP Options.
"""
def __init__(self):
"""
Data structure to store options.
"""
self._number = None
self._value = None
@property
def number(self):
"""
Return the number of the option.
:return: the option number
"""
return self._number
@number.setter
def number(self, value):
"""
Set the option number.
:type value: int
:param value: the option number
"""
self._number = value
@property
def value(self):
"""
Return the option value.
:return: the option value in the correct format depending on the option
"""
if type(self._value) is None:
self._value = bytearray()
opt_type = defines.OptionRegistry.LIST[self._number].value_type
if opt_type == defines.INTEGER:
if byte_len(self._value) > 0:
return int(self._value)
else:
return defines.OptionRegistry.LIST[self._number].default
return self._value
@value.setter
def value(self, value):
"""
Set the value of the option.
:param value: the option value
"""
opt_type = defines.OptionRegistry.LIST[self._number].value_type
if opt_type == defines.INTEGER:
if type(value) is not int:
value = int(value)
if byte_len(value) == 0:
value = 0
elif opt_type == defines.STRING:
if type(value) is not str:
value = str(value)
elif opt_type == defines.OPAQUE:
if type(value) is bytes:
pass
else:
if value is not None:
value = bytes(value, "utf-8")
self._value = value
@property
def length(self):
"""
Return the value length
:rtype : int
"""
if isinstance(self._value, int):
return byte_len(self._value)
if self._value is None:
return 0
return len(self._value)
def is_safe(self):
"""
Check if the option is safe.
:rtype : bool
:return: True, if option is safe
"""
if self._number == defines.OptionRegistry.URI_HOST.number \
or self._number == defines.OptionRegistry.URI_PORT.number \
or self._number == defines.OptionRegistry.URI_PATH.number \
or self._number == defines.OptionRegistry.MAX_AGE.number \
or self._number == defines.OptionRegistry.URI_QUERY.number \
or self._number == defines.OptionRegistry.PROXY_URI.number \
or self._number == defines.OptionRegistry.PROXY_SCHEME.number:
return False
return True
@property
def name(self):
"""
Return option name.
:rtype : String
:return: the option name
"""
return defines.OptionRegistry.LIST[self._number].name
def __str__(self):
"""
Return a string representing the option
:rtype : String
:return: a message with the option name and the value
"""
return self.name + ": " + str(self.value) + "\n"
def __eq__(self, other):
"""
Return True if two option are equal
:type other: Option
:param other: the option to be compared against
:rtype : Boolean
:return: True, if option are equal
"""
return self.__dict__ == other.__dict__