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