Initial LinuxCNC WebAssembly workspace snapshot
This commit is contained in:
82
wasm-core/src/sim_event.c
Normal file
82
wasm-core/src/sim_event.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "sim_event.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user