Skip to content

Commit b2a47f4

Browse files
committed
fix: Refactor
1 parent 12f04d4 commit b2a47f4

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

src/c2pa/c2pa.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,13 +1276,18 @@ def resource_to_stream(self, uri: str, stream: Any) -> int:
12761276
class Signer:
12771277
"""High-level wrapper for C2PA Signer operations."""
12781278

1279-
def __init__(self, signer_ptr: ctypes.POINTER(C2paSigner)):
1279+
def __init__(self, signer_ptr: ctypes.POINTER(C2paSigner), callback_cb: Optional[SignerCallback] = None):
12801280
"""Initialize a new Signer instance.
12811281
12821282
Note: This constructor is not meant to be called directly.
12831283
Use from_info() or from_callback() instead.
1284+
1285+
Args:
1286+
signer_ptr: Pointer to the C2PA signer
1287+
callback_cb: Optional callback function (for callback-based signers)
12841288
"""
12851289
self._signer = signer_ptr
1290+
self._callback_cb = callback_cb # Keep callback alive to prevent garbage collection
12861291
self._closed = False
12871292
self._error_messages = {
12881293
'closed_error': "Signer is closed",
@@ -1373,11 +1378,10 @@ def wrapped_callback(
13731378
data_len,
13741379
signed_bytes_ptr,
13751380
signed_len):
1376-
# Returns 0 on error as this case is handled in the native code gracefully
1381+
# Returns -1 on error as it is what the native code expects.
13771382
# The reason is that otherwise we ping-pong errors between native code and Python code,
13781383
# which can become tedious in handling. So we let the native code deal with it and
1379-
# raise the errors accordingly, since it already checks the
1380-
# signature length for correctness.
1384+
# raise the errors accordingly, since it already does checks.
13811385
try:
13821386
if not data_ptr or data_len <= 0:
13831387
# Error: invalid input, invalid so return -1,
@@ -1398,8 +1402,8 @@ def wrapped_callback(
13981402
# native code will handle that too!
13991403
return -1
14001404

1401-
# Copy the signature back to the C buffer (since callback is
1402-
# used in native code)
1405+
# Copy the signature back to the C buffer
1406+
# (since callback is used in native code)
14031407
actual_len = min(len(signature), signed_len)
14041408
# Use memmove for efficient memory copying instead of byte-by-byte loop
14051409
ctypes.memmove(signed_bytes_ptr, signature, actual_len)
@@ -1423,15 +1427,13 @@ def wrapped_callback(
14231427
error_messages['encoding_error'].format(
14241428
str(e)))
14251429

1426-
# Create the signer with the wrapped callback
1427-
# Store the callback as an instance attribute to keep it alive, as this prevents
1428-
# garbage collection and lifetime issues.
1429-
signer_instance = cls.__new__(cls)
1430-
signer_instance._callback_cb = SignerCallback(wrapped_callback)
1430+
# Create the callback object using the callback function
1431+
callback_cb = SignerCallback(wrapped_callback)
14311432

1433+
# Create the signer with the wrapped callback
14321434
signer_ptr = _lib.c2pa_signer_create(
14331435
None,
1434-
signer_instance._callback_cb,
1436+
callback_cb,
14351437
alg,
14361438
certs_bytes,
14371439
tsa_url_bytes
@@ -1443,12 +1445,8 @@ def wrapped_callback(
14431445
raise C2paError(error)
14441446
raise C2paError("Failed to create signer")
14451447

1446-
# Initialize the signer instance
1447-
signer_instance._signer = signer_ptr
1448-
signer_instance._closed = False
1449-
signer_instance._error_messages = error_messages
1450-
1451-
return signer_instance
1448+
# Create and return the signer instance with the callback
1449+
return cls(signer_ptr, callback_cb)
14521450

14531451
def __enter__(self):
14541452
"""Context manager entry."""
@@ -1888,6 +1886,7 @@ def _sign_internal(
18881886
source_stream.close()
18891887
dest_stream.close()
18901888

1889+
18911890
def sign(
18921891
self,
18931892
signer: Signer,

0 commit comments

Comments
 (0)