diff options
author | Ole Troan <ot@cisco.com> | 2018-10-22 09:30:26 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-10-22 11:52:20 +0000 |
commit | 31555a3475a37195938378217a635b3451e449de (patch) | |
tree | b330d858fe6d8f1a0b236b608e8970d5114e015c /src/vpp-api/python/vpp_papi/vpp_format.py | |
parent | 430634c457da5dd04f481da0118bab581ace732e (diff) |
PAPI: Add support for format/unformat functions.
With the introduction of new types, like vl_api_address_t
it is now possible to call a message using one of those
functions with a string representation. E.g. for an IP address
ip_add_address(address="1.1.1.1/24")
The language wrapper will automatically convert the string
into the vl_api_address_t representation. Currently
the caller must do the reverse conversion from the returned
named tuple with the unformat function.
rv = get_address_on_interface(sw_if_index=1)
print(VPPFormat.unformat(rv.address))
Change-Id: Ic872b4560b2f4836255bd5260289bfa38c75bc5d
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp-api/python/vpp_papi/vpp_format.py')
-rw-r--r-- | src/vpp-api/python/vpp_papi/vpp_format.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/vpp-api/python/vpp_papi/vpp_format.py b/src/vpp-api/python/vpp_papi/vpp_format.py new file mode 100644 index 00000000000..b1800d87dd1 --- /dev/null +++ b/src/vpp-api/python/vpp_papi/vpp_format.py @@ -0,0 +1,144 @@ +# +# Copyright (c) 2018 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from socket import inet_pton, inet_ntop, AF_INET6, AF_INET + + +class VPPFormat: + @staticmethod + def format_vl_api_ip6_prefix_t(args): + prefix, len = args.split('/') + return {'prefix': {'address': inet_pton(AF_INET6, prefix)}, + 'len': int(len)} + + @staticmethod + def unformat_vl_api_ip6_prefix_t(args): + return "{}/{}".format(inet_ntop(AF_INET6, args.prefix.address), + args.len) + + @staticmethod + def format_vl_api_ip4_prefix_t(args): + prefix, len = args.split('/') + return {'prefix': {'address': inet_pton(AF_INET, prefix)}, + 'len': int(len)} + + @staticmethod + def unformat_vl_api_ip4_prefix_t(args): + return "{}/{}".format(inet_ntop(AF_INET, args.prefix.address), + args.len) + + @staticmethod + def format_vl_api_ip6_address_t(args): + return {'address': inet_pton(AF_INET6, args)} + + @staticmethod + def format_vl_api_ip4_address_t(args): + return {'address': inet_pton(AF_INET, args)} + + @staticmethod + def format_vl_api_address_t(args): + try: + return {'un': {'ip6': {'address': inet_pton(AF_INET6, args)}}, + 'af': int(1)} + except Exception as e: + return {'un': {'ip4': {'address': inet_pton(AF_INET, args)}}, + 'af': int(0)} + + @staticmethod + def unformat_vl_api_address_t(arg): + if arg.af == 1: + return inet_ntop(AF_INET6, arg.un.ip6.address) + if arg.af == 0: + return inet_ntop(AF_INET, arg.un.ip4.address) + raise + + @staticmethod + def format_vl_api_prefix_t(args): + prefix, len = args.split('/') + return {'address': VPPFormat.format_vl_api_address_t(prefix), + 'address_length': int(len)} + + @staticmethod + def unformat_vl_api_prefix_t(arg): + if arg.address.af == 1: + return "{}/{}".format(inet_ntop(AF_INET6, + arg.address.un.ip6.address), + arg.address_length) + if arg.address.af == 0: + return "{}/{}".format(inet_ntop(AF_INET, + arg.address.un.ip4.address), + arg.address_length) + raise + + @staticmethod + def format_u8(args): + try: + return int(args) + except Exception as e: + return args.encode() + + @staticmethod + def format(typename, args): + try: + return getattr(VPPFormat, 'format_' + typename)(args) + except AttributeError: + # Default + return (int(args)) + + @staticmethod + def unformat_bytes(args): + try: + return args.decode('utf-8') + except Exception as e: + return args + + @staticmethod + def unformat_list(args): + s = '[' + for f in args: + t = type(f).__name__ + if type(f) is int: + s2 = str(f) + else: + s2 = VPPFormat.unformat_t(t, f) + s += '{} '.format(s2) + return s[:-1] + ']' + + @staticmethod + def unformat(args): + s = '' + return VPPFormat.unformat_t(type(args).__name__, args) + ''' + for i, f in enumerate(args): + print('F', f) + t = type(f).__name__ + if type(f) is int: + s2 = str(f) + else: + s2 = VPPFormat.unformat_t(t, f) + s += '{} {} '.format(args._fields[i], s2) + return s[:-1] + ''' + + @staticmethod + def unformat_t(typename, args): + try: + return getattr(VPPFormat, 'unformat_' + typename)(args) + except AttributeError: + # Type without explicit override + return VPPFormat.unformat(args) + + # Default handling + return args |