2022-10-14 14:53:06 +00:00
|
|
|
import base64
|
2022-02-17 22:54:30 +00:00
|
|
|
from urllib.parse import unquote
|
2020-01-20 15:19:53 +00:00
|
|
|
|
2022-10-14 14:53:06 +00:00
|
|
|
from benedict.serializers.abstract import AbstractSerializer
|
|
|
|
from benedict.utils import type_util
|
2020-01-20 15:19:53 +00:00
|
|
|
|
|
|
|
|
2020-02-20 16:15:14 +00:00
|
|
|
class Base64CoreSerializer(AbstractSerializer):
|
2022-02-13 10:56:44 +00:00
|
|
|
"""
|
|
|
|
This class describes a base64 core serializer.
|
|
|
|
"""
|
|
|
|
|
2020-02-20 16:15:14 +00:00
|
|
|
def __init__(self):
|
2022-12-31 17:33:20 +00:00
|
|
|
super().__init__(
|
2022-10-05 14:43:46 +00:00
|
|
|
extensions=[
|
|
|
|
"b64",
|
|
|
|
"base64",
|
|
|
|
],
|
|
|
|
)
|
2020-02-20 16:15:14 +00:00
|
|
|
|
|
|
|
def _fix_url_encoding_and_padding(self, s):
|
2020-01-20 15:19:53 +00:00
|
|
|
# fix urlencoded chars
|
|
|
|
s = unquote(s)
|
|
|
|
# fix padding
|
|
|
|
m = len(s) % 4
|
|
|
|
if m != 0:
|
2022-02-13 10:35:43 +00:00
|
|
|
s += "=" * (4 - m)
|
2020-02-20 16:15:14 +00:00
|
|
|
return s
|
|
|
|
|
|
|
|
def decode(self, s, **kwargs):
|
|
|
|
value = self._fix_url_encoding_and_padding(s)
|
2022-02-13 10:35:43 +00:00
|
|
|
encoding = kwargs.pop("encoding", "utf-8")
|
2020-01-20 15:19:53 +00:00
|
|
|
if encoding:
|
2020-02-20 16:15:14 +00:00
|
|
|
value = value.encode(encoding)
|
|
|
|
value = base64.b64decode(value)
|
2020-02-21 12:54:33 +00:00
|
|
|
if encoding:
|
2020-02-20 16:15:14 +00:00
|
|
|
return value.decode(encoding)
|
|
|
|
return value
|
|
|
|
|
|
|
|
def encode(self, d, **kwargs):
|
|
|
|
value = d
|
2022-02-13 10:35:43 +00:00
|
|
|
encoding = kwargs.pop("encoding", "utf-8")
|
2020-02-20 16:15:14 +00:00
|
|
|
if encoding and type_util.is_string(value):
|
|
|
|
value = value.encode(encoding)
|
|
|
|
value = base64.b64encode(value)
|
|
|
|
if encoding:
|
|
|
|
value = value.decode(encoding)
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
class Base64Serializer(Base64CoreSerializer):
|
|
|
|
def __init__(self):
|
2022-12-31 17:33:20 +00:00
|
|
|
super().__init__()
|
2020-02-20 16:15:14 +00:00
|
|
|
|
|
|
|
def _pop_options(self, options):
|
2022-02-13 10:35:43 +00:00
|
|
|
encoding = options.pop("encoding", "utf-8")
|
|
|
|
subformat = options.pop("subformat", None)
|
2020-02-20 16:15:14 +00:00
|
|
|
from benedict.serializers import get_serializer_by_format
|
2021-10-12 12:27:35 +00:00
|
|
|
|
2020-02-20 16:15:14 +00:00
|
|
|
serializer = get_serializer_by_format(subformat)
|
2021-10-12 12:27:35 +00:00
|
|
|
return (serializer, encoding)
|
2020-02-20 16:15:14 +00:00
|
|
|
|
|
|
|
def decode(self, s, **kwargs):
|
|
|
|
serializer, encoding = self._pop_options(kwargs)
|
2022-12-31 17:33:20 +00:00
|
|
|
value = super().decode(s, encoding=encoding)
|
2020-02-20 16:15:14 +00:00
|
|
|
if serializer:
|
|
|
|
value = serializer.decode(value, **kwargs)
|
|
|
|
return value
|
|
|
|
|
|
|
|
def encode(self, d, **kwargs):
|
|
|
|
serializer, encoding = self._pop_options(kwargs)
|
|
|
|
value = d
|
|
|
|
if serializer:
|
|
|
|
value = serializer.encode(value, **kwargs)
|
2022-12-31 17:33:20 +00:00
|
|
|
value = super().encode(value, encoding=encoding)
|
2020-02-20 16:15:14 +00:00
|
|
|
return value
|