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