]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add scols_cell_refer_memory()
authorKarel Zak <kzak@redhat.com>
Wed, 18 Oct 2023 08:20:12 +0000 (10:20 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 23 Oct 2023 19:54:00 +0000 (21:54 +0200)
* allow to use non-string data
* use memcpy() rather than strdup() for data

Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/src/cell.c
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/print.c
libsmartcols/src/smartcolsP.h

index f1d488fe87a058e63f872d07df38011e141c9cf0..f2bac54350e9119ccb29d327cbc0ca97ecbe490b 100644 (file)
@@ -56,27 +56,31 @@ int scols_reset_cell(struct libscols_cell *ce)
  * @ce: a pointer to a struct libscols_cell instance
  * @data: data (used for scols_print_table())
  *
- * Stores a copy of the @str in @ce, the old data are deallocated by free().
+ * Stores a copy of the @data in @ce, the old data are deallocated by free().
  *
  * Returns: 0, a negative value in case of an error.
  */
 int scols_cell_set_data(struct libscols_cell *ce, const char *data)
 {
+       int rc;
+
        if (!ce)
                return -EINVAL;
 
-       return strdup_to_struct_member(ce, data, data);
+       rc = strdup_to_struct_member(ce, data, data);
+       ce->datasiz = ce->data ? strlen(ce->data) + 1: 0;
+       return rc;
 }
 
 /**
  * scols_cell_refer_data:
  * @ce: a pointer to a struct libscols_cell instance
- * @data: data (used for scols_print_table())
+ * @data: string (used for scols_print_table())
  *
- * Adds a reference to @str to @ce. The pointer is deallocated by
- * scols_reset_cell() or scols_unref_line(). This function is mostly designed
- * for situations when the data for the cell are already composed in allocated
- * memory (e.g. asprintf()) to avoid extra unnecessary strdup().
+ * Adds a reference to @data to @ce. The pointer is deallocated by
+ * scols_reset_cell() or scols_unref_line() by free(). This function is mostly
+ * designed for situations when the data for the cell are already composed in
+ * allocated memory (e.g. asprintf()) to avoid extra unnecessary strdup().
  *
  * Returns: 0, a negative value in case of an error.
  */
@@ -86,9 +90,46 @@ int scols_cell_refer_data(struct libscols_cell *ce, char *data)
                return -EINVAL;
        free(ce->data);
        ce->data = data;
+       ce->datasiz = ce->data ? strlen(ce->data) + 1: 0;
+       return 0;
+}
+
+/**
+ * scols_cell_refer_memory:
+ * @ce: a pointer to a struct libscols_cell instance
+ * @data: data
+ * @datasiz: size of the data
+ *
+ * Same like scols_cell_refer_data, but @data does not have to be zero terminated.
+ * The pointer is deallocated by scols_reset_cell() or scols_unref_line() by free().
+ *
+ * The column (for the cell) has to define wrap function which converts the
+ * data to zero terminated string, otherwise library will work with the data as
+ * with string!
+ *
+ * Returns: 0, a negative value in case of an error.
+ */
+int scols_cell_refer_memory(struct libscols_cell *ce, char *data, size_t datasiz)
+{
+       if (!ce)
+               return -EINVAL;
+       free(ce->data);
+       ce->data = data;
+       ce->datasiz = datasiz;
        return 0;
 }
 
+/**
+ * scols_cell_get_datasiz:
+ * @ce: a pointer to a struct libscols_cell instance
+ *
+ * Returns: the current set data size.
+ */
+size_t scols_cell_get_datasiz(struct libscols_cell *ce)
+{
+       return ce ? ce->datasiz : 0;
+}
+
 /**
  * scols_cell_get_data:
  * @ce: a pointer to a struct libscols_cell instance
@@ -251,7 +292,7 @@ int scols_cell_get_alignment(const struct libscols_cell *ce)
  * @dest: a pointer to a struct libscols_cell instance
  * @src: a pointer to an immutable struct libscols_cell instance
  *
- * Copy the contents of @src into @dest.
+ * Copy the contents (data, usewrdata, colors) of @src into @dest.
  *
  * Returns: 0, a negative value in case of an error.
  */
