1"""BINARY values from :rfc:`5545`."""
2
3import base64
4import binascii
5from typing import ClassVar
6
7from icalendar.compatibility import Self
8from icalendar.error import JCalParsingError
9from icalendar.parser import Parameters
10from icalendar.parser_tools import to_unicode
11
12
13class vBinary:
14 """Binary property values are base 64 encoded."""
15
16 default_value: ClassVar[str] = "BINARY"
17 params: Parameters
18 obj: str
19
20 def __init__(self, obj: str | bytes, params: dict[str, str] | None = None) -> None:
21 self.obj = to_unicode(obj)
22 self.params = Parameters(encoding="BASE64", value="BINARY")
23 if params:
24 self.params.update(params)
25
26 def __repr__(self) -> str:
27 return f"vBinary({self.to_ical()})"
28
29 def to_ical(self) -> bytes:
30 return binascii.b2a_base64(self.obj.encode("utf-8"))[:-1]
31
32 @staticmethod
33 def from_ical(ical: str | bytes) -> bytes:
34 try:
35 return base64.b64decode(ical)
36 except ValueError as e:
37 raise ValueError("Not valid base 64 encoding.") from e
38
39 def __eq__(self, other: object) -> bool:
40 """self == other"""
41 return isinstance(other, vBinary) and self.obj == other.obj
42
43 def __hash__(self) -> int:
44 """Hash of the vBinary object."""
45 return hash(self.obj)
46
47 @classmethod
48 def examples(cls) -> list[Self]:
49 """Examples of vBinary."""
50 return [cls("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4")]
51
52 from icalendar.param import VALUE
53
54 def to_jcal(self, name: str) -> list:
55 """The jCal representation of this property according to :rfc:`7265`."""
56 params = self.params.to_jcal()
57 if params.get("encoding") == "BASE64":
58 # BASE64 is the only allowed encoding
59 del params["encoding"]
60 return [name, params, self.VALUE.lower(), self.obj]
61
62 @classmethod
63 def from_jcal(cls, jcal_property: list) -> Self:
64 """Parse jCal from :rfc:`7265` to a vBinary.
65
66 Parameters:
67 jcal_property: The jCal property to parse.
68
69 Raises:
70 ~error.JCalParsingError: If the provided jCal is invalid.
71 """
72 JCalParsingError.validate_property(jcal_property, cls)
73 JCalParsingError.validate_value_type(jcal_property[3], str, cls, 3)
74 return cls(
75 jcal_property[3],
76 params=Parameters.from_jcal_property(jcal_property),
77 )
78
79
80__all__ = ["vBinary"]