src/cx/properties.h

changeset 924
3c90dfc35f06
parent 923
45da884269c8
--- a/src/cx/properties.h	Thu Oct 10 18:40:27 2024 +0200
+++ b/src/cx/properties.h	Sat Oct 12 19:34:19 2024 +0200
@@ -38,6 +38,7 @@
 
 #include "common.h"
 #include "string.h"
+#include "array_list.h"
 
 struct cx_properties_config_s {
     /**
@@ -50,7 +51,7 @@
      * The character, when appearing at the end of a line, continues that line.
      * This is '\' by default.
      */
-    char continuation;
+    // char continuation; // TODO: line continuation in properties
 
     /**
      * The first comment character.
@@ -104,6 +105,18 @@
      * Input buffer is \c NULL.
      */
     CX_PROPERTIES_NULL_INPUT,
+    /**
+     * The line contains a delimiter, but no key.
+     */
+    CX_PROPERTIES_INVALID_EMPTY_KEY,
+    /**
+     * The line contains data, but no delimiter.
+     */
+    CX_PROPERTIES_INVALID_MISSING_DELIMITER,
+    /**
+     * More internal buffer was needed, but could not be allocated.
+     */
+    CX_PROPERTIES_BUFFER_ALLOC_FAILED,
 };
 
 /**
@@ -121,14 +134,34 @@
     const char *text;
 
     /**
-     * Length of the text buffer.
+     * Size of the text buffer.
      */
-    size_t text_len;
+    size_t text_size;
 
     /**
      * Position in the text buffer.
      */
     size_t text_pos;
+
+    /**
+     * Temporary internal buffer.
+     */
+    char *buf;
+
+    /**
+     * Size of the internal buffer.
+     */
+    size_t buf_size;
+
+    /**
+     * Capacity of the internal buffer.
+     */
+    size_t buf_capacity;
+
+    /**
+     * Internal flags.
+     */
+    int flags;
 };
 
 /**
@@ -138,20 +171,28 @@
 
 
 /**
- * Initialize a properties parser.
+ * Initialize a properties interface.
  *
  * @param prop the properties interface
  * @param config the properties configuration
  * @see cxPropertiesInitDefault()
  */
- __attribute__((__nonnull__))
-static inline void cxPropertiesInit(
-        CxProperties *prop,
-        CxPropertiesConfig config
-) {
-     prop->config = config;
-     prop->text = NULL;
- }
+__attribute__((__nonnull__))
+void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config);
+
+/**
+ * Destroys the properties interface.
+ *
+ * \note Even when you are certain that you did not use the interface in a
+ * way that caused a memory allocation, you should call this function anyway.
+ * Future versions of the library might add features that need additional memory
+ * and you really don't want to search the entire code where you might need
+ * add call to this function.
+ *
+ * @param prop the properties interface
+ */
+__attribute__((__nonnull__))
+void cxPropertiesDestroy(CxProperties *prop);
 
 /**
  * Initialize a properties parser with the default configuration.
@@ -173,35 +214,72 @@
  * @param len the length of the data
  */
 __attribute__((__nonnull__))
-static inline void cxPropertiesInput(
+void cxPropertiesInput(
         CxProperties *prop,
-        const void *buf,
+        const char *buf,
         size_t len
-) {
-    prop->text = buf;
-    prop->text_len = len;
-    prop->text_pos = 0;
-}
+);
+
+/**
+ * Sets a new input buffer after copying the current unprocessed data
+ * to a temporary buffer.
+ *
+ * This temporary buffer is allocated on the heap, unless you specified
+ * a buffer on the stack with #cxPropertiesUseStack().
+ * In that case, the stack buffer is used, until the capacity is not sufficient
+ * anymore.
+ *
+ * When this function is called without any unprocessed data that needs to be
+ * copied, it behaves exactly as #cxPropertiesInput().
+ *
+ * @param prop the properties interface
+ * @param buf a pointer to data
+ * @param len the length of the data
+ * @return non-zero when a memory allocation was necessary but failed
+ */
+__attribute__((__nonnull__))
+int cxPropertiesFill(
+        CxProperties *prop,
+        const char *buf,
+        size_t len
+);
+
+/**
+ * Specifies stack memory that shall be used by #cxPropertiesFill().
+ *
+ * @param prop the properties interface
+ * @param buf a pointer to stack memory
+ * @param capacity the capacity of the stack memory
+ */
+void cxPropertiesUseStack(
+        CxProperties *prop,
+        char *buf,
+        size_t capacity
+);
 
 /**
  * Retrieves the next key/value-pair.
  *
- * This function returns zero as long as there are key/value-pairs
- * found. If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA
- * is returned. You may refill the input buffer with cxPropertiesInput().
+ * This function returns zero as long as there are key/value-pairs found.
+ * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned.
  *
- * When an invalid line is encountered, #CX_PROPERTIES_INVALID_LINE is returned
- * and the position of the input buffer will be the start of the affected line.
+ * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is
+ * returned and the position of the input buffer will be the start of the
+ * affected line. You can then add more data with #cxPropertiesFill().
+ *
+ * \attention The returned strings will point into a buffer that might not be
+ * available later. It is strongly recommended to copy the strings for further
+ * use.
  *
  * @param prop the properties interface
- * @param name a pointer to the cxstring that shall contain the property name
+ * @param key a pointer to the cxstring that shall contain the property name
  * @param value a pointer to the cxstring that shall contain the property value
- * @return Nonzero, if a key/value-pair was successfully retrieved
- * @see ucx_properties_fill()
+ * @return the status code as defined above
+ * @see cxPropertiesFill()
  */
 enum cx_properties_status cxPropertiesNext(
         CxProperties *prop,
-        cxstring *name,
+        cxstring *key,
         cxstring *value
 );
 

mercurial