138 lines
3.7 KiB
Python
138 lines
3.7 KiB
Python
|
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__
|