PAPI: Add support for format/unformat functions.
[vpp.git] / src / vpp-api / python / vpp_papi / vpp_format.py
1 #
2 # Copyright (c) 2018 Cisco and/or its affiliates.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15
16 from socket import inet_pton, inet_ntop, AF_INET6, AF_INET
17
18
19 class VPPFormat:
20     @staticmethod
21     def format_vl_api_ip6_prefix_t(args):
22         prefix, len = args.split('/')
23         return {'prefix': {'address': inet_pton(AF_INET6, prefix)},
24                 'len': int(len)}
25
26     @staticmethod
27     def unformat_vl_api_ip6_prefix_t(args):
28         return "{}/{}".format(inet_ntop(AF_INET6, args.prefix.address),
29                               args.len)
30
31     @staticmethod
32     def format_vl_api_ip4_prefix_t(args):
33         prefix, len = args.split('/')
34         return {'prefix': {'address': inet_pton(AF_INET, prefix)},
35                 'len': int(len)}
36
37     @staticmethod
38     def unformat_vl_api_ip4_prefix_t(args):
39         return "{}/{}".format(inet_ntop(AF_INET, args.prefix.address),
40                               args.len)
41
42     @staticmethod
43     def format_vl_api_ip6_address_t(args):
44         return {'address': inet_pton(AF_INET6, args)}
45
46     @staticmethod
47     def format_vl_api_ip4_address_t(args):
48         return {'address': inet_pton(AF_INET, args)}
49
50     @staticmethod
51     def format_vl_api_address_t(args):
52         try:
53             return {'un': {'ip6': {'address': inet_pton(AF_INET6, args)}},
54                     'af': int(1)}
55         except Exception as e:
56             return {'un': {'ip4': {'address': inet_pton(AF_INET, args)}},
57                     'af': int(0)}
58
59     @staticmethod
60     def unformat_vl_api_address_t(arg):
61         if arg.af == 1:
62             return inet_ntop(AF_INET6, arg.un.ip6.address)
63         if arg.af == 0:
64             return inet_ntop(AF_INET, arg.un.ip4.address)
65         raise
66
67     @staticmethod
68     def format_vl_api_prefix_t(args):
69         prefix, len = args.split('/')
70         return {'address': VPPFormat.format_vl_api_address_t(prefix),
71                 'address_length': int(len)}
72
73     @staticmethod
74     def unformat_vl_api_prefix_t(arg):
75         if arg.address.af == 1:
76             return "{}/{}".format(inet_ntop(AF_INET6,
77                                             arg.address.un.ip6.address),
78                                   arg.address_length)
79         if arg.address.af == 0:
80             return "{}/{}".format(inet_ntop(AF_INET,
81                                             arg.address.un.ip4.address),
82                                   arg.address_length)
83         raise
84
85     @staticmethod
86     def format_u8(args):
87         try:
88             return int(args)
89         except Exception as e:
90             return args.encode()
91
92     @staticmethod
93     def format(typename, args):
94         try:
95             return getattr(VPPFormat, 'format_' + typename)(args)
96         except AttributeError:
97             # Default
98             return (int(args))
99
100     @staticmethod
101     def unformat_bytes(args):
102         try:
103             return args.decode('utf-8')
104         except Exception as e:
105             return args
106
107     @staticmethod
108     def unformat_list(args):
109         s = '['
110         for f in args:
111             t = type(f).__name__
112             if type(f) is int:
113                 s2 = str(f)
114             else:
115                 s2 = VPPFormat.unformat_t(t, f)
116             s += '{} '.format(s2)
117         return s[:-1] + ']'
118
119     @staticmethod
120     def unformat(args):
121         s = ''
122         return VPPFormat.unformat_t(type(args).__name__, args)
123         '''
124         for i, f in enumerate(args):
125             print('F', f)
126             t = type(f).__name__
127             if type(f) is int:
128                 s2 = str(f)
129             else:
130                 s2 = VPPFormat.unformat_t(t, f)
131             s += '{} {} '.format(args._fields[i], s2)
132         return s[:-1]
133         '''
134
135     @staticmethod
136     def unformat_t(typename, args):
137         try:
138             return getattr(VPPFormat, 'unformat_' + typename)(args)
139         except AttributeError:
140             # Type without explicit override
141             return VPPFormat.unformat(args)
142
143         # Default handling
144         return args