1 2// TODO Experiment with versioning. This may be removed or changed dramatically. 3// Please ignore for now. Do not review. 4#define OBOE_VERSION_EXPERIMENT 0 5#if OBOE_VERSION_EXPERIMENT 6 7#define OBOE_EARLIEST_SUPPORTED_VERSION 1 8#define OBOE_CURRENT_VERSION 2 9 10typedef struct OboeInterface_s { 11 int32_t size; // do not use size_t because its size can vary 12 int32_t version; 13 int32_t reserved1; 14 void * reserved2; 15 oboe_result_t (*createStreamBuilder)(OboeStreamBuilder *); 16} OboeInterface_t; 17 18OboeInterface_t s_oboe_template = { 19 .size = sizeof(OboeInterface_t), 20 .version = OBOE_CURRENT_VERSION, 21 .reserved1 = 0, 22 .reserved2 = NULL, 23 .createStreamBuilder = Oboe_createStreamBuilder 24}; 25 26oboe_result_t Oboe_Unimplemented(OboeInterface_t *oboe) { 27 (void) oboe; 28 return OBOE_ERROR_UNIMPLEMENTED; 29} 30 31typedef oboe_result_t (*OboeFunction_t)(OboeInterface_t *oboe); 32 33int32_t Oboe_Initialize(OboeInterface_t *oboe, uint32_t flags) { 34 if (oboe->version < OBOE_EARLIEST_SUPPORTED_VERSION) { 35 return OBOE_ERROR_INCOMPATIBLE; 36 } 37 // Fill in callers vector table. 38 uint8_t *start = (uint8_t*)&oboe->reserved1; 39 uint8_t *end; 40 if (oboe->size <= s_oboe_template.size) { 41 end = ((uint8_t *)oboe) + oboe->size; 42 } else { 43 end = ((uint8_t *)oboe) + s_oboe_template.size; 44 // Assume the rest of the structure is vectors. 45 // Point them all to OboeInternal_Unimplemented() 46 // Point to first vector past end of the known structure. 47 OboeFunction_t *next = (OboeFunction_t*)end; 48 while ((((uint8_t *)next) - ((uint8_t *)oboe)) < oboe->size) { 49 *next++ = Oboe_Unimplemented; 50 } 51 } 52 memcpy(&oboe->reserved1, &s_oboe_template.reserved1, end - start); 53 return OBOE_OK; 54} 55#endif /* OBOE_VERSION_EXPERIMENT -------------------------- */ 56