Test Failed
Pull Request — master (#603)
by
unknown
02:35
created

StatsReply._unpack_body()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.4218

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
ccs 1
cts 4
cp 0.25
rs 10
c 0
b 0
f 0
cc 1
nop 1
crap 1.4218
1
"""Response the stat request packet from the controller."""
2 1
from importlib import import_module
3
4 1
from pyof.foundation.base import GenericMessage
5 1
from pyof.foundation.basic_types import BinaryData, FixedTypeList, UBInt16
6 1
from pyof.v0x01.common.header import Header, Type
7 1
from pyof.v0x01.controller2switch.common import DescStats, StatsType
8
9 1
__all__ = ('StatsReply',)
10
11
12 1
class StatsReply(GenericMessage):
13
    """Class implements the response to the stats request."""
14
15
    #: OpenFlow :class:`~pyof.v0x01.common.header.Header`
16 1
    header = Header(message_type=Type.OFPT_STATS_REPLY)
17 1
    body_type = UBInt16(enum_ref=StatsType)
18 1
    flags = UBInt16()
19 1
    body = BinaryData()
20
21 1
    def __init__(self, xid=None, body_type=None, flags=None, body=b''):
22
        """Create a StatsReply with the optional parameters below.
23
24
        Args:
25
            xid (int): xid to be used on the message header.
26
            body_type (StatsType): One of the OFPST_* constants.
27
            flags (int): OFPSF_REQ_* flags (none yet defined).
28
            body (BinaryData): Body of the request.
29
        """
30
        super().__init__(xid)
31
        self.body_type = body_type
32
        self.flags = flags
33
        self.body = body
34
35 1
    def pack(self, value=None):
36
        """Pack a StatsReply using the object's attributes.
37
38
        This method will pack the attribute body and body_type before pack the
39
        StatsReply object, then will return this struct as a binary data.
40
41
        Returns:
42
            bytes: Binary data with StatsReply packed.
43
44
        """
45
        buff = self.body
46
        if not value:
47
            value = self.body
48
49
        if value and hasattr(value, 'pack'):
50
            self.body = BinaryData(value.pack())
51
        stats_reply_packed = super().pack()
52
53
        self.body = buff
54
        return stats_reply_packed
55
56 1
    def unpack(self, buff, offset=0):
57
        """Unpack a binary message into this object's attributes.
58
59
        Unpack the binary value *buff* and update this object attributes based
60
        on the results. It is an inplace method and it receives the binary data
61
        of the message **without the header**.
62
63
        This class' unpack method is like the :meth:`.GenericMessage.unpack`
64
        one, except for the ``body`` attribute which has its type determined
65
        by the ``body_type`` attribute.
66
67
        Args:
68
            buff (bytes): Binary data package to be unpacked, without the
69
                header.
70
        """
71
        super().unpack(buff[offset:])
72
        self._unpack_body()
73
74 1
    def _unpack_body(self):
75
        """Unpack `body` replace it by the result."""
76
        obj = self._get_body_instance()
77
        obj.unpack(self.body.value)
78
        self.body = obj
79
80 1
    def _get_body_instance(self):
81
        """Return the body instance."""
82
        pyof_class = self._get_body_class()
83
84
        if pyof_class is None:
85
            return BinaryData(b'')
86
        if pyof_class is DescStats:
87
            return pyof_class()
88
89
        return FixedTypeList(pyof_class=pyof_class)
90
91 1 View Code Duplication
    def _get_body_class(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
92
        if isinstance(self.body_type, (int, UBInt16)):
93
            self.body_type = self.body_type.enum_ref(self.body_type.value)
94
95
        body_name = self.body_type.name.replace('OFPST_', '').title()
96
        module = import_module('pyof.v0x01.controller2switch.common')
97
98
        for class_name in module.__all__:
99
            if 'Request' not in class_name and body_name in class_name:
100
                return getattr(module, class_name)
101
        return None
102