「‍」 Lingenic

hsv

(⤓.h ◇.h); γ ≜ [2026-01-27T073206.165, 2026-01-27T073206.165] ∧ |γ| = 1

/*
 * Copyright 2026 Danslav Slavenskoj, Lingenic LLC
 * License: CC0 1.0 - Public Domain
 * https://creativecommons.org/publicdomain/zero/1.0/
 * You may use this code for any purpose without attribution.
 *
 * Spec: https://hsvfile.com
 * Repo: https://github.com/LingenicLLC/HSV
 */

#ifndef HSV_H
#define HSV_H

#include <stddef.h>

/* Control characters */
#define HSV_SOH '\x01'  /* Start of Header */
#define HSV_STX '\x02'  /* Start of Text (data block) */
#define HSV_ETX '\x03'  /* End of Text */
#define HSV_EOT '\x04'  /* End of Transmission */
#define HSV_SO  '\x0e'  /* Shift Out (start nested) */
#define HSV_SI  '\x0f'  /* Shift In (end nested) */
#define HSV_DLE '\x10'  /* Data Link Escape (binary mode) */
#define HSV_FS  '\x1c'  /* File/Record Separator */
#define HSV_GS  '\x1d'  /* Group/Array Separator */
#define HSV_RS  '\x1e'  /* Record/Property Separator */
#define HSV_US  '\x1f'  /* Unit/Key-Value Separator */

/* Value types */
typedef enum {
    HSV_TYPE_STRING,
    HSV_TYPE_ARRAY,
    HSV_TYPE_OBJECT
} hsv_type_t;

/* Forward declarations */
typedef struct hsv_value hsv_value_t;
typedef struct hsv_pair hsv_pair_t;
typedef struct hsv_document hsv_document_t;

/* Key-value pair */
struct hsv_pair {
    char *key;
    hsv_value_t *value;
};

/* HSV value (string, array, or object) */
struct hsv_value {
    hsv_type_t type;
    union {
        char *string;
        struct {
            hsv_value_t **items;
            size_t count;
        } array;
        struct {
            hsv_pair_t *pairs;
            size_t count;
        } object;
    } data;
};

/* HSV document */
struct hsv_document {
    hsv_value_t *header;  /* NULL if no header */
    hsv_value_t **records;
    size_t record_count;
};

/* Parse HSV text into a document. Caller must free with hsv_free_document(). */
hsv_document_t *hsv_parse(const char *text);

/* Free a document and all its contents */
void hsv_free_document(hsv_document_t *doc);

/* Free a value and all its contents */
void hsv_free_value(hsv_value_t *value);

/* Helper: get string value from object by key. Returns NULL if not found or not a string. */
const char *hsv_get_string(hsv_value_t *obj, const char *key);

/* Helper: get value from object by key. Returns NULL if not found. */
hsv_value_t *hsv_get(hsv_value_t *obj, const char *key);

#endif /* HSV_H */