#include "sim_api.h" #include typedef struct { uint32_t created; uint32_t loaded; uint64_t tick; uint32_t pending_event; } sim_state; static sim_state state; #ifndef SIM_CHECKPOINT_BUILD_ID #define SIM_CHECKPOINT_BUILD_ID "unversioned" #endif const char *sim_checkpoint_build_id(void) { return SIM_CHECKPOINT_BUILD_ID; } uint32_t sim_core_checkpoint_size(void) { return sizeof(state); } int32_t sim_core_checkpoint_export(uint8_t *output, uint32_t capacity) { if (output == NULL || capacity != sizeof(state)) return SIM_ERR_INVALID_ARGUMENT; memcpy(output, &state, sizeof(state)); return SIM_OK; } int32_t sim_core_checkpoint_restore(const uint8_t *input, uint32_t length) { if (input == NULL || length != sizeof(state)) return SIM_ERR_INVALID_ARGUMENT; const sim_state *saved = (const sim_state *)input; if (saved->created > 1 || saved->loaded > 1 || saved->pending_event > 1) return SIM_ERR_INVALID_ARGUMENT; memcpy(&state, saved, sizeof(state)); return SIM_OK; } static int valid_buffer(const uint8_t *data, uint32_t len) { return len == 0 || data != NULL; } int32_t sim_create(const uint8_t *config, uint32_t config_len) { if (!valid_buffer(config, config_len)) return SIM_ERR_INVALID_ARGUMENT; memset(&state, 0, sizeof(state)); state.created = 1; state.pending_event = 1; return SIM_OK; } int32_t sim_load_workspace(const char *root_path) { if (!state.created) return SIM_ERR_NOT_CREATED; if (root_path == NULL || root_path[0] == '\0') return SIM_ERR_INVALID_ARGUMENT; state.loaded = 1; state.pending_event = 1; return SIM_OK; } int32_t sim_command(const uint8_t *command, uint32_t command_len) { if (!state.created || !state.loaded) return SIM_ERR_INVALID_STATE; if (!valid_buffer(command, command_len) || command_len == 0) return SIM_ERR_INVALID_ARGUMENT; state.pending_event = 1; return SIM_OK; } int32_t sim_step(uint32_t cycles) { if (!state.created || !state.loaded) return SIM_ERR_INVALID_STATE; state.tick += cycles; state.pending_event = 1; return SIM_OK; } uint32_t sim_read_snapshot(uint8_t *out, uint32_t capacity) { const uint32_t size = (uint32_t)sizeof(state.tick); if (out == NULL || capacity < size) return size; memcpy(out, &state.tick, size); return size; } uint32_t sim_read_event(uint8_t *out, uint32_t capacity) { const uint32_t size = 1; if (!state.pending_event) return 0; if (out == NULL || capacity < size) return size; out[0] = 1; state.pending_event = 0; return size; } int32_t sim_export_state(uint8_t *out, uint32_t capacity) { const uint32_t size = (uint32_t)sizeof(state); if (out == NULL || capacity < size) return SIM_ERR_BUFFER_TOO_SMALL; memcpy(out, &state, size); return (int32_t)size; } int32_t sim_import_state(const uint8_t *data, uint32_t len) { if (data == NULL || len != sizeof(state)) return SIM_ERR_INVALID_ARGUMENT; memcpy(&state, data, sizeof(state)); return SIM_OK; } void sim_destroy(void) { memset(&state, 0, sizeof(state)); }