58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
|
"""
|
||
|
Utility functions to deal with binary structs.
|
||
|
"""
|
||
|
|
||
|
# Copyright (C) 2020 The Psycopg Team
|
||
|
|
||
|
import struct
|
||
|
from typing import Callable, cast, Optional, Tuple
|
||
|
from typing_extensions import TypeAlias
|
||
|
|
||
|
from .abc import Buffer
|
||
|
from . import errors as e
|
||
|
from ._compat import Protocol
|
||
|
|
||
|
PackInt: TypeAlias = Callable[[int], bytes]
|
||
|
UnpackInt: TypeAlias = Callable[[Buffer], Tuple[int]]
|
||
|
PackFloat: TypeAlias = Callable[[float], bytes]
|
||
|
UnpackFloat: TypeAlias = Callable[[Buffer], Tuple[float]]
|
||
|
|
||
|
|
||
|
class UnpackLen(Protocol):
|
||
|
def __call__(self, data: Buffer, start: Optional[int]) -> Tuple[int]:
|
||
|
...
|
||
|
|
||
|
|
||
|
pack_int2 = cast(PackInt, struct.Struct("!h").pack)
|
||
|
pack_uint2 = cast(PackInt, struct.Struct("!H").pack)
|
||
|
pack_int4 = cast(PackInt, struct.Struct("!i").pack)
|
||
|
pack_uint4 = cast(PackInt, struct.Struct("!I").pack)
|
||
|
pack_int8 = cast(PackInt, struct.Struct("!q").pack)
|
||
|
pack_float4 = cast(PackFloat, struct.Struct("!f").pack)
|
||
|
pack_float8 = cast(PackFloat, struct.Struct("!d").pack)
|
||
|
|
||
|
unpack_int2 = cast(UnpackInt, struct.Struct("!h").unpack)
|
||
|
unpack_uint2 = cast(UnpackInt, struct.Struct("!H").unpack)
|
||
|
unpack_int4 = cast(UnpackInt, struct.Struct("!i").unpack)
|
||
|
unpack_uint4 = cast(UnpackInt, struct.Struct("!I").unpack)
|
||
|
unpack_int8 = cast(UnpackInt, struct.Struct("!q").unpack)
|
||
|
unpack_float4 = cast(UnpackFloat, struct.Struct("!f").unpack)
|
||
|
unpack_float8 = cast(UnpackFloat, struct.Struct("!d").unpack)
|
||
|
|
||
|
_struct_len = struct.Struct("!i")
|
||
|
pack_len = cast(Callable[[int], bytes], _struct_len.pack)
|
||
|
unpack_len = cast(UnpackLen, _struct_len.unpack_from)
|
||
|
|
||
|
|
||
|
def pack_float4_bug_304(x: float) -> bytes:
|
||
|
raise e.InterfaceError(
|
||
|
"cannot dump Float4: Python affected by bug #304. Note that the psycopg-c"
|
||
|
" and psycopg-binary packages are not affected by this issue."
|
||
|
" See https://github.com/psycopg/psycopg/issues/304"
|
||
|
)
|
||
|
|
||
|
|
||
|
# If issue #304 is detected, raise an error instead of dumping wrong data.
|
||
|
if struct.Struct("!f").pack(1.0) != bytes.fromhex("3f800000"):
|
||
|
pack_float4 = pack_float4_bug_304
|