/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #pragma once #include "error/error.h" #include "yyjson.h" /** * Small helper around a yyjson mutable document, used to build up a save * file's fields one at a time before writing it out. Schema-agnostic - * knows nothing about saveslot_t/savemeta_t; the caller supplies field * names and values. */ typedef struct { yyjson_mut_doc *doc; yyjson_mut_val *root; } savejsonwriterlinux_t; /** * Creates a new mutable JSON document with an empty root object. * * @param writer Writer to initialize. * @return An error if the document can't be allocated. */ errorret_t saveJsonWriterInitLinux(savejsonwriterlinux_t *writer); /** * Adds a "version": field to the root object. */ void saveJsonWriterAddUInt32Linux( savejsonwriterlinux_t *writer, const char_t *key, const uint32_t value ); /** * Adds a float field to the root object (written as a JSON number). */ void saveJsonWriterAddFloatLinux( savejsonwriterlinux_t *writer, const char_t *key, const float_t value ); /** * Adds a "key": field to the root object. */ void saveJsonWriterAddUInt8Linux( savejsonwriterlinux_t *writer, const char_t *key, const uint8_t value ); /** * Adds a string field to the root object. The value is copied into the * document, so the caller's buffer doesn't need to outlive the call. */ void saveJsonWriterAddStringLinux( savejsonwriterlinux_t *writer, const char_t *key, const char_t *value ); /** * Adds a JSON array of booleans as a field on the root object. */ void saveJsonWriterAddBoolArrayLinux( savejsonwriterlinux_t *writer, const char_t *key, const bool_t *values, const size_t count ); /** * Adds a JSON array of unsigned 8-bit integers as a field on the root * object. */ void saveJsonWriterAddUInt8ArrayLinux( savejsonwriterlinux_t *writer, const char_t *key, const uint8_t *values, const size_t count ); /** * Pretty-prints the document to the given file path, creating or * truncating it. * * @param writer Writer holding the document to write. * @param path Destination file path. * @return An error if the write fails. */ errorret_t saveJsonWriterSaveLinux( savejsonwriterlinux_t *writer, const char_t *path ); /** * Frees the document. Safe to call even if saveJsonWriterInitLinux() * failed partway. * * @param writer Writer to dispose. */ void saveJsonWriterDisposeLinux(savejsonwriterlinux_t *writer); /** * Reads and parses a JSON file, returning its root object. * * @param path File path to read. * @param outDoc Receives the parsed document (must be freed via * yyjson_doc_free() once done, regardless of found/error outcome). * @param outRoot Receives the root object, or NULL if not found. * @param found Set to true if the file exists, false if it does not * (not finding the file is not an error). * @return An error if the file exists but fails to parse. */ errorret_t saveJsonReaderOpenLinux( const char_t *path, yyjson_doc **outDoc, yyjson_val **outRoot, bool_t *found ); /** * Reads a uint32 field, falling back to defaultValue if the key is * missing or not a number - a hand-edited file shouldn't hard-fail the * whole load over one bad/missing field. */ uint32_t saveJsonReadUInt32Linux( yyjson_val *root, const char_t *key, const uint32_t defaultValue ); /** * Reads a float field, falling back to defaultValue if the key is * missing or not a number. */ float_t saveJsonReadFloatLinux( yyjson_val *root, const char_t *key, const float_t defaultValue ); /** * Reads a uint8 field, falling back to defaultValue if the key is * missing or not a number. */ uint8_t saveJsonReadUInt8Linux( yyjson_val *root, const char_t *key, const uint8_t defaultValue ); /** * Reads a string field into out, falling back to defaultValue if the key * is missing or not a string. Always null-terminates. */ void saveJsonReadStringLinux( yyjson_val *root, const char_t *key, char_t *out, const size_t maxLen, const char_t *defaultValue ); /** * Reads a JSON array of booleans into out, up to count entries. Missing * key, non-array value, or a shorter array all leave the remaining/all * entries untouched (caller should zero the buffer first). */ void saveJsonReadBoolArrayLinux( yyjson_val *root, const char_t *key, bool_t *out, const size_t count ); /** * Reads a JSON array of unsigned 8-bit integers into out, up to count * entries. Same forgiving semantics as saveJsonReadBoolArrayLinux(). */ void saveJsonReadUInt8ArrayLinux( yyjson_val *root, const char_t *key, uint8_t *out, const size_t count );