56 lines
1.9 KiB
C
56 lines
1.9 KiB
C
/**
|
|
* @file id.c
|
|
* @brief Trainlog UUIDv4 identifier generation.
|
|
*/
|
|
|
|
#include "trainlog/id.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <uuid/uuid.h>
|
|
|
|
static bool prefix_is_supported(const char *prefix) {
|
|
/*
|
|
* Keep official creator prefixes deliberately small and explicit.
|
|
* The exchange parser remains more permissive because imported v1 IDs are
|
|
* opaque values governed by the frozen wire-schema syntax.
|
|
*/
|
|
return strcmp(prefix, "ex") == 0 || strcmp(prefix, "se") == 0 || strcmp(prefix, "bo") == 0 ||
|
|
strcmp(prefix, "sy") == 0 || strcmp(prefix, "sxe") == 0 || strcmp(prefix, "sp") == 0 ||
|
|
strcmp(prefix, "spr") == 0 || strcmp(prefix, "spe") == 0 || strcmp(prefix, "spd") == 0 ||
|
|
strcmp(prefix, "spw") == 0 || strcmp(prefix, "pgr") == 0 || strcmp(prefix, "del") == 0 ||
|
|
strcmp(prefix, "sl") == 0 || strcmp(prefix, "slr") == 0 || strcmp(prefix, "sle") == 0 ||
|
|
strcmp(prefix, "med") == 0 || strcmp(prefix, "medr") == 0 || strcmp(prefix, "mdi") == 0;
|
|
}
|
|
|
|
TrainlogStatus trainlog_id_generate(const char *prefix, char *output, size_t output_size) {
|
|
uuid_t value;
|
|
char uuid_text[TRAINLOG_UUID_TEXT_LENGTH + 1U];
|
|
int written;
|
|
|
|
if (prefix == NULL || output == NULL) {
|
|
return TRAINLOG_STATUS_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (!prefix_is_supported(prefix) ||
|
|
output_size < strlen(prefix) + 1U + TRAINLOG_UUID_TEXT_LENGTH + 1U) {
|
|
return TRAINLOG_STATUS_INVALID_ARGUMENT;
|
|
}
|
|
|
|
/*
|
|
* libuuid's uuid_generate_random() creates a random RFC 4122 UUID with the
|
|
* version and variant bits set appropriately for UUID version 4.
|
|
*/
|
|
uuid_generate_random(value);
|
|
uuid_unparse_lower(value, uuid_text);
|
|
|
|
written = snprintf(output, output_size, "%s_%s", prefix, uuid_text);
|
|
|
|
if (written < 0 || (size_t)written >= output_size) {
|
|
return TRAINLOG_STATUS_SYSTEM_ERROR;
|
|
}
|
|
|
|
return TRAINLOG_STATUS_OK;
|
|
}
|