backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / lib / type_desc.py
1 # Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #    http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 import base64
18
19 import six
20
21 from ryu.lib import addrconv
22
23
24 class TypeDescr(object):
25     pass
26
27
28 class IntDescr(TypeDescr):
29     def __init__(self, size):
30         self.size = size
31
32     def to_user(self, binary):
33         i = 0
34         for _ in range(self.size):
35             c = binary[:1]
36             i = i * 256 + ord(c)
37             binary = binary[1:]
38         return i
39
40     def from_user(self, i):
41         binary = b''
42         for _ in range(self.size):
43             binary = six.int2byte(i & 255) + binary
44             i //= 256
45         return binary
46
47
48 Int1 = IntDescr(1)
49 Int2 = IntDescr(2)
50 Int3 = IntDescr(3)
51 Int4 = IntDescr(4)
52 Int8 = IntDescr(8)
53 Int9 = IntDescr(9)
54 Int16 = IntDescr(16)
55
56
57 def _split_str(s, n):
58     """
59     split string into list of strings by specified number.
60     """
61     length = len(s)
62     return [s[i:i + n] for i in range(0, length, n)]
63
64
65 class IntDescrMlt(TypeDescr):
66     def __init__(self, length, num):
67         self.length = length
68         self.num = num
69         self.size = length * num
70
71     def to_user(self, binary):
72         assert len(binary) == self.size
73         lb = _split_str(binary, self.length)
74         li = []
75         for b in lb:
76             i = 0
77             for _ in range(self.length):
78                 c = b[:1]
79                 i = i * 256 + ord(c)
80                 b = b[1:]
81             li.append(i)
82         return tuple(li)
83
84     def from_user(self, li):
85         assert len(li) == self.num
86         binary = b''
87         for i in li:
88             b = b''
89             for _ in range(self.length):
90                 b = six.int2byte(i & 255) + b
91                 i //= 256
92             binary += b
93         return binary
94
95
96 Int4Double = IntDescrMlt(4, 2)
97
98
99 class MacAddr(TypeDescr):
100     size = 6
101     to_user = addrconv.mac.bin_to_text
102     from_user = addrconv.mac.text_to_bin
103
104
105 class IPv4Addr(TypeDescr):
106     size = 4
107     to_user = addrconv.ipv4.bin_to_text
108     from_user = addrconv.ipv4.text_to_bin
109
110
111 class IPv6Addr(TypeDescr):
112     size = 16
113     to_user = addrconv.ipv6.bin_to_text
114     from_user = addrconv.ipv6.text_to_bin
115
116
117 class UnknownType(TypeDescr):
118
119     @staticmethod
120     def to_user(data):
121         if six.PY3:
122             return base64.b64encode(data).decode('ascii')
123         else:
124             return base64.b64encode(data)
125
126     from_user = staticmethod(base64.b64decode)
127
128
129 class TypeDisp(object):
130     _TYPES = {}
131     _REV_TYPES = None
132     _UNKNOWN_TYPE = None
133
134     @classmethod
135     def register_unknown_type(cls):
136         def _register_type(subcls):
137             cls._UNKNOWN_TYPE = subcls
138             return subcls
139         return _register_type
140
141     @classmethod
142     def register_type(cls, type_):
143         cls._TYPES = cls._TYPES.copy()
144
145         def _register_type(subcls):
146             cls._TYPES[type_] = subcls
147             cls._REV_TYPES = None
148             return subcls
149         return _register_type
150
151     @classmethod
152     def _lookup_type(cls, type_):
153         try:
154             return cls._TYPES[type_]
155         except KeyError:
156             return cls._UNKNOWN_TYPE
157
158     @classmethod
159     def _rev_lookup_type(cls, targ_cls):
160         if cls._REV_TYPES is None:
161             rev = dict((v, k) for k, v in cls._TYPES.items())
162             cls._REV_TYPES = rev
163         return cls._REV_TYPES[targ_cls]