def test_defaults(self):
default_type = VPPType('default_type_t',
[['u16', 'mtu', {'default': 1500, 'limit': 0}]])
+ without_default_type = VPPType('without_default_type_t',
+ [['u16', 'mtu']])
b = default_type.pack({})
self.assertEqual(len(b), 2)
-
nt, size = default_type.unpack(b)
self.assertEqual(len(b), size)
self.assertEqual(nt.mtu, 1500)
+ # distinguish between parameter 0 and parameter not passed
+ b = default_type.pack({'mtu': 0})
+ self.assertEqual(len(b), 2)
+ nt, size = default_type.unpack(b)
+ self.assertEqual(len(b), size)
+ self.assertEqual(nt.mtu, 0)
+
+ # Ensure that basetypes does not inherit default
+ b = without_default_type.pack({})
+ self.assertEqual(len(b), 2)
+ nt, size = default_type.unpack(b)
+ self.assertEqual(len(b), size)
+ self.assertEqual(nt.mtu, 0)
+
+ # default enum type
+ VPPEnumType('vl_api_enum_t', [["ADDRESS_IP4", 0],
+ ["ADDRESS_IP6", 1],
+ {"enumtype": "u32"}])
+
+ default_with_enum = VPPType('default_enum_type_t',
+ [['u16', 'mtu'], ['vl_api_enum_t',
+ 'e', {'default': 1}]])
+
+ b = default_with_enum.pack({})
+ self.assertEqual(len(b), 6)
+ nt, size = default_with_enum.unpack(b)
+ self.assertEqual(len(b), size)
+ self.assertEqual(nt.e, 1)
class TestAddType(unittest.TestCase):
self.size = self.packer.size
self.options = options
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, data, kwargs=None):
- if not data: # Default to zero if not specified
+ if data is None: # Default to zero if not specified
if self.options and 'default' in self.options:
data = self.options['default']
else:
'u64': BaseTypes('u64'), 'f64': BaseTypes('f64'),
'bool': BaseTypes('bool'), 'string': String}
+class_types = {}
def vpp_get_type(name):
try:
self.size = self.packer.size
self.field_type = field_type
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, data, kwargs=None):
"""Packs a fixed length bytestring. Left-pads with zeros
if input data is too short."""
self.name = name
self.field_type = field_type
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, list, kwargs):
if len(list) != self.num:
raise VPPSerializerValueError(
self.size = self.packer.size
self.length_field = len_field_name
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, lst, kwargs=None):
if not lst:
return b""
self.packer = types[field_type]
self.size = self.packer.size
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, list, kwargs=None):
if self.packer.size == 1:
return bytes(list)
class VPPEnumType(object):
- def __init__(self, name, msgdef):
+ def __init__(self, name, msgdef, options=None):
self.size = types['u32'].size
+ self.name = name
self.enumtype = 'u32'
+ self.msgdef = msgdef
e_hash = {}
for f in msgdef:
if type(f) is dict and 'enumtype' in f:
e_hash[ename] = evalue
self.enum = IntFlag(name, e_hash)
types[name] = self
-
- def __call__(self, args):
- self.options = args
- return self
+ class_types[name] = VPPEnumType
+ self.options = options
def __getattr__(self, name):
return self.enum[name]
__nonzero__ = __bool__
def pack(self, data, kwargs=None):
+ if data is None: # Default to zero if not specified
+ if self.options and 'default' in self.options:
+ data = self.options['default']
+ else:
+ data = 0
+
return types[self.enumtype].pack(data)
def unpack(self, data, offset=0, result=None, ntc=False):
types[name] = self
self.tuple = collections.namedtuple(name, fields, rename=True)
- def __call__(self, args):
- self.options = args
- return self
-
# Union of variable length?
def pack(self, data, kwargs=None):
if not data:
types[name] = self
self.toplevelconversion = False
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, data, kwargs=None):
if data and conversion_required(data, self.name):
try:
p = VLAList(f_name, f_type, f[3], length_index)
self.packers.append(p)
else:
- p = types[f_type](self.options)
+ # Support default for basetypes and enums
+ if 'default' in self.options:
+ try:
+ p = BaseTypes(f_type, 0, self.options)
+ except KeyError:
+ p = class_types[f_type](f_name, types[f_type].msgdef, self.options)
+ else:
+ p = types[f_type]
self.packers.append(p)
size += p.size
types[name] = self
self.toplevelconversion = False
- def __call__(self, args):
- self.options = args
- return self
-
def pack(self, data, kwargs=None):
if not kwargs:
kwargs = data