| 29 | |
| 30 | |
| 31 | class Metadata: |
| 32 | def __init__( |
| 33 | self, value: Optional[MetadataValueType] = None, signed: Optional[bool] = None, raw: Optional[bool] = None, |
| 34 | handle: Optional[core.BNMetadata] = None |
| 35 | ): |
| 36 | """ |
| 37 | The 'raw' parameter is no longer needed it was a workaround for a Python 2 limitation. |
| 38 | To pass raw data into this API, simply use a `bytes` object. |
| 39 | """ |
| 40 | if handle is not None: |
| 41 | self.handle = handle |
| 42 | elif isinstance(value, Metadata): |
| 43 | # If the value is already a Metadata object, reuse its handle |
| 44 | self.handle = value.handle |
| 45 | elif isinstance(value, bool): |
| 46 | self.handle = core.BNCreateMetadataBooleanData(value) |
| 47 | elif isinstance(value, int): |
| 48 | if signed: |
| 49 | self.handle = core.BNCreateMetadataSignedIntegerData(value) |
| 50 | else: |
| 51 | self.handle = core.BNCreateMetadataUnsignedIntegerData(value) |
| 52 | elif isinstance(value, str): |
| 53 | self.handle = core.BNCreateMetadataStringData(value) |
| 54 | elif isinstance(value, bytes): |
| 55 | buffer = (ctypes.c_ubyte * len(value)).from_buffer_copy(value) |
| 56 | self.handle = core.BNCreateMetadataRawData(buffer, len(value)) |
| 57 | elif isinstance(value, float): |
| 58 | self.handle = core.BNCreateMetadataDoubleData(value) |
| 59 | elif isinstance(value, (list, tuple)): |
| 60 | self.handle = core.BNCreateMetadataOfType(MetadataType.ArrayDataType) |
| 61 | for elm in value: |
| 62 | md = Metadata(elm, signed, raw) |
| 63 | core.BNMetadataArrayAppend(self.handle, md.handle) |
| 64 | elif isinstance(value, dict): |
| 65 | self.handle = core.BNCreateMetadataOfType(MetadataType.KeyValueDataType) |
| 66 | for elm in value: |
| 67 | md = Metadata(value[elm], signed, raw) |
| 68 | core.BNMetadataSetValueForKey(self.handle, str(elm), md.handle) |
| 69 | else: |
| 70 | raise ValueError(f"{type(value)} is not a supported type: int, bool, str, bytes, float, list, tuple, dict, or Metadata") |
| 71 | |
| 72 | def __len__(self): |
| 73 | if self.is_array or self.is_dict or self.is_string or self.is_bytes: |
| 74 | return core.BNMetadataSize(self.handle) |
| 75 | raise TypeError("Metadata object doesn't support len()") |
| 76 | |
| 77 | def __eq__(self, other): |
| 78 | if isinstance(other, int) and self.is_integer: |
| 79 | return int(self) == other |
| 80 | elif isinstance(other, str) and self.is_string: |
| 81 | return str(self) == other |
| 82 | elif isinstance(other, bytes) and self.is_bytes: |
| 83 | return bytes(self) == other |
| 84 | elif isinstance(other, float) and self.is_float: |
| 85 | return float(self) == other |
| 86 | elif isinstance(other, bool) and self.is_boolean: |
| 87 | return bool(self) == other |
| 88 | elif self.is_array and ((isinstance(other, Metadata) and other.is_array) or isinstance(other, list)): |
no outgoing calls
no test coverage detected