SerializedData Class
Overview
The SerializedData
class encapsulates serialized data with metadata about encoding and data type. It provides type-safe serialization with comprehensive support for primitive types, complex objects, and proper character encoding.
Package: keychain.core.serialized_data
from keychain.core.serialized_data import SerializedData
Class Definition
class SerializedData(SerializableObject):
"""Encapsulates serialized data with metadata about encoding and data type."""
Constructor
def __init__(
self,
data: Union[ctypes.c_void_p, str, int, float, bool, bytes, None] = None,
data_type: Optional[DataType] = None,
encoding: Optional[CharEncoding] = None,
c_pointer: Optional[ctypes.c_void_p] = None,
) -> None
Initialize SerializedData with various data types.
Parameters:
-
data
(Union[various types]
) - Data to serialize, can be primitive types, bytes, or keychain objects -
data_type
(DataType
, optional) - Optional data type override -
encoding
(CharEncoding
, optional) - Optional encoding override -
c_pointer
(ctypes.c_void_p
, optional) - Existing C pointer to wrap
Supported Data Types:
-
Primitive types:
str
,int
,float
,bool
,bytes
-
Keychain objects:
VerifiableData
,Credential
,Transaction
,EncryptedData
,Attestation
,KeyLock
Properties
data_type()
def data_type(self) -> DataType
Get the data type of the serialized content.
Returns: The DataType enum value identifying the content type
Data Access Methods
utf8_string()
def utf8_string(self) -> str
Get the content as a UTF-8 string.
Returns: String content (for DataType.UTF8_STRING)
Raises: ValueError
if data type is not UTF8_STRING
int32()
def int32(self) -> int
Get the content as a 32-bit signed integer.
Returns: Integer value (for DataType.INT32)
Raises: ValueError
if data type is not INT32
int64()
def int64(self) -> int
Get the content as a 64-bit signed integer.
Returns: Integer value (for DataType.INT64)
Raises: ValueError
if data type is not INT64
boolean()
def boolean(self) -> bool
Get the content as a boolean value.
Returns: Boolean value (for DataType.BOOLEAN)
Raises: ValueError
if data type is not BOOLEAN
single_float()
def single_float(self) -> float
Get the content as a single-precision float.
Returns: Float value (for DataType.SINGLE_FLOAT)
Raises: ValueError
if data type is not SINGLE_FLOAT
Usage Examples
Basic Data Types
from keychain.core.serialized_data import SerializedData
from keychain.constants import DataType, CharEncoding
# String data
text_data = SerializedData("Hello, World!")
print(f"Type: {text_data.data_type()}") # DataType.UTF8_STRING
print(f"Content: {text_data.utf8_string()}")
# Integer data
int_data = SerializedData(42)
print(f"Type: {int_data.data_type()}") # DataType.INT32
print(f"Value: {int_data.int32()}")
# Boolean data
bool_data = SerializedData(True)
print(f"Type: {bool_data.data_type()}") # DataType.BOOLEAN
print(f"Value: {bool_data.boolean()}")
# Binary data
binary_data = SerializedData(b"binary content")
print(f"Type: {binary_data.data_type()}") # DataType.BYTES
Working with Keychain Objects
# Serialize a verifiable data object
verifiable_obj = gateway.sign(persona, "Document content")
serialized_verifiable = SerializedData(verifiable_obj)
print(f"Type: {serialized_verifiable.data_type()}") # DataType.VERIFIABLE_DATA
# Retrieve the original object
retrieved_verifiable = serialized_verifiable.verifiable_data()
assert retrieved_verifiable == verifiable_obj
Type-Safe Access
def process_serialized_data(data: SerializedData):
"""Process serialized data based on its type."""
data_type = data.data_type()
if data_type == DataType.UTF8_STRING:
content = data.utf8_string()
print(f"String content: {content}")
elif data_type == DataType.INT32:
value = data.int32()
print(f"Integer value: {value}")
elif data_type == DataType.BOOLEAN:
flag = data.boolean()
print(f"Boolean flag: {flag}")
elif data_type == DataType.VERIFIABLE_DATA:
verifiable = data.verifiable_data()
print(f"Verifiable data: {verifiable}")
else:
print(f"Unsupported data type: {data_type}")
# Usage
process_serialized_data(SerializedData("test")) # String content: test
process_serialized_data(SerializedData(123)) # Integer value: 123
process_serialized_data(SerializedData(False)) # Boolean flag: False
Serialization and Reconstruction
# Original data
original = SerializedData("Important data")
# Serialize to bytes
serialized_bytes = original.serialize()
# Reconstruct (typically done through deserialization)
# reconstructed = SerializedData.from_bytes(serialized_bytes)
# Check content preservation
print(f"Original type: {original.data_type()}")
print(f"Original content: {original.utf8_string()}")
Character Encoding Handling
# Text with specific encoding
text_data = SerializedData("Héllo, Wörld!")
print(f"Encoding: {text_data.char_encoding()}") # CharEncoding.UTF8
print(f"Content: {text_data.utf8_string()}")
# Binary data has no character encoding
binary_data = SerializedData(b"\\x00\\x01\\x02")
print(f"Encoding: {binary_data.char_encoding()}") # CharEncoding.BINARY
Type Safety and Validation
Data Type Checking
def safe_get_string(data: SerializedData) -> str:
"""Safely extract string content with type checking."""
if data.data_type() != DataType.UTF8_STRING:
raise TypeError(f"Expected UTF8_STRING, got {data.data_type()}")
return data.utf8_string()
def safe_get_number(data: SerializedData) -> Union[int, float]:
"""Safely extract numeric content."""
data_type = data.data_type()
if data_type == DataType.INT32:
return data.int32()
elif data_type == DataType.INT64:
return data.int64()
elif data_type == DataType.SINGLE_FLOAT:
return data.single_float()
elif data_type == DataType.DOUBLE_FLOAT:
return data.double_float()
else:
raise TypeError(f"Expected numeric type, got {data_type}")
See Also
-
DataType - Data type enumeration for serialized content
-
CharEncoding - Character encoding options
-
VerifiableData - Verifiable data objects that can be serialized
-
EncryptedData - Encrypted data objects that can be serialized
-
Credential - Credential objects that can be serialized