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