Completed
Push — master ( 79c35a...3e3ee6 )
by Marek
16s queued 14s
created

SetOfEncoder.encodeValue()   C

Complexity

Conditions 10

Size

Total Lines 34
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 28
nop 5
dl 0
loc 34
rs 5.9999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like pyasn1.codec.cer.encoder.SetOfEncoder.encodeValue() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# CER encoder
2
from pyasn1.type import univ
3
from pyasn1.codec.ber import encoder
4
from pyasn1.compat.octets import int2oct, null
5
6
class BooleanEncoder(encoder.IntegerEncoder):
7
    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
8
        if client == 0:
9
            substrate = int2oct(0)
10
        else:
11
            substrate = int2oct(255)
12
        return substrate, 0
13
14
class BitStringEncoder(encoder.BitStringEncoder):
15
    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
16
        return encoder.BitStringEncoder.encodeValue(
17
            self, encodeFun, client, defMode, 1000
18
            )
19
20
class OctetStringEncoder(encoder.OctetStringEncoder):
21
    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
22
        return encoder.OctetStringEncoder.encodeValue(
23
            self, encodeFun, client, defMode, 1000
24
            )
25
26
# specialized RealEncoder here
27
# specialized GeneralStringEncoder here
28
# specialized GeneralizedTimeEncoder here
29
# specialized UTCTimeEncoder here
30
31
class SetOfEncoder(encoder.SequenceOfEncoder):
32
    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
33
        if isinstance(client, univ.SequenceAndSetBase):
34
            client.setDefaultComponents()
35
        client.verifySizeSpec()
36
        substrate = null; idx = len(client)
37
        # This is certainly a hack but how else do I distinguish SetOf
38
        # from Set if they have the same tags&constraints?
39
        if isinstance(client, univ.SequenceAndSetBase):
40
            # Set
41
            comps = []
42
            while idx > 0:
43
                idx = idx - 1
44
                if client[idx] is None:  # Optional component
45
                    continue
46
                if client.getDefaultComponentByPosition(idx) == client[idx]:
47
                    continue
48
                comps.append(client[idx])
49
            comps.sort(key=lambda x: isinstance(x, univ.Choice) and \
50
                                     x.getMinTagSet() or x.getTagSet())
51
            for c in comps:
52
                substrate += encodeFun(c, defMode, maxChunkSize)
53
        else:
54
            # SetOf
55
            compSubs = []
56
            while idx > 0:
57
                idx = idx - 1
58
                compSubs.append(
59
                    encodeFun(client[idx], defMode, maxChunkSize)
60
                    )
61
            compSubs.sort()  # perhaps padding's not needed
62
            substrate = null
63
            for compSub in compSubs:
64
                substrate += compSub
65
        return substrate, 1
66
67
tagMap = encoder.tagMap.copy()
68
tagMap.update({
69
    univ.Boolean.tagSet: BooleanEncoder(),
70
    univ.BitString.tagSet: BitStringEncoder(),
71
    univ.OctetString.tagSet: OctetStringEncoder(),
72
    univ.SetOf().tagSet: SetOfEncoder()  # conflcts with Set
73
    })
74
75
typeMap = encoder.typeMap.copy()
76
typeMap.update({
77
    univ.Set.typeId: SetOfEncoder(),
78
    univ.SetOf.typeId: SetOfEncoder()
79
    })
80
81
class Encoder(encoder.Encoder):
82
    def __call__(self, client, defMode=0, maxChunkSize=0):
83
        return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
84
85
encode = Encoder(tagMap, typeMap)
86
87
# EncoderFactory queries class instance and builds a map of tags -> encoders
88