| |
| // TODO Experiment with versioning. This may be removed or changed dramatically. |
| // Please ignore for now. Do not review. |
| #define OBOE_VERSION_EXPERIMENT 0 |
| #if OBOE_VERSION_EXPERIMENT |
| |
| #define OBOE_EARLIEST_SUPPORTED_VERSION 1 |
| #define OBOE_CURRENT_VERSION 2 |
| |
| typedef struct OboeInterface_s { |
| int32_t size; // do not use size_t because its size can vary |
| int32_t version; |
| int32_t reserved1; |
| void * reserved2; |
| oboe_result_t (*createStreamBuilder)(OboeStreamBuilder *); |
| } OboeInterface_t; |
| |
| OboeInterface_t s_oboe_template = { |
| .size = sizeof(OboeInterface_t), |
| .version = OBOE_CURRENT_VERSION, |
| .reserved1 = 0, |
| .reserved2 = NULL, |
| .createStreamBuilder = Oboe_createStreamBuilder |
| }; |
| |
| oboe_result_t Oboe_Unimplemented(OboeInterface_t *oboe) { |
| (void) oboe; |
| return OBOE_ERROR_UNIMPLEMENTED; |
| } |
| |
| typedef oboe_result_t (*OboeFunction_t)(OboeInterface_t *oboe); |
| |
| int32_t Oboe_Initialize(OboeInterface_t *oboe, uint32_t flags) { |
| if (oboe->version < OBOE_EARLIEST_SUPPORTED_VERSION) { |
| return OBOE_ERROR_INCOMPATIBLE; |
| } |
| // Fill in callers vector table. |
| uint8_t *start = (uint8_t*)&oboe->reserved1; |
| uint8_t *end; |
| if (oboe->size <= s_oboe_template.size) { |
| end = ((uint8_t *)oboe) + oboe->size; |
| } else { |
| end = ((uint8_t *)oboe) + s_oboe_template.size; |
| // Assume the rest of the structure is vectors. |
| // Point them all to OboeInternal_Unimplemented() |
| // Point to first vector past end of the known structure. |
| OboeFunction_t *next = (OboeFunction_t*)end; |
| while ((((uint8_t *)next) - ((uint8_t *)oboe)) < oboe->size) { |
| *next++ = Oboe_Unimplemented; |
| } |
| } |
| memcpy(&oboe->reserved1, &s_oboe_template.reserved1, end - start); |
| return OBOE_OK; |
| } |
| #endif /* OBOE_VERSION_EXPERIMENT -------------------------- */ |