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