class BaseTypes(object):
def __init__(self, type, elements=0):
base_types = {'u8': '>B',
+ 'string': '>s',
'u16': '>H',
'u32': '>I',
'i32': '>i',
'bool': '>?',
'header': '>HI'}
- if elements > 0 and type == 'u8':
+ if elements > 0 and (type == 'u8' or type == 'string'):
self.packer = struct.Struct('>%ss' % elements)
else:
self.packer = struct.Struct(base_types[type])
self.size = self.packer.size
- logger.debug('Adding {} with format: {}'
- .format(type, base_types[type]))
def pack(self, data, kwargs=None):
if not data: # Default to zero if not specified
return self.packer.unpack_from(data, offset)[0], self.packer.size
+class String(object):
+ def __init__(self):
+ self.name = 'string'
+ self.size = 1
+ self.length_field_packer = BaseTypes('u32')
+
+ def pack(self, list, kwargs=None):
+ if not list:
+ return self.length_field_packer.pack(0) + b""
+ return self.length_field_packer.pack(len(list)) + list.encode('utf8')
+
+ def unpack(self, data, offset=0, result=None, ntc=False):
+ length, length_field_size = self.length_field_packer.unpack(data,
+ offset)
+ if length == 0:
+ return b'', 0
+ p = BaseTypes('u8', length)
+ x, size = p.unpack(data, offset + length_field_size)
+ x2 = x.split(b'\0',1)[0]
+ return (x2.decode('utf8'), size + length_field_size)
+
+
types = {'u8': BaseTypes('u8'), 'u16': BaseTypes('u16'),
'u32': BaseTypes('u32'), 'i32': BaseTypes('i32'),
'u64': BaseTypes('u64'), 'f64': BaseTypes('f64'),
- 'bool': BaseTypes('bool')}
+ 'bool': BaseTypes('bool'), 'string': String()}
def vpp_get_type(name):
self.num = num
self.packer = BaseTypes(field_type, num)
self.size = self.packer.size
+ self.field_type = field_type
def pack(self, data, kwargs=None):
"""Packs a fixed length bytestring. Left-pads with zeros
'Invalid array length for "{}" got {}'
' expected {}'
.format(self.name, len(data[offset:]), self.num))
+ if self.field_type == 'string':
+ s = self.packer.unpack(data, offset)
+ s2 = s[0].split(b'\0', 1)[0]
+ return (s2.decode('utf-8'), self.num)
return self.packer.unpack(data, offset)
class VLAList(object):
def __init__(self, name, field_type, len_field_name, index):
self.name = name
+ self.field_type = field_type
self.index = index
self.packer = types[field_type]
self.size = self.packer.size
b = bytes()
# u8 array
+
if self.packer.size == 1:
return bytearray(list)
e_hash[ename] = evalue
self.enum = IntEnum(name, e_hash)
types[name] = self
- logger.debug('Adding enum {}'.format(name))
def __getattr__(self, name):
return self.enum[name]
types[name] = self
self.tuple = collections.namedtuple(name, fields, rename=True)
- logger.debug('Adding union {}'.format(name))
# Union of variable length?
def pack(self, data, kwargs=None):
if list_elements == 0:
p = VLAList_legacy(f_name, f_type)
self.packers.append(p)
- elif f_type == 'u8':
+ elif f_type == 'u8' or f_type == 'string':
p = FixedList_u8(f_name, f_type, list_elements)
self.packers.append(p)
size += p.size
self.packers.append(p)
size += p.size
elif len(f) == 4: # Variable length list
- # Find index of length field
- length_index = self.fields.index(f[3])
- p = VLAList(f_name, f_type, f[3], length_index)
- self.packers.append(p)
+ length_index = self.fields.index(f[3])
+ p = VLAList(f_name, f_type, f[3], length_index)
+ self.packers.append(p)
else:
self.packers.append(types[f_type])
size += types[f_type].size
self.size = size
self.tuple = collections.namedtuple(name, self.fields, rename=True)
types[name] = self
- logger.debug('Adding type {}'.format(name))
def pack(self, data, kwargs=None):
if not kwargs: