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