@@ -259,11 +300,19 @@ int scols_cell_copy_content(struct libscols_cell *dest,
                            const struct libscols_cell *src)
 {
        int rc;
+       char *data = NULL;
 
        if (!dest || !src)
                return -EINVAL;
 
-       rc = scols_cell_set_data(dest, scols_cell_get_data(src));
+       if (src->datasiz) {
+               data = malloc(src->datasiz);
+               if (!data)
+                       return -ENOMEM;
+               memcpy(data, src->data, src->datasiz);
+       }
+
+       rc = scols_cell_refer_memory(dest, data, src->datasiz);
        if (!rc)
                rc = scols_cell_set_color(dest, scols_cell_get_color(src));
        if (!rc)
index ab54c0efe53ffec80545f48367ff99a1b79e1a7d..a0b5255cab2b3238c71e52f3bde3d86572bf1497 100644 (file)
@@ -146,7 +146,11 @@ extern int scols_cell_copy_content(struct libscols_cell *dest,
                                   const struct libscols_cell *src);
 extern int scols_cell_set_data(struct libscols_cell *ce, const char *data);
 extern int scols_cell_refer_data(struct libscols_cell *ce, char *data);
+extern int scols_cell_refer_memory(struct libscols_cell *ce, char *data, size_t datasiz);
+
 extern const char *scols_cell_get_data(const struct libscols_cell *ce);
+extern size_t scols_cell_get_datasiz(struct libscols_cell *ce);
+
 extern int scols_cell_set_color(struct libscols_cell *ce, const char *color);
 extern const char *scols_cell_get_color(const struct libscols_cell *ce);
 
@@ -159,6 +163,7 @@ extern int scols_cell_set_userdata(struct libscols_cell *ce, void *data);
 
 extern int scols_cmpstr_cells(struct libscols_cell *a,
                              struct libscols_cell *b, void *data);
+
 /* column.c */
 extern int scols_column_is_tree(const struct libscols_column *cl);
 extern int scols_column_is_trunc(const struct libscols_column *cl);
index 4fa6df60405d0c3b045c0e733fbc047d70bdbfe3..909139884ea7e49ef9455a715bdfa1df8102ea15 100644 (file)
@@ -217,4 +217,6 @@ SMARTCOLS_2.39 {
 
 SMARTCOLS_2.40 {
        scols_table_get_cursor;
+       scols_cell_refer_memory;
+       scols_cell_get_datasiz;
 } SMARTCOLS_2.39;
index 6f2cb5abc413f500f8dcadeca186ef50c2c04bf4..20f86f44e957c16a1e5a59ec52ab3c32a171af40 100644 (file)
@@ -656,6 +656,7 @@ int __cursor_to_buffer(struct libscols_table *tb,
                     int cal)
 {
        const char *data = NULL;
+       size_t datasiz = 0;
        struct libscols_cell *ce;
        struct libscols_line *ln;
        struct libscols_column *cl;
@@ -681,9 +682,13 @@ int __cursor_to_buffer(struct libscols_table *tb,
                        if (rc < 0)
                                return rc;
                        data = x;
+                       if (data && *data)
+                               datasiz = strlen(data);
                        rc = 0;
-               } else
+               } else {
                        data = scols_cell_get_data(ce);
+                       datasiz = scols_cell_get_datasiz(ce);
+               }
        }
 
        if (!scols_column_is_tree(cl))
@@ -710,8 +715,9 @@ int __cursor_to_buffer(struct libscols_table *tb,
        if (!rc && (ln->parent || cl->is_groups) && !scols_table_is_json(tb))
                ul_buffer_save_pointer(buf, SCOLS_BUFPTR_TREEEND);
 notree:
-       if (!rc && data)
-               rc = ul_buffer_append_string(buf, data);
+       if (!rc && data && datasiz)
+               rc = ul_buffer_append_data(buf, data, datasiz);
+
        return rc;
 }
 
index 3abe8803a0c9b34f665c0a2352e64df3b274cdd7..1ffdf23f60c2c8683082c1b09bab39ef8fa06753 100644 (file)
@@ -80,6 +80,7 @@ struct libscols_symbols {
  */
 struct libscols_cell {
        char    *data;
+       size_t  datasiz;
        char    *color;
        void    *userdata;
        int     flags;