SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDS_dataprep.c
Go to the documentation of this file.
1/**
2 * @file SDDS_dataprep.c
3 * @brief Functions for preparing SDDS data sets
4 *
5 * @details Implements utility routines used prior to writing or
6 * manipulating SDDS tables, such as allocating column flags and starting
7 * new pages.
8 *
9 * @copyright
10 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
11 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
12 *
13 * @license
14 * This file is distributed under the terms of the Software License Agreement
15 * found in the file LICENSE included with this distribution.
16 *
17 * @authors
18 * M. Borland,
19 * C. Saunders,
20 * R. Soliday,
21 * H. Shang
22 */
23
24#include "SDDS.h"
25#include "SDDS_internal.h"
26#include "mdb.h"
27
28#undef DEBUG
29
30/**
31 * Allocates memory for column flags and column order arrays in the specified SDDS dataset.
32 *
33 * This function allocates memory for the `column_flag` and `column_order` arrays based on the number of columns
34 * defined in the dataset's layout. It initializes `column_flag` to 1 and `column_order` to 0 and 1 respectively.
35 *
36 * @param SDDS_target Pointer to the SDDS_DATASET structure where column flags will be allocated.
37 *
38 * @return Returns 1 on successful allocation and initialization. On failure, returns 0 and records an error message.
39 *
40 * @sa SDDS_Malloc, SDDS_SetMemory, SDDS_SetError
41 */
43 if (SDDS_target->layout.n_columns &&
44 ((!(SDDS_target->column_flag = (int32_t *)SDDS_Malloc(sizeof(int32_t) * SDDS_target->layout.n_columns)) ||
45 !(SDDS_target->column_order = (int32_t *)SDDS_Malloc(sizeof(int32_t) * SDDS_target->layout.n_columns))) ||
46 (!SDDS_SetMemory(SDDS_target->column_flag, SDDS_target->layout.n_columns, SDDS_LONG, (int32_t)1, (int32_t)0) ||
47 !SDDS_SetMemory(SDDS_target->column_order, SDDS_target->layout.n_columns, SDDS_LONG, (int32_t)0, (int32_t)1)))) {
48 SDDS_SetError("Unable to allocate column flags--memory allocation failure (SDDS_AllocateColumnFlags)");
49 return 0;
50 }
51 return 1;
52}
53
54/**
55 * Initializes an SDDS_DATASET structure in preparation for inserting data into a new table.
56 *
57 * This function prepares the specified SDDS dataset for data insertion by initializing necessary data structures
58 * and allocating memory based on the expected number of rows. It must be preceded by a call to `SDDS_InitializeOutput`.
59 * `SDDS_StartPage` can be called multiple times to begin writing additional tables within the dataset. After initializing
60 * a page, `SDDS_WriteTable` should be used to write the table to disk.
61 *
62 * @param SDDS_dataset Pointer to the SDDS_DATASET structure representing the data set.
63 * @param expected_n_rows The expected number of rows in the data table. This value is used to preallocate memory for storing data values.
64 * If `expected_n_rows` is less than or equal to zero, it defaults to 1.
65 *
66 * @return Returns 1 on successful initialization. On failure, returns 0 and records an error message.
67 *
68 * @sa SDDS_InitializeOutput, SDDS_WriteTable, SDDS_SetError
69 */
70int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows) {
71 SDDS_LAYOUT *layout;
72 int64_t i;
73 int32_t size;
74
75 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_StartPage"))
76 return (0);
77 if ((SDDS_dataset->writing_page) && (SDDS_dataset->layout.data_mode.fixed_row_count)) {
78 if (!SDDS_UpdateRowCount(SDDS_dataset))
79 return (0);
80 }
81 if (!SDDS_RestoreLayout(SDDS_dataset)) {
82 SDDS_SetError("Unable to start page--couldn't restore layout (SDDS_StartPage)");
83 return (0);
84 }
85 if (expected_n_rows <= 0)
86 expected_n_rows = 1;
87 SDDS_dataset->n_rows_written = 0;
88 SDDS_dataset->last_row_written = -1;
89 SDDS_dataset->writing_page = 0;
90 SDDS_dataset->first_row_in_mem = 0;
91 layout = &SDDS_dataset->layout;
92 if (SDDS_dataset->page_started == 0) {
93 if (layout->n_parameters) {
94 if (!(SDDS_dataset->parameter = (void **)calloc(sizeof(*SDDS_dataset->parameter), layout->n_parameters))) {
95 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
96 return (0);
97 }
98 for (i = 0; i < layout->n_parameters; i++) {
99 if (!(SDDS_dataset->parameter[i] = (void *)calloc(SDDS_type_size[layout->parameter_definition[i].type - 1], 1))) {
100 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
101 return (0);
102 }
103 }
104 }
105 if (layout->n_arrays) {
106 if (!(SDDS_dataset->array = (SDDS_ARRAY *)calloc(sizeof(*SDDS_dataset->array), layout->n_arrays))) {
107 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
108 return (0);
109 }
110 }
111 if (layout->n_columns) {
112 if (!(SDDS_dataset->data = (void **)calloc(sizeof(*SDDS_dataset->data), layout->n_columns))) {
113 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
114 return (0);
115 }
116 SDDS_dataset->row_flag = NULL;
117 if (expected_n_rows) {
118 if (!(SDDS_dataset->row_flag = (int32_t *)SDDS_Malloc(sizeof(int32_t) * expected_n_rows))) {
119 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
120 return (0);
121 }
122 for (i = 0; i < layout->n_columns; i++) {
123 if (!(SDDS_dataset->data[i] = (void *)calloc(expected_n_rows, SDDS_type_size[layout->column_definition[i].type - 1]))) {
124 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
125 return (0);
126 }
127 }
128 }
129 SDDS_dataset->n_rows_allocated = expected_n_rows;
130 if (!(SDDS_dataset->column_flag = (int32_t *)SDDS_Realloc(SDDS_dataset->column_flag, sizeof(int32_t) * layout->n_columns)) ||
131 !(SDDS_dataset->column_order = (int32_t *)SDDS_Realloc(SDDS_dataset->column_order, sizeof(int32_t) * layout->n_columns))) {
132 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
133 return (0);
134 }
135 }
136 } else if (SDDS_dataset->n_rows_allocated >= expected_n_rows && layout->n_columns) {
137 for (i = 0; i < layout->n_columns; i++) {
138 if (SDDS_dataset->data[i] && layout->column_definition[i].type == SDDS_STRING)
139 SDDS_FreeStringArray(SDDS_dataset->data[i], SDDS_dataset->n_rows_allocated);
140 }
141 } else if (SDDS_dataset->n_rows_allocated < expected_n_rows && layout->n_columns) {
142 if (!SDDS_dataset->data) {
143 if (!(SDDS_dataset->column_flag = (int32_t *)SDDS_Realloc(SDDS_dataset->column_flag, sizeof(int32_t) * layout->n_columns)) ||
144 !(SDDS_dataset->column_order = (int32_t *)SDDS_Realloc(SDDS_dataset->column_order, sizeof(int32_t) * layout->n_columns)) ||
145 !(SDDS_dataset->data = (void **)calloc(layout->n_columns, sizeof(*SDDS_dataset->data)))) {
146 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
147 return (0);
148 }
149 }
150 for (i = 0; i < layout->n_columns; i++) {
151 size = SDDS_type_size[layout->column_definition[i].type - 1];
152 if (SDDS_dataset->data[i] && layout->column_definition[i].type == SDDS_STRING)
153 SDDS_FreeStringArray(SDDS_dataset->data[i], SDDS_dataset->n_rows_allocated);
154 if (!(SDDS_dataset->data[i] = (void *)SDDS_Realloc(SDDS_dataset->data[i], expected_n_rows * size))) {
155 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
156 return (0);
157 }
158 SDDS_ZeroMemory((char *)SDDS_dataset->data[i] + size * SDDS_dataset->n_rows_allocated, size * (expected_n_rows - SDDS_dataset->n_rows_allocated));
159 }
160 if (!(SDDS_dataset->row_flag = (int32_t *)SDDS_Realloc(SDDS_dataset->row_flag, sizeof(int32_t) * expected_n_rows))) {
161 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_StartPage)");
162 return (0);
163 }
164 SDDS_dataset->n_rows_allocated = expected_n_rows;
165 }
166 if (SDDS_dataset->n_rows_allocated && layout->n_columns && !SDDS_SetMemory(SDDS_dataset->row_flag, SDDS_dataset->n_rows_allocated, SDDS_LONG, (int32_t)1, (int32_t)0)) {
167 SDDS_SetError("Unable to start page--memory initialization failure (SDDS_StartPage)");
168 return (0);
169 }
170 if (layout->n_columns && (!SDDS_SetMemory(SDDS_dataset->column_flag, layout->n_columns, SDDS_LONG, (int32_t)1, (int32_t)0) ||
171 !SDDS_SetMemory(SDDS_dataset->column_order, layout->n_columns, SDDS_LONG, (int32_t)0, (int32_t)1))) {
172 SDDS_SetError("Unable to start page--memory initialization failure (SDDS_StartPage)");
173 return (0);
174 }
175 SDDS_dataset->n_of_interest = layout->n_columns;
176 SDDS_dataset->page_number++;
177 SDDS_dataset->page_started = 1;
178 SDDS_dataset->n_rows = 0;
179 return (1);
180}
181
182/**
183 * Clears the current page in the SDDS dataset, resetting all data and flags.
184 *
185 * This function resets the current data page in the specified SDDS dataset by reinitializing column flags and order.
186 * It frees any allocated string data and zeros out the data arrays, parameters, and arrays in the dataset.
187 *
188 * @param SDDS_dataset Pointer to the SDDS_DATASET structure whose current page will be cleared.
189 *
190 * @return Returns 1 on successful clearing of the page. On failure, returns 0 and records an error message.
191 *
192 * @sa SDDS_SetMemory, SDDS_FreeStringData, SDDS_ZeroMemory
193 */
194int32_t SDDS_ClearPage(SDDS_DATASET *SDDS_dataset) {
195 SDDS_LAYOUT *layout;
196 int64_t i;
197 int32_t size;
198
199 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ClearPage"))
200 return 0;
201 layout = &SDDS_dataset->layout;
202
203 if (layout->n_columns && ((SDDS_dataset->column_flag && !SDDS_SetMemory(SDDS_dataset->column_flag, layout->n_columns, SDDS_LONG, (int32_t)1, (int32_t)0)) ||
204 ((SDDS_dataset->column_order && !SDDS_SetMemory(SDDS_dataset->column_order, layout->n_columns, SDDS_LONG, (int32_t)0, (int32_t)1))))) {
205 SDDS_SetError("Unable to start page--memory initialization failure (SDDS_ClearPage)");
206 return 0;
207 }
208 SDDS_FreeStringData(SDDS_dataset);
209 if (SDDS_dataset->data) {
210 for (i = 0; i < layout->n_columns; i++) {
211 size = SDDS_type_size[layout->column_definition[i].type - 1];
212 if (SDDS_dataset->data[i])
213 SDDS_ZeroMemory(SDDS_dataset->data[i], size * SDDS_dataset->n_rows_allocated);
214 }
215 }
216 if (SDDS_dataset->parameter) {
217 for (i = 0; i < layout->n_parameters; i++) {
218 size = SDDS_type_size[layout->parameter_definition[i].type - 1];
219 SDDS_ZeroMemory(SDDS_dataset->parameter[i], size);
220 }
221 }
222 for (i = 0; i < layout->n_arrays; i++) {
223 size = SDDS_type_size[layout->array_definition[i].type - 1];
224 if (SDDS_dataset->array && SDDS_dataset->array[i].data && SDDS_dataset->array[i].elements)
225 SDDS_ZeroMemory(SDDS_dataset->array[i].data, size * SDDS_dataset->array[i].elements);
226 }
227 return 1;
228}
229
230/**
231 * Shortens the data table in the SDDS dataset to a specified number of rows.
232 *
233 * This function reduces the number of allocated rows in the specified SDDS dataset to the given `rows` count.
234 * It reallocates memory for each column's data array and the row flags, freeing existing data as necessary.
235 * All data is reset, and the number of rows is set to zero.
236 *
237 * @param SDDS_dataset Pointer to the SDDS_DATASET structure whose table will be shortened.
238 * @param rows The new number of rows to allocate in the table. If `rows` is less than or equal to zero, it defaults to 1.
239 *
240 * @return Returns 1 on successful reallocation and initialization. On failure, returns 0 and records an error message.
241 *
242 * @sa SDDS_Realloc, SDDS_SetMemory, SDDS_Free, SDDS_SetError
243 */
244int32_t SDDS_ShortenTable(SDDS_DATASET *SDDS_dataset, int64_t rows) {
245 SDDS_LAYOUT *layout;
246 int64_t i, size;
247
248 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ShortenTable"))
249 return (0);
250 layout = &SDDS_dataset->layout;
251 if (!SDDS_dataset->data && !(SDDS_dataset->data = (void **)calloc(layout->n_columns, sizeof(*SDDS_dataset->data)))) {
252 SDDS_SetError("Unable to start page--memory allocation failure (SDDS_ShortenTable)");
253 return (0);
254 }
255 if (rows <= 0)
256 rows = 1;
257 for (i = 0; i < layout->n_columns; i++) {
258 size = SDDS_type_size[layout->column_definition[i].type - 1];
259 if (SDDS_dataset->data[i])
260 free(SDDS_dataset->data[i]);
261 if (!(SDDS_dataset->data[i] = (void *)calloc(rows, size))) {
262 SDDS_SetError("Unable to shorten page--memory allocation failure (SDDS_ShortenTable)");
263 return (0);
264 }
265 }
266 if (SDDS_dataset->row_flag)
267 free(SDDS_dataset->row_flag);
268 if (!(SDDS_dataset->row_flag = (int32_t *)malloc(rows * sizeof(int32_t)))) {
269 SDDS_SetError("Unable to shorten page--memory allocation failure (SDDS_ShortenTable)");
270 return (0);
271 }
272 SDDS_dataset->n_rows_allocated = rows;
273 /* Shorten table is not exactly true. It is really deleting all the rows and then allocating new space.
274 if (SDDS_dataset->n_rows > rows) {
275 SDDS_dataset->n_rows = rows;
276 }
277 */
278 SDDS_dataset->n_rows = 0;
279
280 if (!SDDS_SetMemory(SDDS_dataset->row_flag, SDDS_dataset->n_rows_allocated, SDDS_LONG, (int32_t)1, (int32_t)0) ||
281 !SDDS_SetMemory(SDDS_dataset->column_flag, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)1, (int32_t)0) ||
282 !SDDS_SetMemory(SDDS_dataset->column_order, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)0, (int32_t)1)) {
283 SDDS_SetError("Unable to shorten page--memory initialization failure (SDDS_ShortenTable)");
284 return (0);
285 }
286 return (1);
287}
288
289/**
290 * Increases the number of allocated rows in the SDDS dataset's data table.
291 *
292 * This function extends the allocated memory for the data table in the specified SDDS dataset by adding
293 * the specified number of additional rows. It reallocates memory for each column's data array and the row flags,
294 * initializing the newly allocated memory to zero.
295 *
296 * @param SDDS_dataset Pointer to the SDDS_DATASET structure whose table will be lengthened.
297 * @param n_additional_rows The number of additional rows to allocate. If `n_additional_rows` is less than zero, it is treated as zero.
298 *
299 * @return Returns 1 on successful reallocation and initialization. On failure, returns 0 and records an error message.
300 *
301 * @sa SDDS_Realloc, SDDS_SetMemory, SDDS_ZeroMemory, SDDS_SetError
302 */
303int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows) {
304 SDDS_LAYOUT *layout;
305 int64_t i, size;
306 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_LengthenTable"))
307 return (0);
308 layout = &SDDS_dataset->layout;
309#if defined(DEBUG)
310 fprintf(stderr, "table size being increased from %" PRId64 " to %" PRId64 " rows\n", SDDS_dataset->n_rows_allocated, SDDS_dataset->n_rows_allocated + n_additional_rows);
311#endif
312 if (!SDDS_dataset->data && !(SDDS_dataset->data = (void **)calloc(layout->n_columns, sizeof(*SDDS_dataset->data)))) {
313 SDDS_SetError("Unable to start page--memory allocation failure1 (SDDS_LengthenTable)");
314 return (0);
315 }
316 if (n_additional_rows < 0)
317 n_additional_rows = 0;
318 for (i = 0; i < layout->n_columns; i++) {
319 size = SDDS_type_size[layout->column_definition[i].type - 1];
320 if (!(SDDS_dataset->data[i] = (void *)SDDS_Realloc(SDDS_dataset->data[i], (SDDS_dataset->n_rows_allocated + n_additional_rows) * size))) {
321 SDDS_SetError("Unable to lengthen page--memory allocation failure2 (SDDS_LengthenTable)");
322 return (0);
323 }
324 SDDS_ZeroMemory((char *)SDDS_dataset->data[i] + size * SDDS_dataset->n_rows_allocated, size * n_additional_rows);
325 }
326 if (!(SDDS_dataset->row_flag = (int32_t *)SDDS_Realloc(SDDS_dataset->row_flag, (SDDS_dataset->n_rows_allocated + n_additional_rows) * sizeof(int32_t)))) {
327 SDDS_SetError("Unable to lengthen page--memory allocation failure3 (SDDS_LengthenTable)");
328 return (0);
329 }
330 SDDS_dataset->n_rows_allocated += n_additional_rows;
331
332 if (!SDDS_SetMemory(SDDS_dataset->row_flag, SDDS_dataset->n_rows_allocated, SDDS_LONG, (int32_t)1, (int32_t)0) ||
333 !SDDS_SetMemory(SDDS_dataset->column_flag, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)1, (int32_t)0) ||
334 !SDDS_SetMemory(SDDS_dataset->column_order, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)0, (int32_t)1)) {
335 SDDS_SetError("Unable to lengthen page--memory initialization failure4 (SDDS_LengthenTable)");
336 return (0);
337 }
338 return (1);
339}
340
341/**
342 * Sets the values of one or more parameters for the current data table in an SDDS dataset.
343 *
344 * This function assigns values to parameters in the current data table of the specified SDDS dataset. It must be preceded by a call
345 * to `SDDS_StartPage` to initialize the table. The function can be called multiple times to set parameters for different tables,
346 * but `SDDS_WriteTable` should be used to write each table to disk.
347 *
348 * @param SDDS_dataset Pointer to the SDDS_DATASET structure representing the data set.
349 * @param mode A bitwise combination of the following constants:
350 * - `SDDS_SET_BY_INDEX`: Specify parameters by their index.
351 * - `SDDS_SET_BY_NAME`: Specify parameters by their name.
352 * - `SDDS_PASS_BY_VALUE`: Pass parameter values by value.
353 * - `SDDS_PASS_BY_REFERENCE`: Pass parameter values by reference.
354 *
355 * Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set to indicate how parameters are identified.
356 * Additionally, exactly one of `SDDS_PASS_BY_VALUE` or `SDDS_PASS_BY_REFERENCE` must be set to indicate how parameter
357 * values are provided.
358 *
359 * The syntax for the four possible mode combinations is as follows:
360 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_VALUE`:
361 * `int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index1, value1, int32_t index2, value2, ..., -1)`
362 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_REFERENCE`:
363 * `int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index1, void *data1, int32_t index2, void *data2, ..., -1)`
364 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_VALUE`:
365 * `int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name1, value1, char *name2, value2, ..., NULL)`
366 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_REFERENCE`:
367 * `int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name1, void *data1, char *name2, void *data2, ..., NULL)`
368 *
369 * **Note:** For parameters of type `SDDS_STRING`, passing by value means passing a `char *`, whereas passing by reference means passing a `char **`.
370 *
371 * @return Returns 1 on success. On failure, returns 0 and records an error message.
372 *
373 * @sa SDDS_StartPage, SDDS_WriteTable, SDDS_SetError, SDDS_GetParameterIndex, va_start, va_arg, va_end
374 */
375int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode, ...) {
376 va_list argptr;
377 int32_t index, retval;
378 SDDS_LAYOUT *layout;
379 char *name;
380 char s[SDDS_MAXLINE];
381
382 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetParameters"))
383 return (0);
384 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) || !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
385 SDDS_SetError("Unable to set parameter values--unknown mode (SDDS_SetParameters)");
386 return (0);
387 }
388
389 va_start(argptr, mode);
390 layout = &SDDS_dataset->layout;
391
392 /* variable arguments are pairs of (index, value), where index is a int32_t integer */
393 retval = -1;
394 do {
395 if (mode & SDDS_SET_BY_INDEX) {
396 if ((index = va_arg(argptr, int32_t)) == -1) {
397 retval = 1;
398 break;
399 }
400 if (index < 0 || index >= layout->n_parameters) {
401 SDDS_SetError("Unable to set parameter values--index out of range (SDDS_SetParameters)");
402 retval = 0;
403 break;
404 }
405 } else {
406 if ((name = va_arg(argptr, char *)) == NULL) {
407 retval = 1;
408 break;
409 }
410 if ((index = SDDS_GetParameterIndex(SDDS_dataset, name)) < 0) {
411 sprintf(s, "Unable to set parameter values--name %s not recognized (SDDS_SetParameters)", name);
412 SDDS_SetError(s);
413 retval = 0;
414 break;
415 }
416 }
417 switch (layout->parameter_definition[index].type) {
418 case SDDS_SHORT:
419 if (mode & SDDS_PASS_BY_VALUE)
420 *((short *)SDDS_dataset->parameter[index]) = (short)va_arg(argptr, int);
421 else
422 *((short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, short *));
423 break;
424 case SDDS_USHORT:
425 if (mode & SDDS_PASS_BY_VALUE)
426 *((unsigned short *)SDDS_dataset->parameter[index]) = (unsigned short)va_arg(argptr, unsigned int);
427 else
428 *((unsigned short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, unsigned short *));
429 break;
430 case SDDS_LONG:
431 if (mode & SDDS_PASS_BY_VALUE)
432 *((int32_t *)SDDS_dataset->parameter[index]) = (int32_t)va_arg(argptr, int32_t);
433 else
434 *((int32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, int32_t *));
435 break;
436 case SDDS_ULONG:
437 if (mode & SDDS_PASS_BY_VALUE)
438 *((uint32_t *)SDDS_dataset->parameter[index]) = (uint32_t)va_arg(argptr, uint32_t);
439 else
440 *((uint32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, uint32_t *));
441 break;
442 case SDDS_LONG64:
443 if (mode & SDDS_PASS_BY_VALUE)
444 *((int64_t *)SDDS_dataset->parameter[index]) = (int64_t)va_arg(argptr, int64_t);
445 else
446 *((int64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, int64_t *));
447 break;
448 case SDDS_ULONG64:
449 if (mode & SDDS_PASS_BY_VALUE)
450 *((uint64_t *)SDDS_dataset->parameter[index]) = (uint64_t)va_arg(argptr, uint64_t);
451 else
452 *((uint64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, uint64_t *));
453 break;
454 case SDDS_FLOAT:
455 if (mode & SDDS_PASS_BY_VALUE)
456 *((float *)SDDS_dataset->parameter[index]) = (float)va_arg(argptr, double);
457 else
458 *((float *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, float *));
459 break;
460 case SDDS_DOUBLE:
461 if (mode & SDDS_PASS_BY_VALUE)
462 *((double *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
463 else
464 *((double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
465 break;
466 case SDDS_LONGDOUBLE:
467 if (mode & SDDS_PASS_BY_VALUE)
468 *((long double *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
469 else
470 *((long double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
471 break;
472 case SDDS_STRING:
473 if (*(char **)SDDS_dataset->parameter[index])
474 free(*(char **)SDDS_dataset->parameter[index]);
475 if (mode & SDDS_PASS_BY_VALUE) {
476 if (!SDDS_CopyString((char **)SDDS_dataset->parameter[index], va_arg(argptr, char *))) {
477 SDDS_SetError("Unable to set string parameter value--allocation failure (SDDS_SetParameters)");
478 retval = 0;
479 }
480 } else {
481 if (!SDDS_CopyString((char **)SDDS_dataset->parameter[index], *(va_arg(argptr, char **)))) {
482 SDDS_SetError("Unable to set string parameter value--allocation failure (SDDS_SetParameters)");
483 retval = 0;
484 }
485 }
486 break;
487 case SDDS_CHARACTER:
488 if (mode & SDDS_PASS_BY_VALUE)
489 *((char *)SDDS_dataset->parameter[index]) = (char)va_arg(argptr, int);
490 else
491 *((char *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, char *));
492 break;
493 default:
494 SDDS_SetError("Unknown data type encountered (SDDS_SetParameters)");
495 retval = 0;
496 }
497 } while (retval == -1);
498 va_end(argptr);
499 return (retval);
500}
501
502/**
503 * Sets the value of a single parameter in the current data table of an SDDS dataset.
504 *
505 * This function assigns a value to a specified parameter in the current data table of the given SDDS dataset.
506 * It must be preceded by a call to `SDDS_StartPage` to initialize the table. The parameter to be set can be
507 * identified either by its index or by its name. The value can be passed either by value or by reference,
508 * depending on the specified mode.
509 *
510 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
511 * @param mode A bitwise combination of the following constants:
512 * - `SDDS_SET_BY_INDEX`: Identify the parameter by its index.
513 * - `SDDS_SET_BY_NAME`: Identify the parameter by its name.
514 * - `SDDS_PASS_BY_VALUE`: Pass the parameter value by value.
515 * - `SDDS_PASS_BY_REFERENCE`: Pass the parameter value by reference.
516 *
517 * **Mode Requirements:**
518 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
519 * - Exactly one of `SDDS_PASS_BY_VALUE` or `SDDS_PASS_BY_REFERENCE` must be set.
520 *
521 * **Syntax Based on Mode Combination:**
522 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_VALUE`:
523 * `int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, value)`
524 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_REFERENCE`:
525 * `int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, void *data)`
526 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_VALUE`:
527 * `int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, value)`
528 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_REFERENCE`:
529 * `int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, void *data)`
530 *
531 * **Note:** For parameters of type `SDDS_STRING`, passing by value means passing a `char *`,
532 * whereas passing by reference means passing a `char **`.
533 *
534 * @return Returns `1` on successful assignment of the parameter value.
535 * On failure, returns `0` and records an appropriate error message.
536 *
537 * @sa SDDS_StartPage, SDDS_SetError, SDDS_GetParameterIndex, SDDS_CopyString
538 */
539int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode, ...) {
540 va_list argptr;
541 int32_t index;
542 SDDS_LAYOUT *layout;
543 char *name;
544 char s[SDDS_MAXLINE];
545
546 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetParameters"))
547 return (0);
548 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) || !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
549 SDDS_SetError("Unable to set parameter values--unknown mode (SDDS_SetParameters)");
550 return (0);
551 }
552
553 va_start(argptr, mode);
554 layout = &SDDS_dataset->layout;
555
556 /* variable arguments are pairs of (index, value), where index is a int32_t integer */
557 if (mode & SDDS_SET_BY_INDEX) {
558 if ((index = va_arg(argptr, int32_t)) == -1) {
559 SDDS_SetError("Unable to set parameter values--index is null (SDDS_SetParameter)");
560 va_end(argptr);
561 return (0);
562 }
563 if (index < 0 || index >= layout->n_parameters) {
564 SDDS_SetError("Unable to set parameter values--index out of range (SDDS_SetParameter)");
565 va_end(argptr);
566 return (0);
567 }
568 } else {
569 if ((name = va_arg(argptr, char *)) == NULL) {
570 SDDS_SetError("Unable to set parameter values--name is null (SDDS_SetParameter)");
571 va_end(argptr);
572 return (0);
573 }
574 if ((index = SDDS_GetParameterIndex(SDDS_dataset, name)) < 0) {
575 sprintf(s, "Unable to set parameter values--name %s not recognized (SDDS_SetParameter)", name);
576 SDDS_SetError(s);
577 va_end(argptr);
578 return (0);
579 }
580 }
581 switch (layout->parameter_definition[index].type) {
582 case SDDS_SHORT:
583 if (mode & SDDS_PASS_BY_VALUE)
584 *((short *)SDDS_dataset->parameter[index]) = (short)va_arg(argptr, int);
585 else
586 *((short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, short *));
587 break;
588 case SDDS_USHORT:
589 if (mode & SDDS_PASS_BY_VALUE)
590 *((unsigned short *)SDDS_dataset->parameter[index]) = (unsigned short)va_arg(argptr, unsigned int);
591 else
592 *((unsigned short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, unsigned short *));
593 break;
594 case SDDS_LONG:
595 if (mode & SDDS_PASS_BY_VALUE)
596 *((int32_t *)SDDS_dataset->parameter[index]) = (int32_t)va_arg(argptr, int32_t);
597 else
598 *((int32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, int32_t *));
599 break;
600 case SDDS_ULONG:
601 if (mode & SDDS_PASS_BY_VALUE)
602 *((uint32_t *)SDDS_dataset->parameter[index]) = (uint32_t)va_arg(argptr, uint32_t);
603 else
604 *((uint32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, uint32_t *));
605 break;
606 case SDDS_LONG64:
607 if (mode & SDDS_PASS_BY_VALUE)
608 *((int64_t *)SDDS_dataset->parameter[index]) = (int64_t)va_arg(argptr, int64_t);
609 else
610 *((int64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, int64_t *));
611 break;
612 case SDDS_ULONG64:
613 if (mode & SDDS_PASS_BY_VALUE)
614 *((uint64_t *)SDDS_dataset->parameter[index]) = (uint64_t)va_arg(argptr, uint64_t);
615 else
616 *((uint64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, uint64_t *));
617 break;
618 case SDDS_FLOAT:
619 if (mode & SDDS_PASS_BY_VALUE)
620 *((float *)SDDS_dataset->parameter[index]) = (float)va_arg(argptr, double);
621 else
622 *((float *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, float *));
623 break;
624 case SDDS_DOUBLE:
625 if (mode & SDDS_PASS_BY_VALUE)
626 *((double *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
627 else
628 *((double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
629 break;
630 case SDDS_LONGDOUBLE:
631 if (mode & SDDS_PASS_BY_VALUE)
632 *((long double *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
633 else
634 *((long double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
635 break;
636 case SDDS_STRING:
637 if (*(char **)SDDS_dataset->parameter[index])
638 free(*(char **)SDDS_dataset->parameter[index]);
639 if (mode & SDDS_PASS_BY_VALUE) {
640 if (!SDDS_CopyString((char **)SDDS_dataset->parameter[index], va_arg(argptr, char *))) {
641 SDDS_SetError("Unable to set string parameter value--allocation failure (SDDS_SetParameters)");
642 va_end(argptr);
643 return (0);
644 }
645 } else {
646 if (!SDDS_CopyString((char **)SDDS_dataset->parameter[index], *(va_arg(argptr, char **)))) {
647 SDDS_SetError("Unable to set string parameter value--allocation failure (SDDS_SetParameters)");
648 va_end(argptr);
649 return (0);
650 }
651 }
652 break;
653 case SDDS_CHARACTER:
654 if (mode & SDDS_PASS_BY_VALUE)
655 *((char *)SDDS_dataset->parameter[index]) = (char)va_arg(argptr, int);
656 else
657 *((char *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, char *));
658 break;
659 default:
660 SDDS_SetError("Unknown data type encountered (SDDS_SetParameters)");
661 va_end(argptr);
662 return (0);
663 }
664 va_end(argptr);
665 return (1);
666}
667
668/**
669 * Sets the values of one or more parameters in the current data table of an SDDS dataset using double-precision floating-point numbers.
670 *
671 * This function assigns double-precision floating-point values to specified parameters in the current data table of the given SDDS dataset.
672 * It must be preceded by a call to `SDDS_StartPage` to initialize the table. Parameters can be identified either by their index or by
673 * their name. The values can be passed either by value or by reference, depending on the specified mode.
674 *
675 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
676 * @param mode A bitwise combination of the following constants:
677 * - `SDDS_SET_BY_INDEX`: Identify parameters by their indices.
678 * - `SDDS_SET_BY_NAME`: Identify parameters by their names.
679 * - `SDDS_PASS_BY_VALUE`: Pass parameter values by value.
680 * - `SDDS_PASS_BY_REFERENCE`: Pass parameter values by reference.
681 *
682 * **Mode Requirements:**
683 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
684 * - Exactly one of `SDDS_PASS_BY_VALUE` or `SDDS_PASS_BY_REFERENCE` must be set.
685 *
686 * **Syntax Based on Mode Combination:**
687 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_VALUE`:
688 * `int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, double value)`
689 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_REFERENCE`:
690 * `int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, double *data)`
691 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_VALUE`:
692 * `int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, double value)`
693 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_REFERENCE`:
694 * `int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, double *data)`
695 *
696 * **Note:** For parameters of type `SDDS_STRING`, setting values using this function is not supported and will result in an error.
697 *
698 * @return Returns `1` on successful assignment of all specified parameter values.
699 * On failure, returns `0` and records an appropriate error message.
700 *
701 * @sa SDDS_StartPage, SDDS_SetError, SDDS_GetParameterIndex
702 */
703int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, ...) {
704 va_list argptr;
705 int32_t index, retval;
706 SDDS_LAYOUT *layout;
707 char *name;
708 char s[SDDS_MAXLINE];
709
710 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetParametersFromDoubles"))
711 return (0);
712 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) || !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
713 SDDS_SetError("Unable to set parameter values--unknown mode (SDDS_SetParametersFromDoubles)");
714 return (0);
715 }
716
717 va_start(argptr, mode);
718 layout = &SDDS_dataset->layout;
719
720 /* variable arguments are pairs of (index, value), where index is a int32_t integer */
721 retval = -1;
722 do {
723 if (mode & SDDS_SET_BY_INDEX) {
724 if ((index = va_arg(argptr, int32_t)) == -1) {
725 retval = 1;
726 break;
727 }
728 if (index < 0 || index >= layout->n_parameters) {
729 sprintf(s, "Unable to set parameter values--index %" PRId32 " out of range [%d, %" PRId32 "] (SDDS_SetParametersFromDoubles)", index, 0, layout->n_parameters);
730 SDDS_SetError(s);
731 retval = 0;
732 break;
733 }
734 } else {
735 if ((name = va_arg(argptr, char *)) == NULL) {
736 retval = 1;
737 break;
738 }
739 if ((index = SDDS_GetParameterIndex(SDDS_dataset, name)) < 0) {
740 sprintf(s, "Unable to set parameter values--name %s not recognized (SDDS_SetParametersFromDoubles)", name);
741 SDDS_SetError(s);
742 retval = 0;
743 break;
744 }
745 }
746 switch (layout->parameter_definition[index].type) {
747 case SDDS_SHORT:
748 if (mode & SDDS_PASS_BY_VALUE)
749 *((short *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
750 else
751 *((short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
752 break;
753 case SDDS_USHORT:
754 if (mode & SDDS_PASS_BY_VALUE)
755 *((unsigned short *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
756 else
757 *((unsigned short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
758 break;
759 case SDDS_LONG:
760 if (mode & SDDS_PASS_BY_VALUE)
761 *((int32_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
762 else
763 *((int32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
764 break;
765 case SDDS_ULONG:
766 if (mode & SDDS_PASS_BY_VALUE)
767 *((uint32_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
768 else
769 *((uint32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
770 break;
771 case SDDS_LONG64:
772 if (mode & SDDS_PASS_BY_VALUE)
773 *((int64_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
774 else
775 *((int64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
776 break;
777 case SDDS_ULONG64:
778 if (mode & SDDS_PASS_BY_VALUE)
779 *((uint64_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
780 else
781 *((uint64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
782 break;
783 case SDDS_FLOAT:
784 if (mode & SDDS_PASS_BY_VALUE)
785 *((float *)SDDS_dataset->parameter[index]) = (float)va_arg(argptr, double);
786 else
787 *((float *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
788 break;
789 case SDDS_DOUBLE:
790 if (mode & SDDS_PASS_BY_VALUE)
791 *((double *)SDDS_dataset->parameter[index]) = va_arg(argptr, double);
792 else
793 *((double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, double *));
794 break;
795 case SDDS_STRING:
796 case SDDS_CHARACTER:
797 SDDS_SetError("Nonnumeric data type encountered (SDDS_SetParametersFromDoubles)");
798 retval = 0;
799 break;
800 default:
801 SDDS_SetError("Unknown data type encountered (SDDS_SetParametersFromDoubles)");
802 retval = 0;
803 }
804 } while (retval == -1);
805 va_end(argptr);
806 return (retval);
807}
808
809/**
810 * Sets the values of one or more parameters in the current data table of an SDDS dataset using long double-precision floating-point numbers.
811 *
812 * This function assigns long double-precision floating-point values to specified parameters in the current data table of the given SDDS dataset.
813 * It must be preceded by a call to `SDDS_StartPage` to initialize the table. Parameters can be identified either by their index or by
814 * their name. The values can be passed either by value or by reference, depending on the specified mode.
815 *
816 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
817 * @param mode A bitwise combination of the following constants:
818 * - `SDDS_SET_BY_INDEX`: Identify parameters by their indices.
819 * - `SDDS_SET_BY_NAME`: Identify parameters by their names.
820 * - `SDDS_PASS_BY_VALUE`: Pass parameter values by value.
821 * - `SDDS_PASS_BY_REFERENCE`: Pass parameter values by reference.
822 *
823 * **Mode Requirements:**
824 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
825 * - Exactly one of `SDDS_PASS_BY_VALUE` or `SDDS_PASS_BY_REFERENCE` must be set.
826 *
827 * **Syntax Based on Mode Combination:**
828 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_VALUE`:
829 * `int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, long double value)`
830 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_REFERENCE`:
831 * `int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t index, long double *data)`
832 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_VALUE`:
833 * `int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, long double value)`
834 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_REFERENCE`:
835 * `int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, char *name, long double *data)`
836 *
837 * **Note:** For parameters of type `SDDS_STRING`, setting values using this function is not supported and will result in an error.
838 *
839 * @return Returns `1` on successful assignment of all specified parameter values.
840 * On failure, returns `0` and records an appropriate error message.
841 *
842 * @sa SDDS_StartPage, SDDS_SetError, SDDS_GetParameterIndex
843 */
844int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, ...) {
845 va_list argptr;
846 int32_t index, retval;
847 SDDS_LAYOUT *layout;
848 char *name;
849 char s[SDDS_MAXLINE];
850
851 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetParametersFromLongDoubles"))
852 return (0);
853 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) || !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
854 SDDS_SetError("Unable to set parameter values--unknown mode (SDDS_SetParametersFromLongDoubles)");
855 return (0);
856 }
857
858 va_start(argptr, mode);
859 layout = &SDDS_dataset->layout;
860
861 /* variable arguments are pairs of (index, value), where index is a int32_t integer */
862 retval = -1;
863 do {
864 if (mode & SDDS_SET_BY_INDEX) {
865 if ((index = va_arg(argptr, int32_t)) == -1) {
866 retval = 1;
867 break;
868 }
869 if (index < 0 || index >= layout->n_parameters) {
870 sprintf(s, "Unable to set parameter values--index %" PRId32 " out of range [%d, %" PRId32 "] (SDDS_SetParametersFromLongDoubles)", index, 0, layout->n_parameters);
871 SDDS_SetError(s);
872 retval = 0;
873 break;
874 }
875 } else {
876 if ((name = va_arg(argptr, char *)) == NULL) {
877 retval = 1;
878 break;
879 }
880 if ((index = SDDS_GetParameterIndex(SDDS_dataset, name)) < 0) {
881 sprintf(s, "Unable to set parameter values--name %s not recognized (SDDS_SetParametersFromLongDoubles)", name);
882 SDDS_SetError(s);
883 retval = 0;
884 break;
885 }
886 }
887 switch (layout->parameter_definition[index].type) {
888 case SDDS_SHORT:
889 if (mode & SDDS_PASS_BY_VALUE)
890 *((short *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
891 else
892 *((short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
893 break;
894 case SDDS_USHORT:
895 if (mode & SDDS_PASS_BY_VALUE)
896 *((unsigned short *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
897 else
898 *((unsigned short *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
899 break;
900 case SDDS_LONG:
901 if (mode & SDDS_PASS_BY_VALUE)
902 *((int32_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
903 else
904 *((int32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
905 break;
906 case SDDS_ULONG:
907 if (mode & SDDS_PASS_BY_VALUE)
908 *((uint32_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
909 else
910 *((uint32_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
911 break;
912 case SDDS_LONG64:
913 if (mode & SDDS_PASS_BY_VALUE)
914 *((int64_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
915 else
916 *((int64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
917 break;
918 case SDDS_ULONG64:
919 if (mode & SDDS_PASS_BY_VALUE)
920 *((uint64_t *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
921 else
922 *((uint64_t *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
923 break;
924 case SDDS_FLOAT:
925 if (mode & SDDS_PASS_BY_VALUE)
926 *((float *)SDDS_dataset->parameter[index]) = (float)va_arg(argptr, long double);
927 else
928 *((float *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
929 break;
930 case SDDS_DOUBLE:
931 if (mode & SDDS_PASS_BY_VALUE)
932 *((double *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
933 else
934 *((double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
935 break;
936 case SDDS_LONGDOUBLE:
937 if (mode & SDDS_PASS_BY_VALUE)
938 *((long double *)SDDS_dataset->parameter[index]) = va_arg(argptr, long double);
939 else
940 *((long double *)SDDS_dataset->parameter[index]) = *(va_arg(argptr, long double *));
941 break;
942 case SDDS_STRING:
943 case SDDS_CHARACTER:
944 SDDS_SetError("Nonnumeric data type encountered (SDDS_SetParametersFromLongDoubles)");
945 retval = 0;
946 break;
947 default:
948 SDDS_SetError("Unknown data type encountered (SDDS_SetParametersFromLongDoubles)");
949 retval = 0;
950 }
951 } while (retval == -1);
952 va_end(argptr);
953 return (retval);
954}
955
956/**
957 * Sets the values of one or more columns in a specified row of the current data table of an SDDS dataset.
958 *
959 * This function assigns values to specified columns in a particular row of the current data table within the given SDDS dataset.
960 * It must be preceded by a call to `SDDS_StartPage` to initialize the table. Columns can be identified either by their index or by
961 * their name. The values can be passed either by value or by reference, depending on the specified mode.
962 *
963 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
964 * @param mode A bitwise combination of the following constants:
965 * - `SDDS_SET_BY_INDEX`: Identify columns by their indices.
966 * - `SDDS_SET_BY_NAME`: Identify columns by their names.
967 * - `SDDS_PASS_BY_VALUE`: Pass column values by value.
968 * - `SDDS_PASS_BY_REFERENCE`: Pass column values by reference.
969 *
970 * **Mode Requirements:**
971 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
972 * - Exactly one of `SDDS_PASS_BY_VALUE` or `SDDS_PASS_BY_REFERENCE` must be set.
973 *
974 * **Syntax Based on Mode Combination:**
975 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_VALUE`:
976 * `int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row, int32_t index, value, ..., -1)`
977 * - `SDDS_SET_BY_INDEX` + `SDDS_PASS_BY_REFERENCE`:
978 * `int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row, int32_t index, void *data, ..., -1)`
979 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_VALUE`:
980 * `int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row, char *name, value, ..., NULL)`
981 * - `SDDS_SET_BY_NAME` + `SDDS_PASS_BY_REFERENCE`:
982 * `int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row, char *name, void *data, ..., NULL)`
983 *
984 * **Note:** For columns of type `SDDS_STRING`, passing by value means passing a `char *`,
985 * whereas passing by reference means passing a `char **`.
986 *
987 * @param row The row number in the data table where the column values will be set. Row numbering starts from 1.
988 *
989 * @return Returns `1` on successful assignment of all specified column values.
990 * On failure, returns `0` and records an appropriate error message.
991 *
992 * @sa SDDS_StartPage, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyString
993 */
994int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row, ...) {
995 va_list argptr;
996 int32_t index;
997 int32_t retval;
998 SDDS_LAYOUT *layout;
999 char *name;
1000 char buffer[200];
1001
1002 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetRowValues"))
1003 return (0);
1004 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME) || !(mode & SDDS_PASS_BY_VALUE || mode & SDDS_PASS_BY_REFERENCE)) {
1005 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetRowValues)");
1006 return (0);
1007 }
1008 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetRowValues"))
1009 return (0);
1010 row -= SDDS_dataset->first_row_in_mem;
1011 if (row >= SDDS_dataset->n_rows_allocated) {
1012 sprintf(buffer, "Unable to set column values--row number (%" PRId64 ") exceeds exceeds allocated memory (%" PRId64 ") (SDDS_SetRowValues)", row, SDDS_dataset->n_rows_allocated);
1013 SDDS_SetError(buffer);
1014 return (0);
1015 }
1016 if (row > SDDS_dataset->n_rows - 1)
1017 SDDS_dataset->n_rows = row + 1;
1018
1019 va_start(argptr, row);
1020 layout = &SDDS_dataset->layout;
1021
1022 /* variable arguments are pairs of (index, value), where index is a int32_t integer */
1023 retval = -1;
1024#ifdef DEBUG
1025 fprintf(stderr, "setting row %" PRId64 " (mem slot %" PRId64 ")\n", row + SDDS_dataset->first_row_in_mem, row);
1026#endif
1027 do {
1028 if (mode & SDDS_SET_BY_INDEX) {
1029 if ((index = va_arg(argptr, int32_t)) == -1) {
1030 retval = 1;
1031 break;
1032 }
1033 if (index < 0 || index >= layout->n_columns) {
1034 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetRowValues)");
1035 retval = 0;
1036 break;
1037 }
1038#ifdef DEBUG
1039 fprintf(stderr, "Setting values for column #%" PRId32 "\n", index);
1040#endif
1041 } else {
1042 if ((name = va_arg(argptr, char *)) == NULL) {
1043 retval = 1;
1044 break;
1045 }
1046#ifdef DEBUG
1047 fprintf(stderr, "Setting values for column %s\n", name);
1048#endif
1049 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
1050 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetRowValues)");
1051 retval = 0;
1052 break;
1053 }
1054 }
1055 switch (layout->column_definition[index].type) {
1056 case SDDS_SHORT:
1057 if (mode & SDDS_PASS_BY_VALUE)
1058 *(((short *)SDDS_dataset->data[index]) + row) = (short)va_arg(argptr, int);
1059 else
1060 *(((short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, short *));
1061 break;
1062 case SDDS_USHORT:
1063 if (mode & SDDS_PASS_BY_VALUE)
1064 *(((unsigned short *)SDDS_dataset->data[index]) + row) = (unsigned short)va_arg(argptr, unsigned int);
1065 else
1066 *(((unsigned short *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, unsigned short *));
1067 break;
1068 case SDDS_LONG:
1069 if (mode & SDDS_PASS_BY_VALUE)
1070 *(((int32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int32_t);
1071 else
1072 *(((int32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int32_t *));
1073 break;
1074 case SDDS_ULONG:
1075 if (mode & SDDS_PASS_BY_VALUE)
1076 *(((uint32_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint32_t);
1077 else
1078 *(((uint32_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint32_t *));
1079 break;
1080 case SDDS_LONG64:
1081 if (mode & SDDS_PASS_BY_VALUE)
1082 *(((int64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, int64_t);
1083 else
1084 *(((int64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, int64_t *));
1085 break;
1086 case SDDS_ULONG64:
1087 if (mode & SDDS_PASS_BY_VALUE)
1088 *(((uint64_t *)SDDS_dataset->data[index]) + row) = va_arg(argptr, uint64_t);
1089 else
1090 *(((uint64_t *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, uint64_t *));
1091 break;
1092 case SDDS_FLOAT:
1093 if (mode & SDDS_PASS_BY_VALUE)
1094 *(((float *)SDDS_dataset->data[index]) + row) = (float)va_arg(argptr, double);
1095 else
1096 *(((float *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, float *));
1097 break;
1098 case SDDS_DOUBLE:
1099 if (mode & SDDS_PASS_BY_VALUE)
1100 *(((double *)SDDS_dataset->data[index]) + row) = va_arg(argptr, double);
1101 else
1102 *(((double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, double *));
1103 break;
1104 case SDDS_LONGDOUBLE:
1105 if (mode & SDDS_PASS_BY_VALUE)
1106 *(((long double *)SDDS_dataset->data[index]) + row) = va_arg(argptr, long double);
1107 else
1108 *(((long double *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, long double *));
1109 break;
1110 case SDDS_STRING:
1111 if (((char **)SDDS_dataset->data[index])[row]) {
1112 free(((char **)SDDS_dataset->data[index])[row]);
1113 ((char **)SDDS_dataset->data[index])[row] = NULL;
1114 }
1115 if (mode & SDDS_PASS_BY_VALUE) {
1116 if (!SDDS_CopyString((char **)SDDS_dataset->data[index] + row, va_arg(argptr, char *))) {
1117 SDDS_SetError("Unable to set string column value--allocation failure (SDDS_SetRowValues)");
1118 retval = 0;
1119 }
1120 } else {
1121 if (!SDDS_CopyString((char **)SDDS_dataset->data[index] + row, *(va_arg(argptr, char **)))) {
1122 SDDS_SetError("Unable to set string column value--allocation failure (SDDS_SetRowValues)");
1123 retval = 0;
1124 }
1125 }
1126 break;
1127 case SDDS_CHARACTER:
1128 if (mode & SDDS_PASS_BY_VALUE)
1129 *(((char *)SDDS_dataset->data[index]) + row) = (char)va_arg(argptr, int);
1130 else
1131 *(((char *)SDDS_dataset->data[index]) + row) = *(va_arg(argptr, char *));
1132 break;
1133 default:
1134 SDDS_SetError("Unknown data type encountered (SDDS_SetRowValues");
1135 retval = 0;
1136 break;
1137 }
1138 } while (retval == -1);
1139 va_end(argptr);
1140 return (retval);
1141}
1142
1143/**
1144 * @brief Sets the values of an array variable in the SDDS dataset using variable arguments for dimensions.
1145 *
1146 * This function assigns data to a specified array within the current SDDS dataset. The dimensions of the array are
1147 * provided as variable arguments, allowing for flexible assignment of multi-dimensional arrays. The `mode` parameter
1148 * controls how the data is interpreted and stored. This function handles both pointer arrays and contiguous data.
1149 *
1150 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1151 * @param array_name The name of the array to set within the dataset.
1152 * @param mode Bitwise flags that determine how the array is set. Valid flags include:
1153 * - `SDDS_POINTER_ARRAY`: Indicates that the array is a pointer array.
1154 * - `SDDS_CONTIGUOUS_DATA`: Indicates that the data is contiguous in memory.
1155 * @param data_pointer Pointer to the data to be assigned to the array. The data must match the type defined for the array.
1156 * @param ... Variable arguments specifying the dimensions of the array. The number of dimensions should match the array definition.
1157 *
1158 * @return Returns `1` on successful assignment of the array data.
1159 * On failure, returns `0` and records an appropriate error message.
1160 *
1161 * @sa SDDS_Realloc, SDDS_CopyStringArray, SDDS_SetError, SDDS_GetArrayIndex, SDDS_ZeroMemory, SDDS_AdvanceCounter
1162 */
1163int32_t SDDS_SetArrayVararg(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, ...) {
1164 va_list argptr;
1165 int32_t index, retval, i, size;
1166 int32_t *counter = NULL;
1167 SDDS_LAYOUT *layout;
1168 SDDS_ARRAY *array;
1169 void *ptr;
1170
1171 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetArrayVararg"))
1172 return (0);
1173 if (!(mode & SDDS_POINTER_ARRAY) && !(mode & SDDS_CONTIGUOUS_DATA)) {
1174 SDDS_SetError("Unable to set array--invalid mode (SDDS_SetArrayVararg)");
1175 return (0);
1176 }
1177 if ((index = SDDS_GetArrayIndex(SDDS_dataset, array_name)) < 0) {
1178 SDDS_SetError("Unable to set array--unknown array name given (SDDS_SetArrayVararg)");
1179 return (0);
1180 }
1181 if (!SDDS_dataset->array) {
1182 SDDS_SetError("Unable to set array--internal array pointer is NULL (SDDS_SetArrayVararg)");
1183 return (0);
1184 }
1185
1186 layout = &SDDS_dataset->layout;
1187 array = SDDS_dataset->array + index;
1188 if (!layout->array_definition) {
1189 SDDS_SetError("Unable to set array--internal array definition pointer is NULL (SDDS_SetArrayVararg)");
1190 return (0);
1191 }
1192 array->definition = layout->array_definition + index;
1193 if (!array->dimension && !(array->dimension = (int32_t *)SDDS_Malloc(sizeof(*array->dimension) * array->definition->dimensions))) {
1194 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArrayVararg)");
1195 return (0);
1196 }
1197
1198 va_start(argptr, data_pointer);
1199
1200 /* variable arguments are dimensions */
1201 retval = 1;
1202 index = 0;
1203 array->elements = 1;
1204 do {
1205 if ((array->dimension[index] = va_arg(argptr, int32_t)) < 0) {
1206 SDDS_SetError("Unable to set array--negative dimension given (SDDS_SetArrayVararg)");
1207 retval = 0;
1208 break;
1209 }
1210 array->elements *= array->dimension[index];
1211 } while (retval == 1 && ++index < array->definition->dimensions);
1212 va_end(argptr);
1213
1214 if (!retval)
1215 return (0);
1216 if (!array->elements)
1217 return (1);
1218 if (!data_pointer) {
1219 SDDS_SetError("Unable to set array--data pointer is NULL (SDDS_SetArrayVararg)");
1220 return (0);
1221 }
1222
1223 size = SDDS_type_size[array->definition->type - 1];
1224 if (!(array->data = SDDS_Realloc(array->data, size * array->elements))) {
1225 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArrayVararg");
1226 return (0);
1227 }
1228
1229 /* handle 1-d arrays and contiguous data as a special case */
1230 if (array->definition->dimensions == 1 || mode & SDDS_CONTIGUOUS_DATA) {
1231 if (array->definition->type != SDDS_STRING)
1232 memcpy(array->data, data_pointer, size * array->elements);
1233 else if (!SDDS_CopyStringArray(array->data, data_pointer, array->elements)) {
1234 SDDS_SetError("Unable to set array--string copy failure (SDDS_SetArrayVararg");
1235 return (0);
1236 }
1237 return (1);
1238 }
1239
1240 if (!(counter = SDDS_Realloc(counter, sizeof(*counter) * (array->elements - 1)))) {
1241 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArrayVararg");
1242 return (0);
1243 }
1244 SDDS_ZeroMemory(counter, sizeof(*counter) * (array->elements - 1));
1245 index = 0;
1246 do {
1247 ptr = data_pointer;
1248 for (i = 0; i < array->definition->dimensions - 1; i++)
1249 ptr = ((void **)ptr)[counter[i]];
1250 if (array->definition->type != SDDS_STRING)
1251 memcpy((char *)array->data + size * index, ptr, size * array->dimension[i]);
1252 else if (!SDDS_CopyStringArray(((char **)array->data) + index, ptr, array->dimension[i])) {
1253 SDDS_SetError("Unable to set array--string copy failure (SDDS_SetArrayVararg");
1254 return (0);
1255 }
1256 index += array->dimension[i];
1257 } while (SDDS_AdvanceCounter(counter, array->dimension, array->definition->dimensions - 1) != -1);
1258 if (counter)
1259 free(counter);
1260 return (1);
1261}
1262
1263/**
1264 * @brief Sets the values of an array variable in the SDDS dataset using specified dimensions.
1265 *
1266 * This function assigns data to a specified array within the current SDDS dataset. The dimensions of the array are
1267 * provided as an array of integers, allowing for the assignment of multi-dimensional arrays. The `mode` parameter
1268 * controls how the data is interpreted and stored. This function handles both pointer arrays and contiguous data.
1269 *
1270 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1271 * @param array_name The name of the array to set within the dataset.
1272 * @param mode Bitwise flags that determine how the array is set. Valid flags include:
1273 * - `SDDS_POINTER_ARRAY`: Indicates that the array is a pointer array.
1274 * - `SDDS_CONTIGUOUS_DATA`: Indicates that the data is contiguous in memory.
1275 * @param data_pointer Pointer to the data to be assigned to the array. The data must match the type defined for the array.
1276 * @param dimension Pointer to an array of integers specifying the dimensions of the array. The number of dimensions should
1277 * match the array definition.
1278 *
1279 * @return Returns `1` on successful assignment of the array data.
1280 * On failure, returns `0` and records an appropriate error message.
1281 *
1282 * @sa SDDS_Realloc, SDDS_CopyStringArray, SDDS_SetError, SDDS_GetArrayIndex, SDDS_ZeroMemory, SDDS_AdvanceCounter
1283 */
1284int32_t SDDS_SetArray(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, int32_t *dimension) {
1285 int32_t index, i, size;
1286 int32_t *counter = NULL;
1287 SDDS_LAYOUT *layout;
1288 SDDS_ARRAY *array;
1289 void *ptr;
1290
1291 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetArray"))
1292 return (0);
1293 if (!(mode & SDDS_POINTER_ARRAY) && !(mode & SDDS_CONTIGUOUS_DATA)) {
1294 SDDS_SetError("Unable to set array--invalid mode (SDDS_SetArray)");
1295 return (0);
1296 }
1297 if ((index = SDDS_GetArrayIndex(SDDS_dataset, array_name)) < 0) {
1298 SDDS_SetError("Unable to set array--unknown array name given (SDDS_SetArray)");
1299 return (0);
1300 }
1301
1302 if (!dimension) {
1303 SDDS_SetError("Unable to set array--dimension pointer is NULL (SDDS_SetArray)");
1304 return (0);
1305 }
1306 if (!SDDS_dataset->array) {
1307 SDDS_SetError("Unable to set array--internal array pointer is NULL (SDDS_SetArray)");
1308 return (0);
1309 }
1310
1311 layout = &SDDS_dataset->layout;
1312 array = SDDS_dataset->array + index;
1313 if (!layout->array_definition) {
1314 SDDS_SetError("Unable to set array--internal array definition pointer is NULL (SDDS_SetArray)");
1315 return (0);
1316 }
1317 array->definition = layout->array_definition + index;
1318 if (!array->dimension && !(array->dimension = (int32_t *)SDDS_Malloc(sizeof(*array->dimension) * array->definition->dimensions))) {
1319 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArray)");
1320 return (0);
1321 }
1322 array->elements = 1;
1323 for (i = 0; i < array->definition->dimensions; i++) {
1324 if ((array->dimension[i] = dimension[i]) < 0) {
1325 SDDS_SetError("Unable to set array--negative dimension specified (SDDS_SetArray)");
1326 return (0);
1327 }
1328 array->elements *= dimension[i];
1329 if (array->elements && !data_pointer) {
1330 SDDS_SetError("Unable to set array--data pointer is NULL (SDDS_SetArray)");
1331 return (0);
1332 }
1333 }
1334 if (!array->elements)
1335 return (1);
1336
1337 size = SDDS_type_size[array->definition->type - 1];
1338 if (!(array->data = SDDS_Realloc(array->data, size * array->elements))) {
1339 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArray)");
1340 return (0);
1341 }
1342
1343 /* handle 1-d arrays and contiguous data as a special case */
1344 if (array->definition->dimensions == 1 || mode & SDDS_CONTIGUOUS_DATA) {
1345 if (array->definition->type != SDDS_STRING)
1346 memcpy(array->data, data_pointer, size * array->elements);
1347 else if (!SDDS_CopyStringArray(array->data, data_pointer, array->elements)) {
1348 SDDS_SetError("Unable to set array--string copy failure (SDDS_SetArrayVararg");
1349 return (0);
1350 }
1351 return (1);
1352 }
1353
1354 if (!(counter = SDDS_Realloc(counter, sizeof(*counter) * (array->elements - 1)))) {
1355 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArray)");
1356 return (0);
1357 }
1358 SDDS_ZeroMemory(counter, sizeof(*counter) * (array->elements - 1));
1359 index = 0;
1360 do {
1361 ptr = data_pointer;
1362 for (i = 0; i < array->definition->dimensions - 1; i++)
1363 ptr = ((void **)ptr)[counter[i]];
1364 if (array->definition->type != SDDS_STRING)
1365 memcpy((char *)array->data + size * index, ptr, size * array->dimension[i]);
1366 else if (!SDDS_CopyStringArray(((char **)array->data) + index, ptr, array->dimension[i])) {
1367 SDDS_SetError("Unable to set array--string copy failure (SDDS_SetArray)");
1368 return (0);
1369 }
1370 index += array->dimension[i];
1371 } while (SDDS_AdvanceCounter(counter, array->dimension, array->definition->dimensions - 1) != -1);
1372 if (counter)
1373 free(counter);
1374 return (1);
1375}
1376
1377/**
1378 * @brief Appends data to an existing array variable in the SDDS dataset using variable arguments for dimensions.
1379 *
1380 * This function appends additional data to a specified array within the current SDDS dataset. The `elements` parameter
1381 * specifies the number of new elements to append. The `mode` parameter controls how the data is interpreted and stored.
1382 * The dimensions of the array are provided as variable arguments, allowing for flexible handling of multi-dimensional arrays.
1383 *
1384 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1385 * @param array_name The name of the array to append data to within the dataset.
1386 * @param mode Bitwise flags that determine how the array is set. Valid flags include:
1387 * - `SDDS_POINTER_ARRAY`: Indicates that the array is a pointer array.
1388 * - `SDDS_CONTIGUOUS_DATA`: Indicates that the data is contiguous in memory.
1389 * @param data_pointer Pointer to the data to be appended to the array. The data must match the type defined for the array.
1390 * @param elements The number of elements to append to the array.
1391 * @param ... Variable arguments specifying the dimensions of the array. The number of dimensions should match the array definition.
1392 *
1393 * @return Returns `1` on successful appending of the array data.
1394 * On failure, returns `0` and records an appropriate error message.
1395 *
1396 * @sa SDDS_Realloc, SDDS_CopyStringArray, SDDS_SetError, SDDS_GetArrayIndex
1397 */
1398int32_t SDDS_AppendToArrayVararg(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, int32_t elements, ...) {
1399 va_list argptr;
1400 int32_t index, retval, size, startIndex = 0;
1401 SDDS_LAYOUT *layout;
1402 SDDS_ARRAY *array;
1403
1404 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_AppendToArrayVararg"))
1405 return (0);
1406 if (!(mode & SDDS_POINTER_ARRAY) && !(mode & SDDS_CONTIGUOUS_DATA)) {
1407 SDDS_SetError("Unable to set array--invalid mode (SDDS_AppendToArrayVararg)");
1408 return (0);
1409 }
1410 if ((index = SDDS_GetArrayIndex(SDDS_dataset, array_name)) < 0) {
1411 SDDS_SetError("Unable to set array--unknown array name given (SDDS_AppendToArrayVararg)");
1412 return (0);
1413 }
1414 if (!data_pointer) {
1415 SDDS_SetError("Unable to set array--data pointer is NULL (SDDS_AppendToArrayVararg)");
1416 return (0);
1417 }
1418 if (!SDDS_dataset->array) {
1419 SDDS_SetError("Unable to set array--internal array pointer is NULL (SDDS_AppendToArrayVararg)");
1420 return (0);
1421 }
1422
1423 layout = &SDDS_dataset->layout;
1424 array = SDDS_dataset->array + index;
1425 if (!layout->array_definition) {
1426 SDDS_SetError("Unable to set array--internal array definition pointer is NULL (SDDS_AppendToArrayVararg)");
1427 return (0);
1428 }
1429 array->definition = layout->array_definition + index;
1430 if (!array->dimension && !(array->dimension = (int32_t *)SDDS_Malloc(sizeof(*array->dimension) * array->definition->dimensions))) {
1431 SDDS_SetError("Unable to set array--allocation failure (SDDS_SetArrayVararg)");
1432 return (0);
1433 }
1434 if (!(array->definition->dimensions == 1 || mode & SDDS_CONTIGUOUS_DATA)) {
1435 SDDS_SetError("Unable to set array--append operation requires contiguous data (SDDS_AppendToArrayVararg)");
1436 return (0);
1437 }
1438
1439 va_start(argptr, elements);
1440
1441 /* variable arguments are dimensions */
1442 retval = 1;
1443 index = 0;
1444 array->elements = 1;
1445 do {
1446 if ((array->dimension[index] = va_arg(argptr, int32_t)) < 0) {
1447 SDDS_SetError("Unable to set array--negative dimension given (SDDS_AppendToArrayVararg)");
1448 retval = 0;
1449 break;
1450 }
1451 array->elements *= array->dimension[index];
1452 } while (retval == 1 && ++index < array->definition->dimensions);
1453 va_end(argptr);
1454
1455 if (!retval)
1456 return (0);
1457 if (!array->elements)
1458 return (1);
1459
1460 size = SDDS_type_size[array->definition->type - 1];
1461 if (!(array->data = SDDS_Realloc(array->data, size * array->elements))) {
1462 SDDS_SetError("Unable to set array--allocation failure (SDDS_AppendToArrayVararg)");
1463 return (0);
1464 }
1465
1466 startIndex = array->elements - elements;
1467
1468 /* handle 1-d arrays and contiguous data as a special case */
1469 if (array->definition->dimensions == 1 || mode & SDDS_CONTIGUOUS_DATA) {
1470 if (array->definition->type != SDDS_STRING)
1471 memcpy((char *)array->data + size * startIndex, data_pointer, size * elements);
1472 else if (!SDDS_CopyStringArray(((char **)array->data) + startIndex, data_pointer, elements)) {
1473 SDDS_SetError("Unable to set array--string copy failure (SDDS_AppendToArrayVararg)");
1474 return (0);
1475 }
1476 return (1);
1477 }
1478
1479 return (1);
1480}
1481
1482/**
1483 * @brief Advances a multi-dimensional counter based on maximum counts for each dimension.
1484 *
1485 * This helper function increments a multi-dimensional counter array, handling carry-over for each dimension. It is typically
1486 * used for iterating over multi-dimensional arrays in a nested loop fashion.
1487 *
1488 * @param counter Pointer to an array of integers representing the current count in each dimension.
1489 * @param max_count Pointer to an array of integers representing the maximum count for each dimension.
1490 * @param n_indices The number of dimensions (indices) in the counter and max_count arrays.
1491 *
1492 * @return Returns the index of the dimension that was incremented. If all dimensions have been fully iterated over,
1493 * returns `-1` to indicate completion.
1494 *
1495 * @sa SDDS_SetArrayVararg, SDDS_SetArray, SDDS_AdvanceCounter
1496 */
1497int32_t SDDS_AdvanceCounter(int32_t *counter, int32_t *max_count, int32_t n_indices) {
1498 int32_t i;
1499
1500 for (i = n_indices - 1; i >= 0; i--)
1501 if (counter[i] != (max_count[i] - 1))
1502 break;
1503 if (i == -1)
1504 return (-1);
1505
1506 for (i = n_indices - 1; i >= 0; i--) {
1507 if (counter[i] < (max_count[i] - 1)) {
1508 counter[i]++;
1509 break;
1510 } else {
1511 counter[i] = 0;
1512 }
1513 }
1514 return (i);
1515}
1516
1517/**
1518 * @brief Sets the values for one data column in the current data table of an SDDS dataset.
1519 *
1520 * This function assigns data to a specified column within the current data table of the given SDDS dataset. The column
1521 * can be identified either by its index or by its name. The `mode` parameter determines how the column is identified.
1522 * The function ensures that the number of rows in the new column matches the existing data table.
1523 *
1524 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1525 * @param mode Bitwise flags that determine how the column is identified. Valid flags include:
1526 * - `SDDS_SET_BY_INDEX`: Identify the column by its index.
1527 * - `SDDS_SET_BY_NAME`: Identify the column by its name.
1528 * @param data Pointer to an array of data to be assigned to the column. The elements of the array must be of the same type as the column type.
1529 * @param rows The number of rows in the column. This should match the number of rows in the existing data table.
1530 * @param ... Variable arguments specifying either the column index or column name, depending on the `mode` parameter:
1531 * - If `mode` includes `SDDS_SET_BY_INDEX`: Provide an `int32_t` index.
1532 * - If `mode` includes `SDDS_SET_BY_NAME`: Provide a `char*` name.
1533 *
1534 * @return Returns `1` on successful assignment of the column data.
1535 * On failure, returns `0` and records an appropriate error message.
1536 *
1537 * @note The function ensures that the number of rows in the new column matches the existing data table. If the data type of the column is `SDDS_STRING`,
1538 * it handles memory allocation and copying of strings appropriately.
1539 *
1540 * @sa SDDS_SetRowValues, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyStringArray
1541 */
1542int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows, ...) {
1543 va_list argptr;
1544 int32_t index;
1545 int32_t retval;
1546 SDDS_LAYOUT *layout;
1547 char *name;
1548
1549 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetColumn"))
1550 return (0);
1551 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME)) {
1552 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetColumn)");
1553 return (0);
1554 }
1555 if (rows > SDDS_dataset->n_rows_allocated) {
1556 SDDS_SetError("Unable to set column values--number of rows exceeds allocated memory (SDDS_SetColumn)");
1557 return (0);
1558 }
1559 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetColumn"))
1560 return (0);
1561 if (SDDS_dataset->n_rows != 0 && SDDS_dataset->n_rows != rows) {
1562 SDDS_SetError("Number of rows in new column unequal to number in other columns (SDDS_SetColumn)");
1563 return (0);
1564 }
1565 SDDS_dataset->n_rows = rows;
1566 layout = &SDDS_dataset->layout;
1567
1568 retval = 1;
1569 va_start(argptr, rows);
1570 if (mode & SDDS_SET_BY_INDEX) {
1571 index = va_arg(argptr, int32_t);
1572 if (index < 0 || index >= layout->n_columns) {
1573 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetColumn)");
1574 retval = 0;
1575 }
1576 } else {
1577 name = va_arg(argptr, char *);
1578 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
1579 SDDS_SetError0("Unable to set column values--name ");
1580 SDDS_SetError0(name);
1581 SDDS_SetError(" not recognized (SDDS_SetColumn)");
1582 retval = 0;
1583 }
1584 }
1585 va_end(argptr);
1586 if (!retval)
1587 return 0;
1588
1589 if (layout->column_definition[index].type == SDDS_STRING) {
1590 if (SDDS_dataset->data[index]) {
1591 char *ptr;
1592 int64_t i;
1593 for (i = 0; i < rows; i++) {
1594 ptr = *((char **)SDDS_dataset->data[index] + i);
1595 if (ptr)
1596 free(ptr);
1597 *((char **)SDDS_dataset->data[index] + i) = NULL;
1598 }
1599 }
1600 if (!SDDS_CopyStringArray((char **)(SDDS_dataset->data[index]), (char **)data, rows)) {
1601 SDDS_SetError("Unable to set column--error copying string data (SDDS_SetColumn)");
1602 return 0;
1603 }
1604 } else
1605 memcpy(SDDS_dataset->data[index], data, rows * SDDS_type_size[layout->column_definition[index].type - 1]);
1606 return 1;
1607}
1608
1609/**
1610 * @brief Sets the values for a single data column using double-precision floating-point numbers.
1611 *
1612 * This function assigns data to a specified column within the current data table of the given SDDS dataset.
1613 * The column can be identified either by its index or by its name, based on the provided `mode`. The data
1614 * provided must be in the form of double-precision floating-point numbers (`double`). If the target column
1615 * is of a different numeric type, the function will perform the necessary type casting. For string columns,
1616 * the function converts the double values to strings with appropriate formatting.
1617 *
1618 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1619 * @param mode Bitwise flags that determine how the column is identified. Valid flags include:
1620 * - `SDDS_SET_BY_INDEX`: Identify the column by its index.
1621 * - `SDDS_SET_BY_NAME`: Identify the column by its name.
1622 *
1623 * **Mode Requirements:**
1624 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
1625 *
1626 * **Syntax Based on Mode Combination:**
1627 * - `SDDS_SET_BY_INDEX`:
1628 * `int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows, int32_t index)`
1629 * - `SDDS_SET_BY_NAME`:
1630 * `int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows, char *name)`
1631 *
1632 * @param data Pointer to an array of double-precision floating-point data to be assigned to the column.
1633 * The array should contain at least `rows` elements.
1634 * @param rows The number of rows (elements) in the column to be set. Must not exceed the allocated memory for the dataset.
1635 * @param ... Variable arguments specifying either the column index (`int32_t`) or column name (`char *`), depending on the `mode`.
1636 *
1637 * @return Returns `1` on successful assignment of the column data.
1638 * On failure, returns `0` and records an appropriate error message using `SDDS_SetError`.
1639 *
1640 * @note
1641 * - If the target column is of type `SDDS_STRING`, the function converts each double value to a string
1642 * with a precision of up to 15 significant digits.
1643 * - The function ensures that the number of rows in the new column matches the existing data table.
1644 * - It is required to call `SDDS_StartPage` before setting column values.
1645 *
1646 * @sa SDDS_SetColumnFromLongDoubles, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyStringArray, SDDS_CastValue
1647 */
1648int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows, ...) {
1649 va_list argptr;
1650 int64_t i;
1651 int32_t index, retval, type, size;
1652 SDDS_LAYOUT *layout;
1653 char *name;
1654
1655 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetColumnFromDoubles"))
1656 return (0);
1657 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME)) {
1658 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetColumnFromDoubles)");
1659 return (0);
1660 }
1661 if (rows > SDDS_dataset->n_rows_allocated) {
1662 SDDS_SetError("Unable to set column values--number of rows exceeds allocated memory (SDDS_SetColumnFromDoubles)");
1663 return (0);
1664 }
1665 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetColumnFromDoubles"))
1666 return (0);
1667 if (SDDS_dataset->n_rows != 0 && SDDS_dataset->n_rows != rows) {
1668 SDDS_SetError("Number of rows in new column unequal to number in other columns (SDDS_SetColumnFromDoubles)");
1669 return (0);
1670 }
1671 SDDS_dataset->n_rows = rows;
1672 layout = &SDDS_dataset->layout;
1673
1674 retval = 1;
1675 va_start(argptr, rows);
1676 if (mode & SDDS_SET_BY_INDEX) {
1677 index = va_arg(argptr, int32_t);
1678 if (index < 0 || index >= layout->n_columns) {
1679 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetColumnFromDoubles)");
1680 retval = 0;
1681 }
1682 } else {
1683 name = va_arg(argptr, char *);
1684 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
1685 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetColumnFromDoubles)");
1686 retval = 0;
1687 }
1688 }
1689 va_end(argptr);
1690 if (!retval)
1691 return 0;
1692
1693 type = layout->column_definition[index].type;
1694 if (!SDDS_NUMERIC_TYPE(type)) {
1695 if (type == SDDS_STRING) {
1696 char **stringArray;
1697 if (SDDS_dataset->data[index]) {
1698 char *ptr;
1699 int64_t i;
1700 for (i = 0; i < rows; i++) {
1701 ptr = *((char **)SDDS_dataset->data[index] + i);
1702 if (ptr)
1703 free(ptr);
1704 *((char **)SDDS_dataset->data[index] + i) = NULL;
1705 }
1706 }
1707 stringArray = (char **)malloc(sizeof(char *) * rows);
1708 for (i = 0; i < rows; i++) {
1709 stringArray[i] = (char *)malloc(sizeof(char) * 40);
1710 sprintf(stringArray[i], "%.15lg", data[i]);
1711 }
1712 if (!SDDS_CopyStringArray((char **)(SDDS_dataset->data[index]), (char **)stringArray, rows)) {
1713 SDDS_SetError("Unable to set column--error copying string data (SDDS_SetColumnFromDoubles)");
1714 return 0;
1715 }
1716 for (i = 0; i < rows; i++) {
1717 free(stringArray[i]);
1718 }
1719 free(stringArray);
1720 return 1;
1721 }
1722 SDDS_SetError("Unable to set column--source type is nonnumeric (SDDS_SetColumnFromDoubles)");
1723 return 0;
1724 }
1725
1726 size = SDDS_type_size[layout->column_definition[index].type - 1];
1727
1728 if (type == SDDS_DOUBLE) {
1729 memcpy((char *)SDDS_dataset->data[index], (char *)data, rows * size);
1730 return 1;
1731 }
1732
1733 for (i = 0; i < rows; i++)
1734 if (!SDDS_CastValue(data, i, SDDS_DOUBLE, type, (char *)(SDDS_dataset->data[index]) + i * size)) {
1735 SDDS_SetError("Unable to set column--cast error (SDDS_SetColumnFromDoubles)");
1736 return 0;
1737 }
1738
1739 return 1;
1740}
1741
1742/**
1743 * @brief Sets the values for a single data column using long double-precision floating-point numbers.
1744 *
1745 * This function assigns data to a specified column within the current data table of the given SDDS dataset.
1746 * The column can be identified either by its index or by its name, based on the provided `mode`. The data
1747 * provided must be in the form of long double-precision floating-point numbers (`long double`). If the target
1748 * column is of a different numeric type, the function will perform the necessary type casting. For string columns,
1749 * the function converts the long double values to strings with appropriate formatting.
1750 *
1751 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1752 * @param mode Bitwise flags that determine how the column is identified. Valid flags include:
1753 * - `SDDS_SET_BY_INDEX`: Identify the column by its index.
1754 * - `SDDS_SET_BY_NAME`: Identify the column by its name.
1755 *
1756 * **Mode Requirements:**
1757 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
1758 *
1759 * **Syntax Based on Mode Combination:**
1760 * - `SDDS_SET_BY_INDEX`:
1761 * `int32_t SDDS_SetColumnFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, long double *data, int64_t rows, int32_t index)`
1762 * - `SDDS_SET_BY_NAME`:
1763 * `int32_t SDDS_SetColumnFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, long double *data, int64_t rows, char *name)`
1764 *
1765 * @param data Pointer to an array of long double-precision floating-point data to be assigned to the column.
1766 * The array should contain at least `rows` elements.
1767 * @param rows The number of rows (elements) in the column to be set. Must not exceed the allocated memory for the dataset.
1768 * @param ... Variable arguments specifying either the column index (`int32_t`) or column name (`char *`), depending on the `mode`.
1769 *
1770 * @return Returns `1` on successful assignment of the column data.
1771 * On failure, returns `0` and records an appropriate error message using `SDDS_SetError`.
1772 *
1773 * @note
1774 * - If the target column is of type `SDDS_STRING`, the function converts each long double value to a string
1775 * with a precision of up to 18 significant digits if supported, otherwise 15 digits.
1776 * - The function ensures that the number of rows in the new column matches the existing data table.
1777 * - It is required to call `SDDS_StartPage` before setting column values.
1778 *
1779 * @sa SDDS_SetColumnFromDoubles, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyStringArray, SDDS_CastValue
1780 */
1781int32_t SDDS_SetColumnFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, long double *data, int64_t rows, ...) {
1782 va_list argptr;
1783 int64_t i;
1784 int32_t index, retval, type, size;
1785 SDDS_LAYOUT *layout;
1786 char *name;
1787
1788 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetColumnFromLongDoubles"))
1789 return (0);
1790 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME)) {
1791 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetColumnFromLongDoubles)");
1792 return (0);
1793 }
1794 if (rows > SDDS_dataset->n_rows_allocated) {
1795 SDDS_SetError("Unable to set column values--number of rows exceeds allocated memory (SDDS_SetColumnFromLongDoubles)");
1796 return (0);
1797 }
1798 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetColumnFromLongDoubles"))
1799 return (0);
1800 if (SDDS_dataset->n_rows != 0 && SDDS_dataset->n_rows != rows) {
1801 SDDS_SetError("Number of rows in new column unequal to number in other columns (SDDS_SetColumnFromLongDoubles)");
1802 return (0);
1803 }
1804 SDDS_dataset->n_rows = rows;
1805 layout = &SDDS_dataset->layout;
1806
1807 retval = 1;
1808 va_start(argptr, rows);
1809 if (mode & SDDS_SET_BY_INDEX) {
1810 index = va_arg(argptr, int32_t);
1811 if (index < 0 || index >= layout->n_columns) {
1812 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetColumnFromLongDoubles)");
1813 retval = 0;
1814 }
1815 } else {
1816 name = va_arg(argptr, char *);
1817 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
1818 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetColumnFromLongDoubles)");
1819 retval = 0;
1820 }
1821 }
1822 va_end(argptr);
1823 if (!retval)
1824 return 0;
1825
1826 type = layout->column_definition[index].type;
1827 if (!SDDS_NUMERIC_TYPE(type)) {
1828 if (type == SDDS_STRING) {
1829 char **stringArray;
1830 if (SDDS_dataset->data[index]) {
1831 char *ptr;
1832 int64_t i;
1833 for (i = 0; i < rows; i++) {
1834 ptr = *((char **)SDDS_dataset->data[index] + i);
1835 if (ptr)
1836 free(ptr);
1837 *((char **)SDDS_dataset->data[index] + i) = NULL;
1838 }
1839 }
1840 stringArray = (char **)malloc(sizeof(char *) * rows);
1841 for (i = 0; i < rows; i++) {
1842 stringArray[i] = (char *)malloc(sizeof(char) * 40);
1843 if (LDBL_DIG == 18) {
1844 sprintf(stringArray[i], "%.18Lg", data[i]);
1845 } else {
1846 sprintf(stringArray[i], "%.15Lg", data[i]);
1847 }
1848 }
1849 if (!SDDS_CopyStringArray((char **)(SDDS_dataset->data[index]), (char **)stringArray, rows)) {
1850 SDDS_SetError("Unable to set column--error copying string data (SDDS_SetColumnFromLongDoubles)");
1851 return 0;
1852 }
1853 for (i = 0; i < rows; i++) {
1854 free(stringArray[i]);
1855 }
1856 free(stringArray);
1857 return 1;
1858 }
1859 SDDS_SetError("Unable to set column--source type is nonnumeric (SDDS_SetColumnFromLongDoubles)");
1860 return 0;
1861 }
1862
1863 size = SDDS_type_size[layout->column_definition[index].type - 1];
1864
1865 if (type == SDDS_LONGDOUBLE) {
1866 memcpy((char *)SDDS_dataset->data[index], (char *)data, rows * size);
1867 return 1;
1868 }
1869
1870 for (i = 0; i < rows; i++)
1871 if (!SDDS_CastValue(data, i, SDDS_LONGDOUBLE, type, (char *)(SDDS_dataset->data[index]) + i * size)) {
1872 SDDS_SetError("Unable to set column--cast error (SDDS_SetColumnFromLongDoubles)");
1873 return 0;
1874 }
1875
1876 return 1;
1877}
1878
1879/**
1880 * @brief Sets the values for a single data column using single-precision floating-point numbers.
1881 *
1882 * This function assigns data to a specified column within the current data table of the given SDDS dataset.
1883 * The column can be identified either by its index or by its name, based on the provided `mode`. The data
1884 * provided must be in the form of single-precision floating-point numbers (`float`). If the target column
1885 * is of a different numeric type, the function will perform the necessary type casting. For string columns,
1886 * the function converts the float values to strings with appropriate formatting.
1887 *
1888 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
1889 * @param mode Bitwise flags that determine how the column is identified. Valid flags include:
1890 * - `SDDS_SET_BY_INDEX`: Identify the column by its index.
1891 * - `SDDS_SET_BY_NAME`: Identify the column by its name.
1892 *
1893 * **Mode Requirements:**
1894 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
1895 *
1896 * **Syntax Based on Mode Combination:**
1897 * - `SDDS_SET_BY_INDEX`:
1898 * `int32_t SDDS_SetColumnFromFloats(SDDS_DATASET *SDDS_dataset, int32_t mode, float *data, int64_t rows, int32_t index)`
1899 * - `SDDS_SET_BY_NAME`:
1900 * `int32_t SDDS_SetColumnFromFloats(SDDS_DATASET *SDDS_dataset, int32_t mode, float *data, int64_t rows, char *name)`
1901 *
1902 * @param data Pointer to an array of single-precision floating-point data to be assigned to the column.
1903 * The array should contain at least `rows` elements.
1904 * @param rows The number of rows (elements) in the column to be set. Must not exceed the allocated memory for the dataset.
1905 * @param ... Variable arguments specifying either the column index (`int32_t`) or column name (`char *`), depending on the `mode`.
1906 *
1907 * @return Returns `1` on successful assignment of the column data.
1908 * On failure, returns `0` and records an appropriate error message using `SDDS_SetError`.
1909 *
1910 * @note
1911 * - If the target column is of type `SDDS_STRING`, the function converts each float value to a string
1912 * with a precision of up to 8 significant digits.
1913 * - The function ensures that the number of rows in the new column matches the existing data table.
1914 * - It is required to call `SDDS_StartPage` before setting column values.
1915 *
1916 * @sa SDDS_SetColumnFromDoubles, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyStringArray, SDDS_CastValue
1917 */
1918int32_t SDDS_SetColumnFromFloats(SDDS_DATASET *SDDS_dataset, int32_t mode, float *data, int64_t rows, ...) {
1919 va_list argptr;
1920 int64_t i;
1921 int32_t index, retval, type, size;
1922 SDDS_LAYOUT *layout;
1923 char *name;
1924
1925 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetColumnFromFloats"))
1926 return (0);
1927 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME)) {
1928 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetColumnFromFloats)");
1929 return (0);
1930 }
1931 if (rows > SDDS_dataset->n_rows_allocated) {
1932 SDDS_SetError("Unable to set column values--number of rows exceeds allocated memory (SDDS_SetColumnFromFloats)");
1933 return (0);
1934 }
1935 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetColumnFromFloats"))
1936 return (0);
1937 if (SDDS_dataset->n_rows != 0 && SDDS_dataset->n_rows != rows) {
1938 SDDS_SetError("Number of rows in new column unequal to number in other columns (SDDS_SetColumnFromFloats)");
1939 return (0);
1940 }
1941 SDDS_dataset->n_rows = rows;
1942 layout = &SDDS_dataset->layout;
1943
1944 retval = 1;
1945 va_start(argptr, rows);
1946 if (mode & SDDS_SET_BY_INDEX) {
1947 index = va_arg(argptr, int32_t);
1948 if (index < 0 || index >= layout->n_columns) {
1949 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetColumnFromFloats)");
1950 retval = 0;
1951 }
1952 } else {
1953 name = va_arg(argptr, char *);
1954 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
1955 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetColumnFromFloats)");
1956 retval = 0;
1957 }
1958 }
1959 va_end(argptr);
1960 if (!retval)
1961 return 0;
1962
1963 type = layout->column_definition[index].type;
1964 if (!SDDS_NUMERIC_TYPE(type)) {
1965 if (type == SDDS_STRING) {
1966 char **stringArray;
1967 if (SDDS_dataset->data[index]) {
1968 char *ptr;
1969 int64_t i;
1970 for (i = 0; i < rows; i++) {
1971 ptr = *((char **)SDDS_dataset->data[index] + i);
1972 if (ptr)
1973 free(ptr);
1974 *((char **)SDDS_dataset->data[index] + i) = NULL;
1975 }
1976 }
1977 stringArray = (char **)malloc(sizeof(char *) * rows);
1978 for (i = 0; i < rows; i++) {
1979 stringArray[i] = (char *)malloc(sizeof(char) * 40);
1980 sprintf(stringArray[i], "%.8g", data[i]);
1981 }
1982 if (!SDDS_CopyStringArray((char **)(SDDS_dataset->data[index]), (char **)stringArray, rows)) {
1983 SDDS_SetError("Unable to set column--error copying string data (SDDS_SetColumnFromFloats)");
1984 return 0;
1985 }
1986 for (i = 0; i < rows; i++) {
1987 free(stringArray[i]);
1988 }
1989 free(stringArray);
1990 return 1;
1991 }
1992 SDDS_SetError("Unable to set column--source type is nonnumeric (SDDS_SetColumnFromFloats)");
1993 return 0;
1994 }
1995
1996 size = SDDS_type_size[layout->column_definition[index].type - 1];
1997
1998 if (type == SDDS_FLOAT) {
1999 memcpy((char *)SDDS_dataset->data[index], (char *)data, rows * size);
2000 return 1;
2001 }
2002
2003 for (i = 0; i < rows; i++)
2004 if (!SDDS_CastValue(data, i, SDDS_FLOAT, type, (char *)(SDDS_dataset->data[index]) + i * size)) {
2005 SDDS_SetError("Unable to set column--cast error (SDDS_SetColumnFromFloats)");
2006 return 0;
2007 }
2008
2009 return 1;
2010}
2011
2012/**
2013 * @brief Sets the values for a single data column using long integer numbers.
2014 *
2015 * This function assigns data to a specified column within the current data table of the given SDDS dataset.
2016 * The column can be identified either by its index or by its name, based on the provided `mode`. The data
2017 * provided must be in the form of long integers (`int32_t`). If the target column is of a different numeric type,
2018 * the function will perform the necessary type casting. For string columns, the function converts the integer
2019 * values to strings with appropriate formatting.
2020 *
2021 * @param SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the data set.
2022 * @param mode Bitwise flags that determine how the column is identified. Valid flags include:
2023 * - `SDDS_SET_BY_INDEX`: Identify the column by its index.
2024 * - `SDDS_SET_BY_NAME`: Identify the column by its name.
2025 *
2026 * **Mode Requirements:**
2027 * - Exactly one of `SDDS_SET_BY_INDEX` or `SDDS_SET_BY_NAME` must be set.
2028 *
2029 * **Syntax Based on Mode Combination:**
2030 * - `SDDS_SET_BY_INDEX`:
2031 * `int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows, int32_t index)`
2032 * - `SDDS_SET_BY_NAME`:
2033 * `int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows, char *name)`
2034 *
2035 * @param data Pointer to an array of long integer data to be assigned to the column.
2036 * The array should contain at least `rows` elements.
2037 * @param rows The number of rows (elements) in the column to be set. Must not exceed the allocated memory for the dataset.
2038 * @param ... Variable arguments specifying either the column index (`int32_t`) or column name (`char *`), depending on the `mode`.
2039 *
2040 * @return Returns `1` on successful assignment of the column data.
2041 * On failure, returns `0` and records an appropriate error message using `SDDS_SetError`.
2042 *
2043 * @note
2044 * - If the target column is of type `SDDS_STRING`, the function converts each long integer value to a string
2045 * using the `sprintf` function with the appropriate format specifier.
2046 * - The function ensures that the number of rows in the new column matches the existing data table.
2047 * - It is required to call `SDDS_StartPage` before setting column values.
2048 *
2049 * @sa SDDS_SetColumnFromDoubles, SDDS_SetError, SDDS_GetColumnIndex, SDDS_CopyStringArray, SDDS_CastValue
2050 */
2051int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows, ...) {
2052 va_list argptr;
2053 int64_t i;
2054 int32_t index, retval, type, size;
2055 SDDS_LAYOUT *layout;
2056 char *name;
2057
2058 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetColumnFromLongs"))
2059 return (0);
2060 if (!(mode & SDDS_SET_BY_INDEX || mode & SDDS_SET_BY_NAME)) {
2061 SDDS_SetError("Unable to set column values--unknown mode (SDDS_SetColumnFromLongs)");
2062 return (0);
2063 }
2064 if (rows > SDDS_dataset->n_rows_allocated) {
2065 SDDS_SetError("Unable to set column values--number of rows exceeds allocated memory (SDDS_SetColumnFromLongs)");
2066 return (0);
2067 }
2068 if (!SDDS_CheckTabularData(SDDS_dataset, "SDDS_SetColumnFromLongs"))
2069 return (0);
2070 if (SDDS_dataset->n_rows != 0 && SDDS_dataset->n_rows != rows) {
2071 SDDS_SetError("Number of rows in new column unequal to number in other columns (SDDS_SetColumnFromLongs)");
2072 return (0);
2073 }
2074 SDDS_dataset->n_rows = rows;
2075 layout = &SDDS_dataset->layout;
2076
2077 retval = 1;
2078 va_start(argptr, rows);
2079 if (mode & SDDS_SET_BY_INDEX) {
2080 index = va_arg(argptr, int32_t);
2081 if (index < 0 || index >= layout->n_columns) {
2082 SDDS_SetError("Unable to set column values--index out of range (SDDS_SetColumnFromLongs)");
2083 retval = 0;
2084 }
2085 } else {
2086 name = va_arg(argptr, char *);
2087 if ((index = SDDS_GetColumnIndex(SDDS_dataset, name)) < 0) {
2088 SDDS_SetError("Unable to set column values--name not recognized (SDDS_SetColumnFromLongs)");
2089 retval = 0;
2090 }
2091 }
2092 va_end(argptr);
2093 if (!retval)
2094 return 0;
2095
2096 type = layout->column_definition[index].type;
2097 if (!SDDS_NUMERIC_TYPE(type)) {
2098 if (type == SDDS_STRING) {
2099 char **stringArray;
2100 if (SDDS_dataset->data[index]) {
2101 char *ptr;
2102 int64_t i;
2103 for (i = 0; i < rows; i++) {
2104 ptr = *((char **)SDDS_dataset->data[index] + i);
2105 if (ptr)
2106 free(ptr);
2107 *((char **)SDDS_dataset->data[index] + i) = NULL;
2108 }
2109 }
2110 stringArray = (char **)malloc(sizeof(char *) * rows);
2111 for (i = 0; i < rows; i++) {
2112 stringArray[i] = (char *)malloc(sizeof(char) * 40);
2113 sprintf(stringArray[i], "%" PRId32, data[i]);
2114 }
2115 if (!SDDS_CopyStringArray((char **)(SDDS_dataset->data[index]), (char **)stringArray, rows)) {
2116 SDDS_SetError("Unable to set column--error copying string data (SDDS_SetColumnFromLongs)");
2117 return 0;
2118 }
2119 for (i = 0; i < rows; i++) {
2120 free(stringArray[i]);
2121 }
2122 free(stringArray);
2123 return 1;
2124 }
2125 SDDS_SetError("Unable to set column--source type is nonnumeric (SDDS_SetColumnFromLongs)");
2126 return 0;
2127 }
2128
2129 size = SDDS_type_size[layout->column_definition[index].type - 1];
2130
2131 if (type == SDDS_LONG) {
2132 memcpy((char *)SDDS_dataset->data[index], (char *)data, rows * size);
2133 return 1;
2134 }
2135
2136 for (i = 0; i < rows; i++)
2137 if (!SDDS_CastValue(data, i, SDDS_LONG, type, (char *)(SDDS_dataset->data[index]) + i * size)) {
2138 SDDS_SetError("Unable to set column--cast error (SDDS_SetColumnFromLongs)");
2139 return 0;
2140 }
2141
2142 return 1;
2143}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_RestoreLayout(SDDS_DATASET *SDDS_dataset)
Definition SDDS_copy.c:697
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_AppendToArrayVararg(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, int32_t elements,...)
Appends data to an existing array variable in the SDDS dataset using variable arguments for dimension...
int32_t SDDS_AllocateColumnFlags(SDDS_DATASET *SDDS_target)
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetArrayVararg(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer,...)
Sets the values of an array variable in the SDDS dataset using variable arguments for dimensions.
int32_t SDDS_SetColumnFromFloats(SDDS_DATASET *SDDS_dataset, int32_t mode, float *data, int64_t rows,...)
Sets the values for a single data column using single-precision floating-point numbers.
int32_t SDDS_SetParameter(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_ClearPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_SetColumnFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, long double *data, int64_t rows,...)
Sets the values for a single data column using long double-precision floating-point numbers.
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_ShortenTable(SDDS_DATASET *SDDS_dataset, int64_t rows)
int32_t SDDS_SetParametersFromLongDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetArray(SDDS_DATASET *SDDS_dataset, char *array_name, int32_t mode, void *data_pointer, int32_t *dimension)
Sets the values of an array variable in the SDDS dataset using specified dimensions.
int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows,...)
Sets the values for a single data column using long integer numbers.
int32_t SDDS_AdvanceCounter(int32_t *counter, int32_t *max_count, int32_t n_indices)
Advances a multi-dimensional counter based on maximum counts for each dimension.
int32_t SDDS_UpdateRowCount(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_FreeStringData(SDDS_DATASET *SDDS_dataset)
Internal definitions and function declarations for SDDS with LZMA support.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_SetError0(char *error_text)
Internal function to record an error message in the SDDS error stack.
Definition SDDS_utils.c:437
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void * SDDS_CastValue(void *data, int64_t index, int32_t data_type, int32_t desired_type, void *memory)
Casts a value from one SDDS data type to another.
int32_t SDDS_SetMemory(void *mem, int64_t n_elements, int32_t data_type,...)
Initializes a memory block with a sequence of values based on a specified data type.
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:618
int32_t SDDS_CopyStringArray(char **target, char **source, int64_t n_strings)
Copies an array of strings from source to target.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:705
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:922
int32_t SDDS_CheckTabularData(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the consistency of tabular data within an SDDS dataset.
Definition SDDS_utils.c:643
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:743
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49