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