codekingpro/portable-devtools
115k
1from __future__ import annotations2 3from base64 import b64decode as builtin_decode4from base64 import b64encode as builtin_encode5from base64 import encodebytes as builtin_encodebytes6from binascii import Error as BinAsciiError7from typing import TYPE_CHECKING8 9if TYPE_CHECKING:10 from ._typing import Buffer11 12_bytes_types = (bytes, bytearray) # Types acceptable as binary data13 14 15def _get_simd_name(flags: int) -> str:16 assert flags == 017 return "fallback"18 19 20def _get_simd_path() -> int:21 return 022 23 24def _get_bytes(s: str | Buffer) -> bytes | bytearray:25 if isinstance(s, str):26 try:27 return s.encode("ascii")28 except UnicodeEncodeError:29 msg = "string argument should contain only ASCII characters"30 raise ValueError(msg) from None31 if isinstance(s, _bytes_types):32 return s33 try:34 mv = memoryview(s)35 if not mv.c_contiguous:36 msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"37 raise BufferError(msg)38 return mv.tobytes()39 except TypeError:40 msg = (41 "argument should be a bytes-like object or ASCII "42 f"string, not {s.__class__.__name__!r:s}"43 )44 raise TypeError(msg) from None45 46 47def b64decode(48 s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False49) -> bytes:50 """Decode bytes encoded with the standard Base64 alphabet.51 52 Argument ``s`` is a :term:`bytes-like object` or ASCII string to53 decode.54 55 Optional ``altchars`` must be a :term:`bytes-like object` or ASCII56 string of length 2 which specifies the alternative alphabet used instead57 of the '+' and '/' characters.58 59 If ``validate`` is ``False`` (the default), characters that are neither in60 the normal base-64 alphabet nor the alternative alphabet are discarded61 prior to the padding check.62 If ``validate`` is ``True``, these non-alphabet characters in the input63 result in a :exc:`binascii.Error`.64 65 The result is returned as a :class:`bytes` object.66 67 A :exc:`binascii.Error` is raised if ``s`` is incorrectly padded.68 """69 s = _get_bytes(s)70 if altchars is not None:71 altchars = _get_bytes(altchars)72 if validate:73 if len(s) % 4 != 0:74 msg = "Incorrect padding"75 raise BinAsciiError(msg)76 result = builtin_decode(s, altchars, validate=False)77 78 # check length of result vs length of input79 expected_len = 080 if len(s) > 0:81 padding = 082 # len(s) % 4 != 0 implies len(s) >= 4 here83 if s[-2] == 61: # 61 == ord("=")84 padding += 185 if s[-1] == 61:86 padding += 187 expected_len = 3 * (len(s) // 4) - padding88 if expected_len != len(result):89 msg = "Non-base64 digit found"90 raise BinAsciiError(msg)91 return result92 return builtin_decode(s, altchars, validate=False)93 94 95def b64decode_as_bytearray(96 s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False97) -> bytearray:98 """Decode bytes encoded with the standard Base64 alphabet.99 100 Argument ``s`` is a :term:`bytes-like object` or ASCII string to101 decode.102 103 Optional ``altchars`` must be a :term:`bytes-like object` or ASCII104 string of length 2 which specifies the alternative alphabet used instead105 of the '+' and '/' characters.106 107 If ``validate`` is ``False`` (the default), characters that are neither in108 the normal base-64 alphabet nor the alternative alphabet are discarded109 prior to the padding check.110 If ``validate`` is ``True``, these non-alphabet characters in the input111 result in a :exc:`binascii.Error`.112 113 The result is returned as a :class:`bytearray` object.114 115 A :exc:`binascii.Error` is raised if ``s`` is incorrectly padded.116 """117 return bytearray(b64decode(s, altchars=altchars, validate=validate))118 119 120def b64encode(s: Buffer, altchars: str | Buffer | None = None) -> bytes:121 """Encode bytes using the standard Base64 alphabet.122 123 Argument ``s`` is a :term:`bytes-like object` to encode.124 125 Optional ``altchars`` must be a byte string of length 2 which specifies126 an alternative alphabet for the '+' and '/' characters. This allows an127 application to e.g. generate url or filesystem safe Base64 strings.128 129 The result is returned as a :class:`bytes` object.130 """131 mv = memoryview(s)132 if not mv.c_contiguous:133 msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"134 raise BufferError(msg)135 if altchars is not None:136 altchars = _get_bytes(altchars)137 return builtin_encode(s, altchars)138 139 140def b64encode_as_string(s: Buffer, altchars: str | Buffer | None = None) -> str:141 """Encode bytes using the standard Base64 alphabet.142 143 Argument ``s`` is a :term:`bytes-like object` to encode.144 145 Optional ``altchars`` must be a byte string of length 2 which specifies146 an alternative alphabet for the '+' and '/' characters. This allows an147 application to e.g. generate url or filesystem safe Base64 strings.148 149 The result is returned as a :class:`str` object.150 """151 return b64encode(s, altchars).decode("ascii")152 153 154def encodebytes(s: Buffer) -> bytes:155 """Encode bytes into a bytes object with newlines (b'\\\\n') inserted after156 every 76 bytes of output, and ensuring that there is a trailing newline,157 as per :rfc:`2045` (MIME).158 159 Argument ``s`` is a :term:`bytes-like object` to encode.160 161 The result is returned as a :class:`bytes` object.162 """163 mv = memoryview(s)164 if not mv.c_contiguous:165 msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"166 raise BufferError(msg)167 return builtin_encodebytes(s)168 