1 | // |
2 | // Serialization.h |
3 | // CoreEntitlements |
4 | // |
5 | // |
6 | |
7 | #ifndef CORE_ENTITLEMENTS_SERIALIZATION_H |
8 | #define CORE_ENTITLEMENTS_SERIALIZATION_H |
9 | |
10 | #ifndef _CE_INDIRECT |
11 | #error "Please include <CoreEntitlements/CoreEntitlements.h> instead of this file" |
12 | #endif |
13 | |
14 | #include <CoreEntitlements/Result.h> |
15 | #include <CoreEntitlements/Runtime.h> |
16 | #include <CoreEntitlements/Entitlements.h> |
17 | |
18 | __ptrcheck_abi_assume_single(); |
19 | |
20 | /*! |
21 | * @enum CESerializedElementType_t |
22 | * These are the primitive types that CoreEntitlements can serialize |
23 | * Depending on the underlying representation some of these elements may be "virtual" or zero-sized. |
24 | * However, they must still be included. |
25 | */ |
26 | OS_CLOSED_ENUM(CESerializedElementType, int64_t, |
27 | /* A boolean element with a true / false value */ |
28 | kCESerializedBool = 1, |
29 | /* A string element with a definite length */ |
30 | kCESerializedString = 2, |
31 | /* A key string element with a definite length */ |
32 | kCESerializedKey = 3, |
33 | /* An integer element, must be representable as int64_t */ |
34 | kCESerializedInteger = 4, |
35 | /* Marks the start of an array / ordered sequence */ |
36 | kCESerializedArrayBegin = 5, |
37 | /* Marks the end of an array / ordered sequence */ |
38 | kCESerializedArrayEnd = 6, |
39 | /* Marks the start of a dictionary */ |
40 | /* The only valid elements contained in a dictionary are tuples (represented as an ordered sequence) */ |
41 | /* The first element of the ordered sequence must be kCESerializedString value */ |
42 | /* No restrictions are placed on the contents of the second element*/ |
43 | kCESerializedDictionaryBegin = 7, |
44 | /* Marks the end of a dictionary */ |
45 | kCESerializedDictionaryEnd = 8, |
46 | /* A data element with a definite length*/ |
47 | kCESerializedData = 9, |
48 | ); |
49 | |
50 | /*! |
51 | * @typedef CESerializedElement_t |
52 | * This structure represents an encodable piece of data, along with its type and length (in bytes). |
53 | * For the most part you will not need to use this structure manually, and instead you should use the helpers below |
54 | */ |
55 | typedef struct CESerializedElement { |
56 | CESerializedElementType_t type; |
57 | union { |
58 | #if !__has_ptrcheck |
59 | void* bytes; |
60 | #endif |
61 | int64_t value; |
62 | } data; |
63 | size_t length; |
64 | bool pair; |
65 | } CESerializedElement_t; |
66 | |
67 | static inline void *CE_HEADER_INDEXABLE CESerializedElementGetData(const CESerializedElement_t *element) { |
68 | return __unsafe_forge_bidi_indexable(void *, element->data.value, element->length); |
69 | } |
70 | |
71 | static inline void CESerializedElementSetData(CESerializedElement_t *element, void *__sized_by(length) bytes, size_t length) { |
72 | element->data.value = (intptr_t)bytes; |
73 | element->length = length; |
74 | } |
75 | |
76 | /*! |
77 | * @function CESizeSerialization |
78 | * This function will iterate over the elements that are to be serialized and compute the size of an allocation that needs to be made |
79 | * for a successful serialization. |
80 | * |
81 | * @note |
82 | * This function may modify the length field of the CESerializedElements that are passed in. This must be done for serialization to succeed |
83 | * |
84 | * @returns |
85 | * kCENoError if the requiredSize has been successfully populated and contains a valid value |
86 | */ |
87 | CEError_t CESizeSerialization(CESerializedElement_t elements[__counted_by(elementsCount)], size_t elementsCount, size_t* requiredSize) __result_use_check; |
88 | |
89 | /*! |
90 | * @function CESizeXMLSerialization |
91 | * This function will iterate over the elements that are to be serialized and compute the size of an allocation that needs to be made |
92 | * for a successful serialization to XML. |
93 | * |
94 | * @note |
95 | * This function may modify the length field of the CESerializedElements that are passed in. This must be done for serialization to succeed |
96 | * |
97 | * @returns |
98 | * kCENoError if the requiredSize has been successfully populated and contains a valid value |
99 | */ |
100 | CEError_t CESizeXMLSerialization(CESerializedElement_t elements[__counted_by(elementsCount)], size_t elementsCount, size_t* requiredSize) __result_use_check; |
101 | |
102 | /*! |
103 | * @function CESerializeWithOptions |
104 | * Serializes the array of elements that contains the underlying data. The elements must have been sized with CESizeSerialization before calling this function. |
105 | * |
106 | * @param runtime |
107 | * The runtime to use for this operation |
108 | * |
109 | * @param options |
110 | * Options that modify what can be serialized. |
111 | * |
112 | * @param elements |
113 | * The list of elements to serialize |
114 | * |
115 | * @param elementsCount |
116 | * How many elements are in that list |
117 | * |
118 | * @param start |
119 | * A pointer to the first byte into a buffer that will be filled with the serialized representation |
120 | * |
121 | * @param end |
122 | * A pointer 1 byte past the end of the buffer to be used for serialization |
123 | */ |
124 | CEError_t CESerializeWithOptions(const CERuntime_t runtime, CEValidationOptions* options, CESerializedElement_t elements[__counted_by(elementsCount)], size_t elementsCount, uint8_t *__ended_by(end) start, uint8_t* end) __result_use_check; |
125 | |
126 | /*! |
127 | * @function CESerialize |
128 | * Serializes the array of elements that contains the underlying data. The elements must have been sized with CESizeSerialization before calling this function. |
129 | * |
130 | * @param runtime |
131 | * The runtime to use for this operation |
132 | * |
133 | * @param elements |
134 | * The list of elements to serialize |
135 | * |
136 | * @param elementsCount |
137 | * How many elements are in that list |
138 | * |
139 | * @param start |
140 | * A pointer to the first byte into a buffer that will be filled with the serialized representation |
141 | * |
142 | * @param end |
143 | * A pointer 1 byte past the end of the buffer to be used for serialization |
144 | */ |
145 | CEError_t CESerialize(const CERuntime_t runtime, CESerializedElement_t elements[__counted_by(elementsCount)], size_t elementsCount, uint8_t *__ended_by(end) start, uint8_t* end) __result_use_check; |
146 | |
147 | /*! |
148 | * @function CESerializeXML |
149 | * Serializes the array of elements that contains the underlying data. The elements must have been sized with CESizeXMLSerialization before calling this function. |
150 | * |
151 | * @param runtime |
152 | * The runtime to use for this operation |
153 | * |
154 | * @param elements |
155 | * The list of elements to serialize |
156 | * |
157 | * @param elementsCount |
158 | * How many elements are in that list |
159 | * |
160 | * @param start |
161 | * A pointer to the first byte into a buffer that will be filled with the serialized representation |
162 | * |
163 | * @param end |
164 | * A pointer 1 byte past the end of the buffer to be used for serialization |
165 | */ |
166 | CEError_t CESerializeXML(const CERuntime_t runtime, CESerializedElement_t elements[__counted_by(elementsCount)], size_t elementsCount, uint8_t *__ended_by(end) start, uint8_t* end) __result_use_check; |
167 | |
168 | // Helpers |
169 | // These automatically construct CESerializedElements for you |
170 | #define CESerializeInteger(intv) (CESerializedElement_t){.type = kCESerializedInteger, .data.value = intv} |
171 | #define CESerializeBool(boolVal) (CESerializedElement_t){.type = kCESerializedBool, .data.value = !!boolVal} |
172 | #define CESerializeStaticString(strVal) (CESerializedElement_t){.type = kCESerializedString, .data.value = (intptr_t)strVal, .length = sizeof(strVal) - 1} |
173 | #define CESerializeKey(strVal) (CESerializedElement_t){.type = kCESerializedKey, .data.value = (intptr_t)strVal, .length = sizeof(strVal) - 1} |
174 | #define CESerializeDynamicKey(strVal, len) (CESerializedElement_t){.type = kCESerializedKey, .data.value = (intptr_t)strVal, .length = len} |
175 | #define CESerializeString(strVal, len) (CESerializedElement_t){.type = kCESerializedString, .data.value = (intptr_t)strVal, .length = len} |
176 | #define CESerializeData(dataVal, len) (CESerializedElement_t){.type = kCESerializedData, .data.value = (intptr_t)dataVal, .length = len} |
177 | #define CESerializeArray(...) (CESerializedElement_t){.type = kCESerializedArrayBegin}, __VA_ARGS__ , (CESerializedElement_t){.type = kCESerializedArrayEnd} |
178 | #define CESerializeDictionary(...) (CESerializedElement_t){.type = kCESerializedDictionaryBegin}, __VA_ARGS__ , (CESerializedElement_t){.type = kCESerializedDictionaryEnd} |
179 | #define CESerializeDictionaryPair(a, b) CESerializeArray(a, b) |
180 | |
181 | #endif |
182 | |