Completed
Push — master ( c396a1...0e306d )
by Fabio
03:31
created

Base64CoreSerializer.decode()   A

Complexity

Conditions 4

Size

Total Lines 9
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 9
rs 9.95
c 0
b 0
f 0
cc 4
nop 3
1
# -*- coding: utf-8 -*-
2
3
from __future__ import absolute_import
4
5
from benedict.serializers.abstract import AbstractSerializer
6
from benedict.utils import type_util
7
8
try:
9
    # python 3
10
    from urllib.parse import unquote
11
except ImportError:
12
    # python 2
13
    from urllib import unquote
14
15
import base64
16
17
18
class Base64CoreSerializer(AbstractSerializer):
19
20
    def __init__(self):
21
        super(Base64CoreSerializer, self).__init__()
22
23
    def _fix_url_encoding_and_padding(self, s):
24
        # fix urlencoded chars
25
        s = unquote(s)
26
        # fix padding
27
        m = len(s) % 4
28
        if m != 0:
29
            s += '=' * (4 - m)
30
        return s
31
32
    def decode(self, s, **kwargs):
33
        value = self._fix_url_encoding_and_padding(s)
34
        encoding = kwargs.pop('encoding', 'utf-8')
35
        if encoding:
36
            value = value.encode(encoding)
37
        value = base64.b64decode(value)
38
        if encoding and type_util.is_string(value):
39
            return value.decode(encoding)
40
        return value
41
42
    def encode(self, d, **kwargs):
43
        value = d
44
        encoding = kwargs.pop('encoding', 'utf-8')
45
        if encoding and type_util.is_string(value):
46
            value = value.encode(encoding)
47
        value = base64.b64encode(value)
48
        if encoding:
49
            value = value.decode(encoding)
50
        return value
51
52
53
class Base64Serializer(Base64CoreSerializer):
54
55
    def __init__(self):
56
        super(Base64Serializer, self).__init__()
57
58
    def _pop_options(self, options):
59
        encoding = options.pop('encoding', 'utf-8')
60
        subformat = options.pop('subformat', None)
61
        from benedict.serializers import get_serializer_by_format
62
        serializer = get_serializer_by_format(subformat)
63
        return (serializer, encoding, )
64
65
    def decode(self, s, **kwargs):
66
        serializer, encoding = self._pop_options(kwargs)
67
        value = super(Base64Serializer, self).decode(s, encoding=encoding)
68
        if serializer:
69
            value = serializer.decode(value, **kwargs)
70
        return value
71
72
    def encode(self, d, **kwargs):
73
        serializer, encoding = self._pop_options(kwargs)
74
        value = d
75
        if serializer:
76
            value = serializer.encode(value, **kwargs)
77
        value = super(Base64Serializer, self).encode(value, encoding=encoding)
78
        return value
79