xref: /xnu-10063.141.1/EXTERNAL_HEADERS/CoreEntitlements/Serialization.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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 
CESerializedElementGetData(const CESerializedElement_t * element)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 
CESerializedElementSetData(CESerializedElement_t * element,void * __sized_by (length)bytes,size_t length)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