API: Use string type instead of u8.
[vpp.git] / src / vpp-api / python / vpp_papi / vpp_serializer.py
index 5dce03b..418c024 100644 (file)
@@ -59,6 +59,7 @@ def conversion_unpacker(data, field_type):
 class BaseTypes(object):
     def __init__(self, type, elements=0):
         base_types = {'u8': '>B',
+                      'string': '>s',
                       'u16': '>H',
                       'u32': '>I',
                       'i32': '>i',
@@ -67,13 +68,11 @@ class BaseTypes(object):
                       '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
@@ -84,10 +83,32 @@ class BaseTypes(object):
         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):
@@ -107,6 +128,7 @@ class FixedList_u8(object):
         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
@@ -128,6 +150,10 @@ class FixedList_u8(object):
                 '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)
 
 
@@ -164,6 +190,7 @@ class FixedList(object):
 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
@@ -179,6 +206,7 @@ class VLAList(object):
         b = bytes()
 
         # u8 array
+
         if self.packer.size == 1:
             return bytearray(list)
 
@@ -249,7 +277,6 @@ class VPPEnumType(object):
             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]
@@ -290,7 +317,6 @@ class VPPUnionType(object):
 
         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):
@@ -381,7 +407,7 @@ class VPPType(object):
                 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
@@ -390,10 +416,9 @@ class VPPType(object):
                     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
@@ -401,7 +426,6 @@ class VPPType(object):
         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: