#include "sim_event.h" #include #include typedef struct sim_event_state { uint32_t count; uint32_t last_seq; uint32_t last_tick; sim_event_record records[SIM_EVENT_CAPACITY]; } sim_event_state; static sim_event_state state; static uint64_t hash_payload(const uint8_t *payload, uint32_t payload_len) { uint64_t hash = 1469598103934665603ULL; uint32_t index; if (payload == NULL && payload_len != 0U) return 0; for (index = 0; index < payload_len; ++index) { hash ^= payload[index]; hash *= 1099511628211ULL; } return hash; } void sim_event_reset(void) { memset(&state, 0, sizeof(state)); } int32_t sim_event_append(uint32_t seq, uint32_t tick, const char *kind, const uint8_t *payload, uint32_t payload_len) { sim_event_record *record; size_t kind_len; if (seq == 0U || seq != state.last_seq + 1U) return SIM_EVENT_ERR_SEQUENCE; if (tick < state.last_tick) return SIM_EVENT_ERR_TICK; if (kind == NULL || kind[0] == '\0') return SIM_EVENT_ERR_ARGUMENT; kind_len = strlen(kind); if (kind_len >= SIM_EVENT_KIND_CAPACITY || (payload == NULL && payload_len != 0U)) return SIM_EVENT_ERR_ARGUMENT; if (state.count >= SIM_EVENT_CAPACITY) return SIM_EVENT_ERR_FULL; record = &state.records[state.count++]; memset(record, 0, sizeof(*record)); memcpy(record->kind, kind, kind_len); record->seq = seq; record->tick = tick; record->payload_hash = hash_payload(payload, payload_len); state.last_seq = seq; state.last_tick = tick; return SIM_EVENT_OK; } uint32_t sim_event_count(void) { return state.count; } uint32_t sim_event_cursor(void) { return state.last_seq; } uint32_t sim_event_read(uint32_t index, uint8_t *out, uint32_t capacity) { const uint32_t size = (uint32_t)sizeof(sim_event_record); if (index >= state.count) return 0; if (out == NULL || capacity < size) return size; memcpy(out, &state.records[index], size); return size; } uint32_t sim_event_export(uint8_t *out, uint32_t capacity) { const uint32_t size = (uint32_t)sizeof(state); if (out == NULL || capacity < size) return size; memcpy(out, &state, size); return size; } int32_t sim_event_import(const uint8_t *data, uint32_t len) { if (data == NULL || len != sizeof(state)) return SIM_EVENT_ERR_ARGUMENT; memcpy(&state, data, sizeof(state)); if (state.count > SIM_EVENT_CAPACITY) { sim_event_reset(); return SIM_EVENT_ERR_ARGUMENT; } return SIM_EVENT_OK; }