python-benedict/benedict/serializers/base64.py

77 lines
2.1 KiB
Python
Raw Normal View History

import base64
from urllib.parse import unquote
from benedict.serializers.abstract import AbstractSerializer
from benedict.utils import type_util
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):
super().__init__(
extensions=[
"b64",
"base64",
],
)
2020-02-20 16:15:14 +00:00
def _fix_url_encoding_and_padding(self, s):
# 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")
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):
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)
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)
value = super().encode(value, encoding=encoding)
2020-02-20 16:15:14 +00:00
return value