SDDSlib
Loading...
Searching...
No Matches
SDDS_info.c
Go to the documentation of this file.
1/**
2 * @file SDDS_info.c
3 * @brief This file contains routines for getting the meta data for the SDDS objects.
4 *
5 * This file provides functions for getting information about the SDDS columns, parameters and arrays.
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
16 */
17
18#include "mdb.h"
19#include "match_string.h"
20#include "SDDS.h"
21#include "SDDS_internal.h"
22
23/**
24 * @brief Retrieves information about a specified column in the SDDS dataset.
25 *
26 * This function is the preferred alternative to `SDDS_GetColumnDefinition`. It allows you to obtain information about a specific field of a column, either by the column's name or index.
27 *
28 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
29 * @param[in] field_name A null-terminated string specifying the name of the field for which information is requested.
30 * @param[out] memory Pointer to a variable where the retrieved information will be stored. The variable should be of type `data_type*`, where `data_type` corresponds to the type of the requested information. For `STRING` information, use `char*`. If `memory` is `NULL`, the function will verify the existence and type of the information, returning the data type without storing any data.
31 * @param[in] mode Specifies how to identify the column. Valid values are:
32 * - `SDDS_GET_BY_NAME`: Identify the column by its name. Requires an additional argument of type `char*` (column name).
33 * - `SDDS_GET_BY_INDEX`: Identify the column by its index. Requires an additional argument of type `int32_t` (column index).
34 *
35 * @return On success, returns the SDDS data type of the requested information. On failure, returns zero and records an error message.
36 *
37 * @note This function uses variable arguments to accept either the column name or index based on the `mode` parameter.
38 *
39 * @see SDDS_GetColumnDefinition
40 */
41int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
42 int32_t field_index, type;
43 int32_t column_index;
44 COLUMN_DEFINITION *columndef;
45 char *column_name;
46 va_list argptr;
47 int32_t retval;
48
49 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_GetColumnInformation"))
50 return (0);
51
52 if (!field_name) {
53 SDDS_SetError("NULL field name passed. (SDDS_GetColumnInformation)");
54 return (0);
55 }
56
57 va_start(argptr, mode);
58 retval = 1;
59 if (mode & SDDS_GET_BY_INDEX) {
60 if ((column_index = va_arg(argptr, int32_t)) < 0 || column_index >= SDDS_dataset->layout.n_columns) {
61 SDDS_SetError("Invalid column index passed. (SDDS_GetColumnInformation)");
62 retval = 0;
63 }
64 } else {
65 if (!(column_name = va_arg(argptr, char *))) {
66 SDDS_SetError("NULL column name passed. (SDDS_GetColumnInformation)");
67 retval = 0;
68 }
69 if ((column_index = SDDS_GetColumnIndex(SDDS_dataset, column_name)) < 0) {
70 SDDS_SetError("Unknown column name given (SDDS_GetColumnInformation)");
71 retval = 0;
72 }
73 }
74 columndef = SDDS_dataset->layout.column_definition + column_index;
75 va_end(argptr);
76 if (!retval)
77 return (0);
78
79 for (field_index = 0; field_index < SDDS_COLUMN_FIELDS; field_index++)
80 if (strcmp(field_name, SDDS_ColumnFieldInformation[field_index].name) == 0)
81 break;
82 if (field_index == SDDS_COLUMN_FIELDS) {
83 SDDS_SetError("Unknown field name given (SDDS_GetColumnInformation)");
84 return (0);
85 }
86 type = SDDS_ColumnFieldInformation[field_index].type;
87 if (!memory)
88 return (type);
89 if (type == SDDS_STRING) {
90 if (!SDDS_CopyString((char **)memory, *((char **)((char *)columndef + SDDS_ColumnFieldInformation[field_index].offset)))) {
91 SDDS_SetError("Unable to copy field data (SDDS_GetColumnInformation)");
92 return (0);
93 }
94 } else
95 memcpy(memory, (char *)columndef + SDDS_ColumnFieldInformation[field_index].offset, SDDS_type_size[type - 1]);
96 return (type);
97}
98
99/**
100 * @brief Retrieves information about a specified parameter in the SDDS dataset.
101 *
102 * This function is the preferred alternative to `SDDS_GetParameterDefinition`. It allows you to obtain information about a specific field of a parameter, either by the parameter's name or index.
103 *
104 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
105 * @param[in] field_name A null-terminated string specifying the name of the field for which information is requested.
106 * @param[out] memory Pointer to a variable where the retrieved information will be stored. The variable should be of type `data_type*`, where `data_type` corresponds to the type of the requested information. For `STRING` information, use `char*`. If `memory` is `NULL`, the function will verify the existence and type of the information, returning the data type without storing any data.
107 * @param[in] mode Specifies how to identify the parameter. Valid values are:
108 * - `SDDS_GET_BY_NAME`: Identify the parameter by its name. Requires an additional argument of type `char*` (parameter name).
109 * - `SDDS_GET_BY_INDEX`: Identify the parameter by its index. Requires an additional argument of type `int32_t` (parameter index).
110 *
111 * @return On success, returns the SDDS data type of the requested information. On failure, returns zero and records an error message.
112 *
113 * @note This function uses variable arguments to accept either the parameter name or index based on the `mode` parameter.
114 *
115 * @see SDDS_GetParameterDefinition
116 */
117int32_t SDDS_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
118 int32_t field_index, type, parameter_index;
119 PARAMETER_DEFINITION *parameterdef;
120 char *parameter_name;
121 va_list argptr;
122 int32_t retval;
123
124 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_GetParameterInformation"))
125 return (0);
126
127 if (!field_name) {
128 SDDS_SetError("NULL field name passed. (SDDS_GetParameterInformation)");
129 return (0);
130 }
131
132 va_start(argptr, mode);
133 retval = 1;
134 if (mode & SDDS_GET_BY_INDEX) {
135 if ((parameter_index = va_arg(argptr, int32_t)) < 0 || parameter_index >= SDDS_dataset->layout.n_parameters) {
136 SDDS_SetError("Invalid parameter index passed. (SDDS_GetParameterInformation)");
137 retval = 0;
138 }
139 } else {
140 if (!(parameter_name = va_arg(argptr, char *))) {
141 SDDS_SetError("NULL parameter name passed. (SDDS_GetParameterInformation)");
142 retval = 0;
143 }
144 if ((parameter_index = SDDS_GetParameterIndex(SDDS_dataset, parameter_name)) < 0) {
145 SDDS_SetError("Unknown parameter name given (SDDS_GetParameterInformation)");
146 retval = 0;
147 }
148 }
149 parameterdef = SDDS_dataset->layout.parameter_definition + parameter_index;
150 va_end(argptr);
151 if (!retval)
152 return (0);
153
154 for (field_index = 0; field_index < SDDS_PARAMETER_FIELDS; field_index++)
155 if (strcmp(field_name, SDDS_ParameterFieldInformation[field_index].name) == 0)
156 break;
157 if (field_index == SDDS_PARAMETER_FIELDS) {
158 SDDS_SetError("Unknown field name given (SDDS_GetParameterInformation)");
159 return (0);
160 }
161 type = SDDS_ParameterFieldInformation[field_index].type;
162 if (!memory)
163 return (type);
164 if (type == SDDS_STRING) {
165 if (!SDDS_CopyString((char **)memory, *((char **)((char *)parameterdef + SDDS_ParameterFieldInformation[field_index].offset)))) {
166 SDDS_SetError("Unable to copy field data (SDDS_GetParameterInformation)");
167 return (0);
168 }
169 } else
170 memcpy(memory, (char *)parameterdef + SDDS_ParameterFieldInformation[field_index].offset, SDDS_type_size[type - 1]);
171 return (type);
172}
173
174/**
175 * @brief Retrieves information about a specified array in the SDDS dataset.
176 *
177 * This function is the preferred alternative to `SDDS_GetArrayDefinition`. It allows you to obtain information about a specific field of an array, either by the array's name or index.
178 *
179 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
180 * @param[in] field_name A null-terminated string specifying the name of the field for which information is requested.
181 * @param[out] memory Pointer to a variable where the retrieved information will be stored. The variable should be of type `data_type*`, where `data_type` corresponds to the type of the requested information. For `STRING` information, use `char*`. If `memory` is `NULL`, the function will verify the existence and type of the information, returning the data type without storing any data.
182 * @param[in] mode Specifies how to identify the array. Valid values are:
183 * - `SDDS_GET_BY_NAME`: Identify the array by its name. Requires an additional argument of type `char*` (array name).
184 * - `SDDS_GET_BY_INDEX`: Identify the array by its index. Requires an additional argument of type `int32_t` (array index).
185 *
186 * @return On success, returns the SDDS data type of the requested information. On failure, returns zero and records an error message.
187 *
188 * @note This function uses variable arguments to accept either the array name or index based on the `mode` parameter.
189 *
190 * @see SDDS_GetArrayDefinition
191 */
192int32_t SDDS_GetArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
193 int32_t field_index, type, array_index;
194 ARRAY_DEFINITION *arraydef;
195 char *array_name;
196 va_list argptr;
197 int32_t retval;
198
199 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_GetArrayInformation"))
200 return (0);
201
202 if (!field_name) {
203 SDDS_SetError("NULL field name passed. (SDDS_GetArrayInformation)");
204 return (0);
205 }
206
207 va_start(argptr, mode);
208 retval = 1;
209 if (mode & SDDS_GET_BY_INDEX) {
210 if ((array_index = va_arg(argptr, int32_t)) < 0 || array_index >= SDDS_dataset->layout.n_arrays) {
211 SDDS_SetError("Invalid array index passed. (SDDS_GetArrayInformation)");
212 retval = 0;
213 }
214 } else {
215 if (!(array_name = va_arg(argptr, char *))) {
216 SDDS_SetError("NULL array name passed. (SDDS_GetArrayInformation)");
217 retval = 0;
218 }
219 if ((array_index = SDDS_GetArrayIndex(SDDS_dataset, array_name)) < 0) {
220 SDDS_SetError("Unknown array name given (SDDS_GetArrayInformation)");
221 retval = 0;
222 }
223 }
224 arraydef = SDDS_dataset->layout.array_definition + array_index;
225 va_end(argptr);
226 if (!retval)
227 return (0);
228
229 for (field_index = 0; field_index < SDDS_ARRAY_FIELDS; field_index++)
230 if (strcmp(field_name, SDDS_ArrayFieldInformation[field_index].name) == 0)
231 break;
232 if (field_index == SDDS_ARRAY_FIELDS) {
233 SDDS_SetError("Unknown field name given (SDDS_GetArrayInformation)");
234 return (0);
235 }
236 type = SDDS_ArrayFieldInformation[field_index].type;
237 if (!memory)
238 return (type);
239 if (type == SDDS_STRING) {
240 if (!SDDS_CopyString((char **)memory, *((char **)((char *)arraydef + SDDS_ArrayFieldInformation[field_index].offset)))) {
241 SDDS_SetError("Unable to copy field data (SDDS_GetArrayInformation)");
242 return (0);
243 }
244 } else
245 memcpy(memory, (char *)arraydef + SDDS_ArrayFieldInformation[field_index].offset, SDDS_type_size[type - 1]);
246 return (type);
247}
248
249/**
250 * @brief Retrieves information about a specified associate in the SDDS dataset.
251 *
252 * This function allows you to obtain information about a specific field of an associate, either by the associate's name or index.
253 *
254 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
255 * @param[in] field_name A null-terminated string specifying the name of the field for which information is requested.
256 * @param[out] memory Pointer to a variable where the retrieved information will be stored. The variable should be of type `data_type*`, where `data_type` corresponds to the type of the requested information. For `STRING` information, use `char*`. If `memory` is `NULL`, the function will verify the existence and type of the information, returning the data type without storing any data.
257 * @param[in] mode Specifies how to identify the associate. Valid values are:
258 * - `SDDS_GET_BY_NAME`: Identify the associate by its name. Requires an additional argument of type `char*` (associate name).
259 * - `SDDS_GET_BY_INDEX`: Identify the associate by its index. Requires an additional argument of type `int32_t` (associate index).
260 *
261 * @return On success, returns the SDDS data type of the requested information. On failure, returns zero and records an error message.
262 *
263 * @note This function uses variable arguments to accept either the associate name or index based on the `mode` parameter.
264 *
265 * @see SDDS_GetAssociateDefinition
266 */
267int32_t SDDS_GetAssociateInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
268 int32_t field_index, type, associate_index;
269 ASSOCIATE_DEFINITION *associatedef;
270 char *associate_name;
271 va_list argptr;
272 int32_t retval;
273
274 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_GetAssociateInformation"))
275 return (0);
276
277 if (!field_name) {
278 SDDS_SetError("NULL field name passed. (SDDS_GetAssociateInformation)");
279 return (0);
280 }
281
282 va_start(argptr, mode);
283 retval = 1;
284 if (mode & SDDS_GET_BY_INDEX) {
285 if ((associate_index = va_arg(argptr, int32_t)) < 0 || associate_index >= SDDS_dataset->layout.n_associates) {
286 SDDS_SetError("Invalid associate index passed. (SDDS_GetAssociateInformation)");
287 retval = 0;
288 }
289 } else {
290 if (!(associate_name = va_arg(argptr, char *))) {
291 SDDS_SetError("NULL associate name passed. (SDDS_GetAssociateInformation)");
292 retval = 0;
293 }
294 if ((associate_index = SDDS_GetAssociateIndex(SDDS_dataset, associate_name)) < 0) {
295 SDDS_SetError("Unknown associate name given (SDDS_GetAssociateInformation)");
296 retval = 0;
297 }
298 }
299 associatedef = SDDS_dataset->layout.associate_definition + associate_index;
300 va_end(argptr);
301 if (!retval)
302 return (0);
303
304 for (field_index = 0; field_index < SDDS_ASSOCIATE_FIELDS; field_index++)
305 if (strcmp(field_name, SDDS_AssociateFieldInformation[field_index].name) == 0)
306 break;
307 if (field_index == SDDS_ASSOCIATE_FIELDS) {
308 SDDS_SetError("Unknown field name given (SDDS_GetAssociateInformation)");
309 return (0);
310 }
311 type = SDDS_AssociateFieldInformation[field_index].type;
312 if (!memory)
313 return (type);
314 if (type == SDDS_STRING) {
315 if (!SDDS_CopyString((char **)memory, *((char **)((char *)associatedef + SDDS_AssociateFieldInformation[field_index].offset)))) {
316 SDDS_SetError("Unable to copy field data (SDDS_GetAssociateInformation)");
317 return (0);
318 }
319 } else
320 memcpy(memory, (char *)associatedef + SDDS_AssociateFieldInformation[field_index].offset, SDDS_type_size[type - 1]);
321 return (type);
322}
323
324/**
325 * @brief Modifies a specific field in a column definition within the SDDS dataset.
326 *
327 * This function allows you to change a particular field of a column definition, identified either by its name or index. The new value for the field can be provided either as a direct value or as a string, depending on the field type.
328 *
329 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
330 * @param[in] field_name A null-terminated string specifying the name of the field to be modified.
331 * @param[in] memory Pointer to the new value for the field. The type of this pointer should correspond to the data type of the field being modified:
332 * - For non-string fields, provide a pointer to the appropriate data type (e.g., `int32_t*`, `double*`).
333 * - For string fields, provide a `char*`.
334 * @param[in] mode A bitwise combination of the following constants to specify how to identify the column and how to pass the new value:
335 * - `SDDS_SET_BY_INDEX`: Identify the column by its index. Requires an additional argument of type `int32_t` (column index).
336 * - `SDDS_SET_BY_NAME`: Identify the column by its name. Requires an additional argument of type `char*` (column name).
337 * - `SDDS_PASS_BY_VALUE`: The new value is provided as a direct value (non-string fields).
338 * - `SDDS_PASS_BY_STRING`: The new value is provided as a string (string fields).
339 *
340 * The valid combinations of `mode` are:
341 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE`:
342 * ```c
343 * int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, int32_t column_index);
344 * ```
345 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE`:
346 * ```c
347 * int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, char *column_name);
348 * ```
349 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_STRING`:
350 * ```c
351 * int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, int32_t column_index);
352 * ```
353 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_STRING`:
354 * ```c
355 * int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, char *column_name);
356 * ```
357 *
358 * @return On success, returns the SDDS data type of the modified information. On failure, returns zero and records an error message.
359 *
360 * @note This function uses variable arguments to accept either the column name or index based on the `mode` parameter.
361 *
362 * @see SDDS_GetColumnInformation
363 */
364int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
365 int32_t field_index, type, givenType;
366 int32_t i, column_index;
367 COLUMN_DEFINITION *columndef;
368 char *column_name;
369 va_list argptr;
370 int32_t retval;
371 double buffer[4];
372
373 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ChangeColumnInformation"))
374 return (0);
375
376 if (!field_name) {
377 SDDS_SetError("NULL field name passed. (SDDS_ChangeColumnInformation)");
378 return (0);
379 }
380
381 va_start(argptr, mode);
382 retval = 1;
383 if (mode & SDDS_SET_BY_INDEX) {
384 if ((column_index = va_arg(argptr, int32_t)) < 0 || column_index >= SDDS_dataset->layout.n_columns) {
385 SDDS_SetError("Invalid column index passed. (SDDS_ChangeColumnInformation)");
386 retval = 0;
387 }
388 } else {
389 if (!(column_name = va_arg(argptr, char *))) {
390 SDDS_SetError("NULL column name passed. (SDDS_ChangeColumnInformation)");
391 retval = 0;
392 }
393 if ((column_index = SDDS_GetColumnIndex(SDDS_dataset, column_name)) < 0) {
394 SDDS_SetError("Unknown column name given (SDDS_ChangeColumnInformation)");
395 retval = 0;
396 }
397 }
398 columndef = SDDS_dataset->layout.column_definition + column_index;
399 va_end(argptr);
400 if (!retval)
401 return (0);
402
403 for (field_index = 0; field_index < SDDS_COLUMN_FIELDS; field_index++)
404 if (strcmp(field_name, SDDS_ColumnFieldInformation[field_index].name) == 0)
405 break;
406 if (field_index == SDDS_COLUMN_FIELDS) {
407 SDDS_SetError("Unknown field name given (SDDS_ChangeColumnInformation)");
408 return (0);
409 }
410 type = SDDS_ColumnFieldInformation[field_index].type;
411 if (!memory)
412 return (type);
413 if (type == SDDS_STRING) {
414 if (!SDDS_CopyString(((char **)((char *)columndef + SDDS_ColumnFieldInformation[field_index].offset)), (char *)memory)) {
415 SDDS_SetError("Unable to copy field data (SDDS_ChangeColumnInformation)");
416 return (0);
417 }
418 if (strcmp(field_name, "name") == 0) {
419 for (i = 0; i < SDDS_dataset->layout.n_columns; i++)
420 if (column_index == SDDS_dataset->layout.column_index[i]->index)
421 break;
422 if (i == SDDS_dataset->layout.n_columns) {
423 SDDS_SetError("Unable to copy field data--column indexing problem (SDDS_ChangeColumnInformation)");
424 return (0);
425 }
426 SDDS_dataset->layout.column_index[i]->name = SDDS_dataset->layout.column_definition[column_index].name;
427 qsort((char *)SDDS_dataset->layout.column_index, SDDS_dataset->layout.n_columns, sizeof(*SDDS_dataset->layout.column_index), SDDS_CompareIndexedNamesPtr);
428 }
429 } else {
430 if (mode & SDDS_PASS_BY_STRING) {
431 if (strcmp(field_name, "type") == 0 && (givenType = SDDS_IdentifyType((char *)memory)) > 0)
432 /* the type has been passed as a string (e.g., "double") */
433 memcpy((char *)buffer, (char *)&givenType, sizeof(givenType));
434 else if (!SDDS_ScanData((char *)memory, type, 0, (void *)buffer, 0, 0)) {
435 SDDS_SetError("Unable to scan string data (SDDS_ChangeColumnInformation)");
436 return (0);
437 }
438 memcpy((char *)columndef + SDDS_ColumnFieldInformation[field_index].offset, (void *)buffer, SDDS_type_size[type - 1]);
439 } else
440 memcpy((char *)columndef + SDDS_ColumnFieldInformation[field_index].offset, memory, SDDS_type_size[type - 1]);
441 }
442 return (type);
443}
444
445/**
446 * @brief Modifies a specific field in a parameter definition within the SDDS dataset.
447 *
448 * This function allows you to change a particular field of a parameter definition, identified either by its name or index. The new value for the field can be provided either as a direct value or as a string, depending on the field type.
449 *
450 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
451 * @param[in] field_name A null-terminated string specifying the name of the field to be modified.
452 * @param[in] memory Pointer to the new value for the field. The type of this pointer should correspond to the data type of the field being modified:
453 * - For non-string fields, provide a pointer to the appropriate data type (e.g., `int32_t*`, `double*`).
454 * - For string fields, provide a `char*`.
455 * @param[in] mode A bitwise combination of the following constants to specify how to identify the parameter and how to pass the new value:
456 * - `SDDS_SET_BY_INDEX`: Identify the parameter by its index. Requires an additional argument of type `int32_t` (parameter index).
457 * - `SDDS_SET_BY_NAME`: Identify the parameter by its name. Requires an additional argument of type `char*` (parameter name).
458 * - `SDDS_PASS_BY_VALUE`: The new value is provided as a direct value (non-string fields).
459 * - `SDDS_PASS_BY_STRING`: The new value is provided as a string (string fields).
460 *
461 * The valid combinations of `mode` are:
462 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE`:
463 * ```c
464 * int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, int32_t parameter_index);
465 * ```
466 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE`:
467 * ```c
468 * int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, char *parameter_name);
469 * ```
470 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_STRING`:
471 * ```c
472 * int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, int32_t parameter_index);
473 * ```
474 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_STRING`:
475 * ```c
476 * int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, char *parameter_name);
477 * ```
478 *
479 * @return On success, returns the SDDS data type of the modified information. On failure, returns zero and records an error message.
480 *
481 * @note This function uses variable arguments to accept either the parameter name or index based on the `mode` parameter.
482 *
483 * @see SDDS_GetParameterInformation
484 */
485int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
486 int32_t field_index, type, parameter_index, givenType;
487 PARAMETER_DEFINITION *parameterdef;
488 char *parameter_name;
489 va_list argptr;
490 int32_t retval;
491 double buffer[4];
492
493 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ChangeParameterInformation"))
494 return (0);
495
496 if (!field_name) {
497 SDDS_SetError("NULL field name passed. (SDDS_ChangeParameterInformation)");
498 return (0);
499 }
500
501 va_start(argptr, mode);
502 retval = 1;
503 if (mode & SDDS_SET_BY_INDEX) {
504 if ((parameter_index = va_arg(argptr, int32_t)) < 0 || parameter_index >= SDDS_dataset->layout.n_parameters) {
505 SDDS_SetError("Invalid parameter index passed. (SDDS_ChangeParameterInformation)");
506 retval = 0;
507 }
508 } else {
509 if (!(parameter_name = va_arg(argptr, char *))) {
510 SDDS_SetError("NULL parameter name passed. (SDDS_ChangeParameterInformation)");
511 retval = 0;
512 }
513 if ((parameter_index = SDDS_GetParameterIndex(SDDS_dataset, parameter_name)) < 0) {
514 SDDS_SetError("Unknown parameter name given (SDDS_ChangeParameterInformation)");
515 retval = 0;
516 }
517 }
518 parameterdef = SDDS_dataset->layout.parameter_definition + parameter_index;
519 va_end(argptr);
520 if (!retval)
521 return (0);
522
523 for (field_index = 0; field_index < SDDS_PARAMETER_FIELDS; field_index++)
524 if (strcmp(field_name, SDDS_ParameterFieldInformation[field_index].name) == 0)
525 break;
526 if (field_index == SDDS_PARAMETER_FIELDS) {
527 SDDS_SetError("Unknown field name given (SDDS_ChangeParameterInformation)");
528 return (0);
529 }
530 type = SDDS_ParameterFieldInformation[field_index].type;
531 if (!memory)
532 return (type);
533 if (type == SDDS_STRING) {
534 if (!SDDS_CopyString(((char **)((char *)parameterdef + SDDS_ParameterFieldInformation[field_index].offset)), (char *)memory)) {
535 SDDS_SetError("Unable to copy field data (SDDS_ChangeParameterInformation)");
536 return (0);
537 }
538 if (strcmp(field_name, "name") == 0)
539 qsort((char *)SDDS_dataset->layout.parameter_index, SDDS_dataset->layout.n_parameters, sizeof(*SDDS_dataset->layout.parameter_index), SDDS_CompareIndexedNamesPtr);
540 } else {
541 if (mode & SDDS_PASS_BY_STRING) {
542 if (strcmp(field_name, "type") == 0 && (givenType = SDDS_IdentifyType((char *)memory)) > 0)
543 /* the type has been passed as a string (e.g., "double") */
544 memcpy((char *)buffer, (char *)&givenType, sizeof(givenType));
545 else if (!SDDS_ScanData((char *)memory, type, 0, (void *)buffer, 0, 0)) {
546 SDDS_SetError("Unable to scan string data (SDDS_ChangeParameterInformation)");
547 return (0);
548 }
549 memcpy((char *)parameterdef + SDDS_ParameterFieldInformation[field_index].offset, (void *)buffer, SDDS_type_size[type - 1]);
550 } else
551 memcpy((char *)parameterdef + SDDS_ParameterFieldInformation[field_index].offset, memory, SDDS_type_size[type - 1]);
552 }
553
554 return (type);
555}
556
557/**
558 * @brief Modifies a specific field in an array definition within the SDDS dataset.
559 *
560 * This function allows you to change a particular field of an array definition, identified either by its name or index. The new value for the field can be provided either as a direct value or as a string, depending on the field type.
561 *
562 * @param[in] SDDS_dataset Pointer to the `SDDS_DATASET` structure representing the dataset.
563 * @param[in] field_name A null-terminated string specifying the name of the field to be modified.
564 * @param[in] memory Pointer to the new value for the field. The type of this pointer should correspond to the data type of the field being modified:
565 * - For non-string fields, provide a pointer to the appropriate data type (e.g., `int32_t*`, `double*`).
566 * - For string fields, provide a `char*`.
567 * @param[in] mode A bitwise combination of the following constants to specify how to identify the array and how to pass the new value:
568 * - `SDDS_SET_BY_INDEX`: Identify the array by its index. Requires an additional argument of type `int32_t` (array index).
569 * - `SDDS_SET_BY_NAME`: Identify the array by its name. Requires an additional argument of type `char*` (array name).
570 * - `SDDS_PASS_BY_VALUE`: The new value is provided as a direct value (non-string fields).
571 * - `SDDS_PASS_BY_STRING`: The new value is provided as a string (string fields).
572 *
573 * The valid combinations of `mode` are:
574 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE`:
575 * ```c
576 * int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, int32_t array_index);
577 * ```
578 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE`:
579 * ```c
580 * int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, char *array_name);
581 * ```
582 * - `SDDS_SET_BY_INDEX | SDDS_PASS_BY_STRING`:
583 * ```c
584 * int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, int32_t array_index);
585 * ```
586 * - `SDDS_SET_BY_NAME | SDDS_PASS_BY_STRING`:
587 * ```c
588 * int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, char *memory, int32_t mode, char *array_name);
589 * ```
590 *
591 * @return On success, returns the SDDS data type of the modified information. On failure, returns zero and records an error message.
592 *
593 * @note This function uses variable arguments to accept either the array name or index based on the `mode` parameter.
594 *
595 * @see SDDS_GetArrayInformation
596 */
597int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode, ...) {
598 int32_t field_index, type, array_index, givenType;
599 ARRAY_DEFINITION *arraydef;
600 char *array_name;
601 va_list argptr;
602 int32_t retval;
603 double buffer[4];
604
605 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ChangeArrayInformation"))
606 return (0);
607
608 if (!field_name) {
609 SDDS_SetError("NULL field name passed. (SDDS_ChangeArrayInformation)");
610 return (0);
611 }
612
613 va_start(argptr, mode);
614 retval = 1;
615 if (mode & SDDS_SET_BY_INDEX) {
616 if ((array_index = va_arg(argptr, int32_t)) < 0 || array_index >= SDDS_dataset->layout.n_arrays) {
617 SDDS_SetError("Invalid array index passed. (SDDS_ChangeArrayInformation)");
618 retval = 0;
619 }
620 } else {
621 if (!(array_name = va_arg(argptr, char *))) {
622 SDDS_SetError("NULL array name passed. (SDDS_ChangeArrayInformation)");
623 retval = 0;
624 }
625 if ((array_index = SDDS_GetArrayIndex(SDDS_dataset, array_name)) < 0) {
626 SDDS_SetError("Unknown array name given (SDDS_ChangeArrayInformation)");
627 retval = 0;
628 }
629 }
630 arraydef = SDDS_dataset->layout.array_definition + array_index;
631 va_end(argptr);
632 if (!retval)
633 return (0);
634
635 for (field_index = 0; field_index < SDDS_ARRAY_FIELDS; field_index++)
636 if (strcmp(field_name, SDDS_ArrayFieldInformation[field_index].name) == 0)
637 break;
638 if (field_index == SDDS_ARRAY_FIELDS) {
639 SDDS_SetError("Unknown field name given (SDDS_ChangeArrayInformation)");
640 return (0);
641 }
642 type = SDDS_ArrayFieldInformation[field_index].type;
643 if (!memory)
644 return (type);
645 if (type == SDDS_STRING) {
646 if (!SDDS_CopyString(((char **)((char *)arraydef + SDDS_ArrayFieldInformation[field_index].offset)), (char *)memory)) {
647 SDDS_SetError("Unable to copy field data (SDDS_ChangeArrayInformation)");
648 return (0);
649 }
650 if (strcmp(field_name, "name") == 0)
651 qsort((char *)SDDS_dataset->layout.array_index, SDDS_dataset->layout.n_arrays, sizeof(*SDDS_dataset->layout.array_index), SDDS_CompareIndexedNamesPtr);
652 } else {
653 if (mode & SDDS_PASS_BY_STRING) {
654 if (strcmp(field_name, "type") == 0 && (givenType = SDDS_IdentifyType((char *)memory)) > 0)
655 /* the type has been passed as a string (e.g., "double") */
656 memcpy((char *)buffer, (char *)&givenType, sizeof(givenType));
657 else if (!SDDS_ScanData((char *)memory, type, 0, (void *)buffer, 0, 0)) {
658 SDDS_SetError("Unable to scan string data (SDDS_ChangeArrayInformation)");
659 return (0);
660 }
661 memcpy((char *)arraydef + SDDS_ArrayFieldInformation[field_index].offset, (void *)buffer, SDDS_type_size[type - 1]);
662 } else
663 memcpy((char *)arraydef + SDDS_ArrayFieldInformation[field_index].offset, memory, SDDS_type_size[type - 1]);
664 }
665
666 return (type);
667}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_ScanData(char *string, int32_t type, int32_t field_length, void *data, int64_t index, int32_t is_parameter)
Scans a string and saves the parsed value into a data pointer according to the specified data type.
SDDS_FIELD_INFORMATION SDDS_AssociateFieldInformation[SDDS_ASSOCIATE_FIELDS]
Field information for associate definitions.
Definition SDDS_data.c:225
SDDS_FIELD_INFORMATION SDDS_ArrayFieldInformation[SDDS_ARRAY_FIELDS]
Field information for array definitions.
Definition SDDS_data.c:175
SDDS_FIELD_INFORMATION SDDS_ColumnFieldInformation[SDDS_COLUMN_FIELDS]
Field information for column definitions.
Definition SDDS_data.c:193
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
SDDS_FIELD_INFORMATION SDDS_ParameterFieldInformation[SDDS_PARAMETER_FIELDS]
Field information for parameter definitions.
Definition SDDS_data.c:209
int32_t SDDS_GetArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified array in the SDDS dataset.
Definition SDDS_info.c:192
int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a parameter definition within the SDDS dataset.
Definition SDDS_info.c:485
int32_t SDDS_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified parameter in the SDDS dataset.
Definition SDDS_info.c:117
int32_t SDDS_ChangeArrayInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in an array definition within the SDDS dataset.
Definition SDDS_info.c:597
int32_t SDDS_GetAssociateInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified associate in the SDDS dataset.
Definition SDDS_info.c:267
int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition within the SDDS dataset.
Definition SDDS_info.c:364
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
Internal definitions and function declarations for SDDS with LZMA support.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
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.
int SDDS_CompareIndexedNamesPtr(const void *s1, const void *s2)
Compares two pointers to SORTED_INDEX structures by their name fields.
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:552
int32_t SDDS_IdentifyType(char *typeName)
Identifies the SDDS data type based on its string name.
int32_t SDDS_GetAssociateIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named associate in the SDDS dataset.
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
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85