|
37 | 37 |
|
38 | 38 | T = TypeVar("T") |
39 | 39 | PointerLike = Union[TypedCPointer[Any], VoidPointer] |
40 | | -StringLike = Union[str, bytes, VoidPointer] |
| 40 | +StringLike = Union[str, bytes, VoidPointer, TypedCPointer[bytes]] |
41 | 41 | Format = Union[str, bytes, PointerLike] |
42 | 42 |
|
43 | 43 | __all__ = ( |
|
149 | 149 | "c_calloc", |
150 | 150 | "c_realloc", |
151 | 151 | "c_free", |
| 152 | + "gmtime", |
152 | 153 | ) |
153 | 154 |
|
154 | 155 |
|
@@ -176,7 +177,7 @@ def _decode_response( |
176 | 177 | res = ( |
177 | 178 | TypedCPointer(ctypes.addressof(res), res_typ, ctypes.sizeof(res)) |
178 | 179 | if not issubclass(type(res.contents), ctypes.Structure) |
179 | | - else StructPointer(id(struct), type(_not_null(struct))) |
| 180 | + else StructPointer(id(struct), type(_not_null(struct)), struct) |
180 | 181 | ) |
181 | 182 | # type safety gets mad if i dont use elif here |
182 | 183 | elif fn.restype is ctypes.c_void_p: |
@@ -229,15 +230,22 @@ def _base( |
229 | 230 |
|
230 | 231 |
|
231 | 232 | def _make_char_pointer(data: StringLike) -> Union[bytes, ctypes.c_char_p]: |
232 | | - if type(data) not in {VoidPointer, str, bytes}: |
| 233 | + if type(data) not in {VoidPointer, str, bytes, TypedCPointer}: |
233 | 234 | raise InvalidBindingParameter( |
234 | 235 | f"expected a string-like object, got {repr(data)}" # noqa |
235 | 236 | ) |
236 | 237 |
|
237 | 238 | if isinstance(data, bytes): |
238 | 239 | return data |
239 | 240 |
|
240 | | - if isinstance(data, VoidPointer): |
| 241 | + is_typed_ptr: bool = isinstance(data, TypedCPointer) |
| 242 | + |
| 243 | + if isinstance(data, VoidPointer) or is_typed_ptr: |
| 244 | + if is_typed_ptr and (data.type is not bytes): |
| 245 | + raise InvalidBindingParameter( |
| 246 | + f"{data} does not point to bytes", |
| 247 | + ) |
| 248 | + |
241 | 249 | return ctypes.c_char_p(data.address) |
242 | 250 |
|
243 | 251 | return data.encode() |
@@ -809,12 +817,18 @@ def mktime(timeptr: StructPointer[Tm]) -> int: |
809 | 817 |
|
810 | 818 |
|
811 | 819 | def strftime( |
812 | | - string: str, |
| 820 | + string: StringLike, |
813 | 821 | maxsize: int, |
814 | | - fmt: TypedCPointer[str], |
| 822 | + fmt: StringLike, |
815 | 823 | timeptr: StructPointer[Tm], |
816 | 824 | ) -> int: |
817 | | - return _base(dll.strftime, string, maxsize, fmt, timeptr) |
| 825 | + return _base( |
| 826 | + dll.strftime, |
| 827 | + _make_char_pointer(string), |
| 828 | + maxsize, |
| 829 | + _make_char_pointer(fmt), |
| 830 | + timeptr, |
| 831 | + ) |
818 | 832 |
|
819 | 833 |
|
820 | 834 | def time(timer: TypedCPointer[int]) -> int: |
@@ -851,3 +865,7 @@ def c_realloc(ptr: PointerLike, size: int) -> VoidPointer: |
851 | 865 |
|
852 | 866 | def c_free(ptr: PointerLike) -> None: |
853 | 867 | return _base(_free, ptr) |
| 868 | + |
| 869 | + |
| 870 | +def gmtime(timer: PointerLike) -> StructPointer[Tm]: |
| 871 | + return _base(dll.gmtime, timer) |
0 commit comments