python-benedict/benedict/serializers/base64.py

77 lines
2.1 KiB
Python

import base64
from urllib.parse import unquote
from benedict.serializers.abstract import AbstractSerializer
from benedict.utils import type_util
class Base64CoreSerializer(AbstractSerializer):
"""
This class describes a base64 core serializer.
"""
def __init__(self):
super().__init__(
extensions=[
"b64",
"base64",
],
)
def _fix_url_encoding_and_padding(self, s):
# fix urlencoded chars
s = unquote(s)
# fix padding
m = len(s) % 4
if m != 0:
s += "=" * (4 - m)
return s
def decode(self, s, **kwargs):
value = self._fix_url_encoding_and_padding(s)
encoding = kwargs.pop("encoding", "utf-8")
if encoding:
value = value.encode(encoding)
value = base64.b64decode(value)
if encoding:
return value.decode(encoding)
return value
def encode(self, d, **kwargs):
value = d
encoding = kwargs.pop("encoding", "utf-8")
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__()
def _pop_options(self, options):
encoding = options.pop("encoding", "utf-8")
subformat = options.pop("subformat", None)
from benedict.serializers import get_serializer_by_format
serializer = get_serializer_by_format(subformat)
return (serializer, encoding)
def decode(self, s, **kwargs):
serializer, encoding = self._pop_options(kwargs)
value = super().decode(s, encoding=encoding)
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)
return value