blob: 071239b1c13a6eca3a21c5baefb5c50f13938b56 [file] [log] [blame]
// 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 -------------------------- */