src/cx/properties.h

changeset 928
d2d42cb1d59e
parent 924
3c90dfc35f06
--- a/src/cx/properties.h	Sun Oct 13 15:19:12 2024 +0200
+++ b/src/cx/properties.h	Sun Oct 13 16:44:29 2024 +0200
@@ -38,8 +38,11 @@
 
 #include "common.h"
 #include "string.h"
+#include "map.h"
 #include "array_list.h"
 
+#include <stdio.h>
+
 struct cx_properties_config_s {
     /**
      * The key/value delimiter that shall be used.
@@ -102,6 +105,15 @@
      */
     CX_PROPERTIES_INCOMPLETE_DATA,
     /**
+     * Not used as a status and never returned by any function.
+     *
+     * You can use this enumerator to check for all "good" status results
+     * by checking if the status is less than \c CX_PROPERTIES_OK.
+     *
+     * A "good" status means, that you can refill data and continue parsing.
+     */
+    CX_PROPERTIES_OK,
+    /**
      * Input buffer is \c NULL.
      */
     CX_PROPERTIES_NULL_INPUT,
@@ -117,9 +129,32 @@
      * More internal buffer was needed, but could not be allocated.
      */
     CX_PROPERTIES_BUFFER_ALLOC_FAILED,
+    /**
+     * Initializing the properties source failed.
+     *
+     * @see cx_properties_read_init_func
+     */
+    CX_PROPERTIES_READ_INIT_FAILED,
+    /**
+     * Reading from a properties source failed.
+     *
+     * @see cx_properties_read_func
+     */
+    CX_PROPERTIES_READ_FAILED,
+    /**
+     * Sinking a k/v-pair failed.
+     *
+     * @see cx_properties_sink_func
+     */
+    CX_PROPERTIES_SINK_FAILED,
 };
 
 /**
+ * Typedef for the properties status enum.
+ */
+typedef enum cx_properties_status CxPropertiesStatus;
+
+/**
  * Interface for working with properties data.
  */
 struct cx_properties_s {
@@ -171,6 +206,134 @@
 
 
 /**
+ * Typedef for a properties sink.
+ */
+typedef struct cx_properties_sink_s CxPropertiesSink;
+
+/**
+ * A function that consumes a k/v-pair in a sink.
+ *
+ * The sink could be e.g. a map and the sink function would be calling
+ * a map function to store the k/v-pair.
+ *
+ * @param prop the properties interface that wants to sink a k/v-pair
+ * @param sink the sink
+ * @param key the key
+ * @param value the value
+ * @return zero on success, non-zero when sinking the k/v-pair failed
+ */
+__attribute__((__nonnull__))
+typedef int(*cx_properties_sink_func)(
+        CxProperties *prop,
+        CxPropertiesSink *sink,
+        cxstring key,
+        cxstring value
+);
+
+/**
+ * Defines a sink for k/v-pairs.
+ */
+struct cx_properties_sink_s {
+    /**
+     * The sink object.
+     */
+    void *sink;
+    /**
+     * Optional custom data.
+     */
+    void *data;
+    /**
+     * A function for consuming k/v-pairs into the sink.
+     */
+    cx_properties_sink_func sink_func;
+};
+
+
+/**
+ * Typedef for a properties source.
+ */
+typedef struct cx_properties_source_s CxPropertiesSource;
+
+/**
+ * A function that reads data from a source.
+ *
+ * When the source is depleted, implementations SHALL provide an empty
+ * string in the \p target and return zero.
+ * A non-zero return value is only permitted in case of an error.
+ *
+ * The meaning of the optional parameters is implementation-dependent.
+ *
+ * @param prop the properties interface that wants to read from the source
+ * @param src the source
+ * @param target a string buffer where the read data shall be stored
+ * @return zero on success, non-zero when reading data failed
+ */
+ __attribute__((__nonnull__))
+typedef int(*cx_properties_read_func)(
+        CxProperties *prop,
+        CxPropertiesSource *src,
+        cxstring *target
+);
+
+ /**
+  * A function that may initialize additional memory for the source.
+  *
+  * @param prop the properties interface that wants to read from the source
+  * @param src the source
+  * @return zero when initialization was successful, non-zero otherwise
+  */
+ __attribute__((__nonnull__))
+typedef int(*cx_properties_read_init_func)(
+        CxProperties *prop,
+        CxPropertiesSource *src
+);
+
+/**
+ * A function that cleans memory initialized by the read_init_func.
+ *
+ * @param prop the properties interface that wants to read from the source
+ * @param src the source
+ */
+__attribute__((__nonnull__))
+typedef void(*cx_properties_read_clean_func)(
+        CxProperties *prop,
+        CxPropertiesSource *src
+);
+
+/**
+ * Defines a properties source.
+ */
+struct cx_properties_source_s {
+    /**
+     * The source object.
+     *
+     * For example a file stream or a string.
+     */
+    void *src;
+    /**
+     * Optional additional data pointer.
+     */
+    void *data_ptr;
+    /**
+     * Optional size information.
+     */
+    size_t data_size;
+    /**
+     * A function that reads data from the source.
+     */
+    cx_properties_read_func read_func;
+    /**
+     * Optional function that may prepare the source for reading data.
+     */
+    cx_properties_read_init_func read_init_func;
+    /**
+     * Optional function that cleans additional memory allocated by the
+     * read_init_func.
+     */
+    cx_properties_read_clean_func read_clean_func;
+};
+
+/**
  * Initialize a properties interface.
  *
  * @param prop the properties interface
@@ -251,6 +414,7 @@
  * @param buf a pointer to stack memory
  * @param capacity the capacity of the stack memory
  */
+__attribute__((__nonnull__))
 void cxPropertiesUseStack(
         CxProperties *prop,
         char *buf,
@@ -277,10 +441,95 @@
  * @return the status code as defined above
  * @see cxPropertiesFill()
  */
-enum cx_properties_status cxPropertiesNext(
+__attribute__((__nonnull__, __warn_unused_result__))
+CxPropertiesStatus cxPropertiesNext(
         CxProperties *prop,
         cxstring *key,
         cxstring *value
 );
 
+/**
+ * Creates a properties sink for an UCX map.
+ *
+ * The values stored in the map will be pointers to strings allocated
+ * by #cx_strdup_a().
+ * The default stdlib allocator will be used, unless you specify a custom
+ * allocator in the optional \c data of the sink.
+ *
+ * @param map the map that shall consume the k/v-pairs.
+ * @return the sink
+ * @see cxPropertiesLoad()
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+CxPropertiesSink cxPropertiesMapSink(CxMap *map);
+
+/**
+ * Creates a properties source based on an UCX string.
+ *
+ * @param str the string
+ * @return the properties source
+ * @see cxPropertiesLoad()
+ */
+__attribute__((__warn_unused_result__))
+CxPropertiesSource cxPropertiesStringSource(cxstring str);
+
+/**
+ * Creates a properties source based on C string with the specified length.
+ *
+ * @param str the string
+ * @param len the length
+ * @return the properties source
+ * @see cxPropertiesLoad()
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+CxPropertiesSource cxPropertiesCstrnSource(const char *str, size_t len);
+
+/**
+ * Creates a properties source based on a C string.
+ *
+ * The length will be determined with strlen(), so the string MUST be
+ * zero-terminated.
+ *
+ * @param str the string
+ * @return the properties source
+ * @see cxPropertiesLoad()
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+CxPropertiesSource cxPropertiesCstrSource(const char *str);
+
+/**
+ * Creates a properties source based on an FILE.
+ *
+ * @param file the file
+ * @param chunk_size how many bytes may be read in one operation
+ *
+ * @return the properties source
+ * @see cxPropertiesLoad()
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+CxPropertiesSource cxPropertiesFileSource(FILE *file, size_t chunk_size);
+
+
+/**
+ * Loads properties data from a source and transfers it to a sink.
+ *
+ * This function tries to read as much data from the source as possible.
+ * When the source was completely consumed and at least on k/v-pair was found,
+ * the return value will be #CX_PROPERTIES_NO_ERROR.
+ * When the source was consumed but no k/v-pairs were found, the return value
+ * will be #CX_PROPERTIES_NO_DATA.
+ * The other result codes apply, according to their description.
+ *
+ * @param prop the properties interface
+ * @param sink the sink
+ * @param source the source
+ * @return the status of the last operation
+ */
+__attribute__((__nonnull__))
+CxPropertiesStatus cxPropertiesLoad(
+        CxProperties *prop,
+        CxPropertiesSink sink,
+        CxPropertiesSource source
+);
+
 #endif // UCX_PROPERTIES

mercurial