1 /** @file 2 A general structure for extracting hierarchical data from the devices; 3 typically key-value pairs, but allows for more rich data as well. 4 5 Copyright (C) 2015 by Erkki Seppälä <flux@modeemi.fi> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef INCLUDE_DATA_H_ 22 #define INCLUDE_DATA_H_ 23 24 #include <stddef.h> 25 26 typedef enum { 27 DATA_DATA, /**< pointer to data is stored */ 28 DATA_INT, /**< pointer to integer is stored */ 29 DATA_DOUBLE, /**< pointer to a double is stored */ 30 DATA_STRING, /**< pointer to a string is stored */ 31 DATA_ARRAY, /**< pointer to an array of values is stored */ 32 DATA_COUNT, /**< invalid */ 33 DATA_FORMAT, /**< indicates the following value is formatted */ 34 DATA_COND, /**< add data only if condition is true, skip otherwise */ 35 } data_type_t; 36 37 typedef struct data_array { 38 int num_values; 39 data_type_t type; 40 void *values; 41 } data_array_t; 42 43 typedef union data_value { 44 int v_int; 45 double v_dbl; 46 void *v_ptr; 47 } data_value_t; 48 49 typedef struct data { 50 char *key; 51 char *pretty_key; /**< the name used for displaying data to user in with a nicer name */ 52 data_type_t type; 53 char *format; /**< if not null, contains special formatting string */ 54 data_value_t value; 55 unsigned retain; /**< incremented on data_retain, data_free only frees if this is zero */ 56 struct data *next; /**< chaining to the next element in the linked list; NULL indicates end-of-list */ 57 } data_t; 58 59 /** Constructs a structured data object. 60 61 Example: 62 data_make( 63 "key", "Pretty key", DATA_INT, 42, 64 "others", "More data", DATA_DATA, data_make("foo", DATA_DOUBLE, 42.0, NULL), 65 "zoom", NULL, data_array(2, DATA_STRING, (char*[]){"hello", "World"}), 66 "double", "Double", DATA_DOUBLE, 10.0/3, 67 NULL); 68 69 Most of the time the function copies perhaps what you expect it to. Things 70 it copies: 71 - string contents for keys and values 72 - numerical arrays 73 - string arrays (copied deeply) 74 75 Things it moves: 76 - recursive data_t* and data_array_t* values 77 78 The rule is: if an object is boxed (look at the dmt structure in the data.c) 79 and it has a array_elementwise_import in the same structure, then it is 80 copied deeply. Otherwise, it is copied shallowly. 81 82 @param key Name of the first value to put in. 83 @param pretty_key Pretty name for the key. Use "" if to omit pretty label for this field completely, 84 or NULL if to use key name for it. 85 @param ... Type and then value of the item to put in, followed by the rest of the 86 key-type-values. The list is terminated with a NULL. 87 88 @return A constructed data_t* object or NULL if there was a memory allocation error. 89 */ 90 data_t *data_make(const char *key, const char *pretty_key, ...); 91 92 /** Adds to a structured data object, by appending data. 93 94 @see data_make() 95 */ 96 data_t *data_append(data_t *first, const char *key, const char *pretty_key, ...); 97 98 /** Adds to a structured data object, by prepending data. 99 100 @see data_make() 101 */ 102 data_t *data_prepend(data_t *first, const char *key, const char *pretty_key, ...); 103 104 /** Constructs an array from given data of the given uniform type. 105 106 @param num_values The number of values to be copied. 107 @param type The type of values to be copied. 108 @param ptr The contents pointed by the argument are copied in. 109 110 @return The constructed data array object, typically placed inside a data_t or NULL 111 if there was a memory allocation error. 112 */ 113 data_array_t *data_array(int num_values, data_type_t type, void *ptr); 114 115 /** Releases a data array. */ 116 void data_array_free(data_array_t *array); 117 118 /** Retain a structure object, returns the structure object passed in. */ 119 data_t *data_retain(data_t *data); 120 121 /** Releases a structure object if retain is zero, decrement retain otherwise. */ 122 void data_free(data_t *data); 123 124 struct data_output; 125 126 typedef struct data_output { 127 void (*print_data)(struct data_output *output, data_t *data, char const *format); 128 void (*print_array)(struct data_output *output, data_array_t *data, char const *format); 129 void (*print_string)(struct data_output *output, const char *data, char const *format); 130 void (*print_double)(struct data_output *output, double data, char const *format); 131 void (*print_int)(struct data_output *output, int data, char const *format); 132 void (*output_start)(struct data_output *output, char const *const *fields, int num_fields); 133 void (*output_flush)(struct data_output *output); 134 void (*output_free)(struct data_output *output); 135 } data_output_t; 136 137 /** Setup known field keys and start output, used by CSV only. 138 139 @param output the data_output handle from data_output_x_create 140 @param fields the list of fields to accept and expect. Array is copied, but the actual 141 strings not. The list may contain duplicates and they are eliminated. 142 @param num_fields number of fields 143 */ 144 void data_output_start(struct data_output *output, char const *const *fields, int num_fields); 145 146 /** Prints a structured data object, flushes the output if applicable. */ 147 void data_output_print(struct data_output *output, data_t *data); 148 149 void data_output_free(struct data_output *output); 150 151 /* data output helpers */ 152 153 void print_value(data_output_t *output, data_type_t type, data_value_t value, char const *format); 154 155 void print_array_value(data_output_t *output, data_array_t *array, char const *format, int idx); 156 157 size_t data_print_jsons(data_t *data, char *dst, size_t len); 158 159 #endif // INCLUDE_DATA_H_ 160