SDDSlib
Loading...
Searching...
No Matches
SDDS_ascii.c File Reference

SDDS ascii data input and output routines. More...

#include "SDDS.h"
#include "SDDS_internal.h"
#include "mdb.h"
#include <ctype.h>

Go to the source code of this file.

Macros

#define COMMENT_POSITION   40
 
#define INITIAL_BIG_BUFFER_SIZE   SDDS_MAXLINE
 

Functions

int32_t SDDS_WriteTypedValue (void *data, int64_t index, int32_t type, char *format, FILE *fp)
 Writes a typed value to an ASCII file stream.
 
int32_t SDDS_LZMAWriteTypedValue (void *data, int64_t index, int32_t type, char *format, struct lzmafile *lzmafp)
 Writes a typed value to an LZMA compressed ASCII file stream.
 
int32_t SDDS_WriteAsciiPage (SDDS_DATASET *SDDS_dataset)
 Writes a page of data in ASCII format to the SDDS dataset.
 
int32_t SDDS_WriteAsciiParameters (SDDS_DATASET *SDDS_dataset, FILE *fp)
 Writes the parameter data of an SDDS dataset in ASCII format to a file.
 
int32_t SDDS_LZMAWriteAsciiParameters (SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
 Writes the parameter data of an SDDS dataset in ASCII format to an LZMA compressed file.
 
int32_t SDDS_WriteAsciiArrays (SDDS_DATASET *SDDS_dataset, FILE *fp)
 Writes the arrays of an SDDS dataset in ASCII format to a file.
 
int32_t SDDS_LZMAWriteAsciiArrays (SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
 Writes the arrays of an SDDS dataset in ASCII format to an LZMA compressed file.
 
int32_t SDDS_WriteAsciiRow (SDDS_DATASET *SDDS_dataset, int64_t row, FILE *fp)
 Writes a single row of data in ASCII format to a file.
 
int32_t SDDS_LZMAWriteAsciiRow (SDDS_DATASET *SDDS_dataset, int64_t row, struct lzmafile *lzmafp)
 Writes a single row of data in ASCII format to an LZMA compressed file.
 
int32_t SDDS_ReadAsciiParameters (SDDS_DATASET *SDDS_dataset)
 Reads the parameters from an ASCII file into the SDDS dataset.
 
int32_t SDDS_ReadAsciiArrays (SDDS_DATASET *SDDS_dataset)
 Reads the arrays from an ASCII file into the SDDS dataset.
 
int32_t SDDS_ReadAsciiPage (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int32_t sparse_statistics)
 Reads the next SDDS ASCII page into memory with optional data sparsity and statistics.
 
int32_t SDDS_ReadAsciiPageLastRows (SDDS_DATASET *SDDS_dataset, int64_t last_rows)
 Reads the last specified number of rows from an ASCII page of an SDDS dataset.
 
int32_t SDDS_ReadAsciiPageDetailed (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows, int32_t sparse_statistics)
 Reads a detailed page of data from an ASCII file into an SDDS dataset with optional sparsity and statistics.
 
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.
 
int32_t SDDS_ScanData2 (char *string, char **pstring, int32_t *strlength, 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, optimized for long strings.
 
int32_t SDDS_AsciiDataExpected (SDDS_DATASET *SDDS_dataset)
 Checks whether the SDDS dataset expects ASCII data input.
 
int32_t SDDS_UpdateAsciiPage (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 Updates the current ASCII page of an SDDS dataset with new data.
 

Detailed Description

SDDS ascii data input and output routines.

This file contains the implementation of the SDDS ascii data input and output routines. It provides functions for writing void pointer data to an ASCII file stream. The functions support different data types such as short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, long double, string, and character.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file SDDS_ascii.c.

Macro Definition Documentation

◆ COMMENT_POSITION

#define COMMENT_POSITION   40

Definition at line 29 of file SDDS_ascii.c.

◆ INITIAL_BIG_BUFFER_SIZE

#define INITIAL_BIG_BUFFER_SIZE   SDDS_MAXLINE

Definition at line 39 of file SDDS_ascii.c.

Function Documentation

◆ SDDS_AsciiDataExpected()

int32_t SDDS_AsciiDataExpected ( SDDS_DATASET * SDDS_dataset)

Checks whether the SDDS dataset expects ASCII data input.

This function determines if the provided SDDS dataset is expecting ASCII data. The dataset expects ASCII data if it has columns, arrays, or parameters without fixed values. If the dataset only contains parameters with fixed values and no columns or arrays, it does not expect ASCII data.

Parameters
SDDS_datasetPointer to the SDDS dataset to check.
Returns
Returns 1 if ASCII data is expected, or 0 if ASCII data is not expected.

Definition at line 2140 of file SDDS_ascii.c.

2140 {
2141 int32_t i;
2142 if (SDDS_dataset->layout.n_columns || SDDS_dataset->layout.n_arrays)
2143 return (1);
2144 for (i = 0; i < SDDS_dataset->layout.n_parameters; i++)
2145 if (!SDDS_dataset->layout.parameter_definition[i].fixed_value)
2146 return (1);
2147 return (0);
2148}

◆ SDDS_LZMAWriteAsciiArrays()

int32_t SDDS_LZMAWriteAsciiArrays ( SDDS_DATASET * SDDS_dataset,
struct lzmafile * lzmafp )

Writes the arrays of an SDDS dataset in ASCII format to an LZMA compressed file.

This function writes all arrays contained in the provided SDDS dataset to the specified LZMA compressed file in ASCII format. For each array, it writes the dimensions, a description line, and the array elements formatted according to their data type.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the arrays to be written.
lzmafpPointer to the LZMA file stream where the array data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_LZMAWriteTypedValue() to write each array element according to its data type. Each array element is written, with up to 6 elements per line.

Definition at line 680 of file SDDS_ascii.c.

680 {
681 int32_t i, j;
682 SDDS_LAYOUT *layout;
683 /* char *predefined_format; */
684 ARRAY_DEFINITION *array_definition;
685 SDDS_ARRAY *array;
686
687 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_LZMAWriteAsciiArrays"))
688 return (0);
689 layout = &SDDS_dataset->layout;
690 for (j = 0; j < layout->n_arrays; j++) {
691 array_definition = layout->array_definition + j;
692 array = &SDDS_dataset->array[j];
693 for (i = 0; i < array_definition->dimensions; i++)
694 lzma_printf(lzmafp, "%" PRId32 " ", array->dimension[i]);
695 lzma_printf(lzmafp, " ! %" PRId32 "-dimensional array %s:\n", array_definition->dimensions, array_definition->name);
696 for (i = 0; i < array->elements;) {
697 if (!SDDS_LZMAWriteTypedValue(array->data, i, array_definition->type, NULL, lzmafp)) {
698 SDDS_SetError("Unable to write array--couldn't write ASCII data (SDDS_LZMAWriteAsciiArrays)");
699 return (0);
700 }
701 i++;
702 if (i % 6 == 0 || i == array->elements)
703 lzma_putc('\n', lzmafp);
704 else
705 lzma_putc(' ', lzmafp);
706 }
707 }
708 return (1);
709}
int32_t SDDS_LZMAWriteTypedValue(void *data, int64_t index, int32_t type, char *format, struct lzmafile *lzmafp)
Writes a typed value to an LZMA compressed ASCII file stream.
Definition SDDS_ascii.c:180
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:552

◆ SDDS_LZMAWriteAsciiParameters()

int32_t SDDS_LZMAWriteAsciiParameters ( SDDS_DATASET * SDDS_dataset,
struct lzmafile * lzmafp )

Writes the parameter data of an SDDS dataset in ASCII format to an LZMA compressed file.

This function writes all parameters of the provided SDDS dataset to the specified LZMA compressed file in ASCII format. Only parameters that do not have fixed values are written. Each parameter value is written on a new line.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the parameter data.
lzmafpPointer to the LZMA file stream where the ASCII data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_LZMAWriteTypedValue() to write each parameter value according to its data type.

Definition at line 565 of file SDDS_ascii.c.

565 {
566 int32_t i;
567 SDDS_LAYOUT *layout;
568 /* char *predefined_format; */
569
570 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_LZMAWriteAsciiParameters"))
571 return (0);
572 layout = &SDDS_dataset->layout;
573 for (i = 0; i < layout->n_parameters; i++) {
574 if (layout->parameter_definition[i].fixed_value)
575 continue;
576 if (!SDDS_LZMAWriteTypedValue(SDDS_dataset->parameter[i], 0, layout->parameter_definition[i].type, NULL, lzmafp)) {
577 SDDS_SetError("Unable to write ascii parameters (SDDS_LZMAWriteAsciiParameters)");
578 return 0;
579 }
580 lzma_putc('\n', lzmafp);
581 }
582 return (1);
583}

◆ SDDS_LZMAWriteAsciiRow()

int32_t SDDS_LZMAWriteAsciiRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
struct lzmafile * lzmafp )

Writes a single row of data in ASCII format to an LZMA compressed file.

This function writes the specified row from the SDDS dataset to the provided LZMA compressed file in ASCII format. The data is formatted according to the data types of the columns. Supports multi-line rows as specified by the data mode settings in the dataset layout.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the data.
rowZero-based index of the row to write.
lzmafpPointer to the LZMA file stream where the row data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_LZMAWriteTypedValue() to write each column value according to its data type. The number of values per line is determined by the lines_per_row setting in the dataset layout.

Definition at line 826 of file SDDS_ascii.c.

826 {
827 int32_t newline_needed;
828 int64_t i, n_per_line, line;
829 /* int32_t embedded_quotes_present; */
830 SDDS_LAYOUT *layout;
831 /* char *predefined_format, *s; */
832
833 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_LZMAWriteAsciiRow"))
834 return (0);
835 layout = &SDDS_dataset->layout;
836 if (SDDS_dataset->layout.data_mode.lines_per_row <= 0)
837 SDDS_dataset->layout.data_mode.lines_per_row = 1;
838 n_per_line = SDDS_dataset->layout.n_columns / SDDS_dataset->layout.data_mode.lines_per_row;
839 line = 1;
840 newline_needed = 0;
841 for (i = 0; i < layout->n_columns; i++) {
842 if (!SDDS_LZMAWriteTypedValue(SDDS_dataset->data[i], row, layout->column_definition[i].type, NULL, lzmafp)) {
843 SDDS_SetError("Unable to write ascii row (SDDS_LZMAWriteAsciiRow)");
844 return 0;
845 }
846 if ((i + 1) % n_per_line == 0 && line != SDDS_dataset->layout.data_mode.lines_per_row) {
847 newline_needed = 0;
848 lzma_putc('\n', lzmafp);
849 line++;
850 } else {
851 lzma_putc(' ', lzmafp);
852 newline_needed = 1;
853 }
854 }
855 if (newline_needed)
856 lzma_putc('\n', lzmafp);
857 return (1);
858}

◆ SDDS_LZMAWriteTypedValue()

int32_t SDDS_LZMAWriteTypedValue ( void * data,
int64_t index,
int32_t type,
char * format,
struct lzmafile * lzmafp )

Writes a typed value to an LZMA compressed ASCII file stream.

This function writes a single value from the provided data pointer to the given LZMA compressed file stream. The value is formatted as an ASCII string according to the specified data type and optional format string. Supports various data types including integers, floating-point numbers, strings, and characters.

Parameters
dataPointer to the data to be written. The data should be of the type specified by the type parameter. For array data types, data should point to the base of the array.
indexZero-based index of the element to write if data is an array; use 0 if data is a single value.
typeThe SDDS data type of the value to be written. Determines how the data is interpreted and formatted. Valid types include:
  • SDDS_SHORT
  • SDDS_USHORT
  • SDDS_LONG
  • SDDS_ULONG
  • SDDS_LONG64
  • SDDS_ULONG64
  • SDDS_FLOAT
  • SDDS_DOUBLE
  • SDDS_LONGDOUBLE
  • SDDS_STRING
  • SDDS_CHARACTER
formatOptional printf-style format string to specify the output format. If NULL, a default format is used based on the data type.
lzmafpPointer to the LZMA file stream where the data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
This function handles special character escaping for strings and characters to ensure correct parsing. For string and character types, special characters like '!', '\', and '"' are escaped appropriately.

Definition at line 180 of file SDDS_ascii.c.

180 {
181 char c, *s;
182 short hasWhitespace;
183
184 if (!data) {
185 SDDS_SetError("Unable to write value--data pointer is NULL (SDDS_LZMAWriteTypedValue)");
186 return (0);
187 }
188 if (!lzmafp) {
189 SDDS_SetError("Unable to print value--file pointer is NULL (SDDS_LZMAWriteTypedValue)");
190 return (0);
191 }
192 switch (type) {
193 case SDDS_SHORT:
194 lzma_printf(lzmafp, format ? format : "%hd", *((short *)data + index));
195 break;
196 case SDDS_USHORT:
197 lzma_printf(lzmafp, format ? format : "%hu", *((unsigned short *)data + index));
198 break;
199 case SDDS_LONG:
200 lzma_printf(lzmafp, format ? format : "%" PRId32, *((int32_t *)data + index));
201 break;
202 case SDDS_ULONG:
203 lzma_printf(lzmafp, format ? format : "%" PRIu32, *((uint32_t *)data + index));
204 break;
205 case SDDS_LONG64:
206 lzma_printf(lzmafp, format ? format : "%" PRId64, *((int64_t *)data + index));
207 break;
208 case SDDS_ULONG64:
209 lzma_printf(lzmafp, format ? format : "%" PRIu64, *((uint64_t *)data + index));
210 break;
211 case SDDS_FLOAT:
212 lzma_printf(lzmafp, format ? format : "%15.8e", *((float *)data + index));
213 break;
214 case SDDS_DOUBLE:
215 lzma_printf(lzmafp, format ? format : "%22.15e", *((double *)data + index));
216 break;
217 case SDDS_LONGDOUBLE:
218 if (LDBL_DIG == 18) {
219 lzma_printf(lzmafp, format ? format : "%22.18Le", *((long double *)data + index));
220 } else {
221 lzma_printf(lzmafp, format ? format : "%22.15Le", *((long double *)data + index));
222 }
223 break;
224 case SDDS_STRING:
225 /* ignores format string */
226 s = *((char **)data + index);
227 hasWhitespace = 0;
229 lzma_putc('"', lzmafp);
230 hasWhitespace = 1;
231 }
232 while (s && *s) {
233 c = *s++;
234 if (c == '!')
235 lzma_puts("\\!", lzmafp);
236 else if (c == '\\')
237 lzma_puts("\\\\", lzmafp);
238 else if (c == '"')
239 lzma_puts("\\\"", lzmafp);
240 else if (c == ' ')
241 lzma_putc(' ', lzmafp); /* don't escape plain spaces */
242 else if (isspace(c) || !isprint(c))
243 lzma_printf(lzmafp, "\\%03o", c);
244 else
245 lzma_putc(c, lzmafp);
246 }
247 if (hasWhitespace)
248 lzma_putc('"', lzmafp);
249 break;
250 case SDDS_CHARACTER:
251 /* ignores format string */
252 c = *((char *)data + index);
253 if (c == '!')
254 lzma_puts("\\!", lzmafp);
255 else if (c == '\\')
256 lzma_puts("\\\\", lzmafp);
257 else if (c == '"')
258 lzma_puts("\\\"", lzmafp);
259 else if (!c || isspace(c) || !isprint(c))
260 lzma_printf(lzmafp, "\\%03o", c);
261 else
262 lzma_putc(c, lzmafp);
263 break;
264 default:
265 SDDS_SetError("Unable to write value--unknown data type (SDDS_LZMAWriteTypedValue)");
266 return (0);
267 }
268 return (1);
269}
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
int32_t SDDS_HasWhitespace(char *string)
Checks if a string contains any whitespace characters.
#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_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

◆ SDDS_ReadAsciiArrays()

int32_t SDDS_ReadAsciiArrays ( SDDS_DATASET * SDDS_dataset)

Reads the arrays from an ASCII file into the SDDS dataset.

This function reads array data from an ASCII file and stores it in the provided SDDS dataset. It supports reading from regular files, as well as GZIP and LZMA compressed files if enabled.

Parameters
SDDS_datasetPointer to the SDDS dataset where the arrays will be stored.
Returns
Returns 1 on success, 0 on error, or -1 if end-of-file is reached before any arrays are read.
Note
The function checks the dataset for consistency before reading. It reads array dimensions and elements, handling multi-dimensional arrays appropriately. The array elements are scanned and stored according to their data types.

Definition at line 1047 of file SDDS_ascii.c.

1047 {
1048 int32_t i, j, length;
1049 SDDS_LAYOUT *layout;
1050 char *buffer = NULL;
1051 int32_t bufferSize = 0;
1052 char *bigBuffer = NULL;
1053 int32_t bigBufferSize = 0;
1054 char *bigBufferCopy;
1055 int32_t bigBufferCopySize;
1056 /* ARRAY_DEFINITION *array_definition; */
1057 SDDS_ARRAY *array;
1058#if defined(zLib)
1059 gzFile gzfp = NULL;
1060#endif
1061 FILE *fp = NULL;
1062 struct lzmafile *lzmafp = NULL;
1063
1064 layout = &SDDS_dataset->layout;
1065#if defined(zLib)
1066 if (SDDS_dataset->layout.gzipFile) {
1067 gzfp = layout->gzfp;
1068 } else {
1069#endif
1070 if (SDDS_dataset->layout.lzmaFile) {
1071 lzmafp = layout->lzmafp;
1072 } else {
1073 fp = layout->fp;
1074 }
1075#if defined(zLib)
1076 }
1077#endif
1078 if (layout->n_arrays > 0) {
1079 if (!(bigBuffer = SDDS_Malloc(sizeof(*bigBuffer) * (bigBufferSize = INITIAL_BIG_BUFFER_SIZE)))) {
1080 SDDS_SetError("Unable to read parameters--buffer allocation failure (SDDS_ReadAsciiArrays)");
1081 return (0);
1082 }
1083 }
1084 for (i = 0; i < layout->n_arrays; i++) {
1085#if defined(zLib)
1086 if (SDDS_dataset->layout.gzipFile) {
1087 if (!fgetsGZipSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, gzfp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1088 if (i == 0)
1089 return (-1);
1090 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1091 return (0);
1092 }
1093 } else {
1094#endif
1095 if (SDDS_dataset->layout.lzmaFile) {
1096 if (!fgetsLZMASkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, lzmafp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1097 if (i == 0)
1098 return (-1);
1099 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1100 return (0);
1101 }
1102 } else {
1103 if (!fgetsSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, fp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1104 if (i == 0)
1105 return (-1);
1106 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1107 return (0);
1108 }
1109 }
1110#if defined(zLib)
1111 }
1112#endif
1113 if (!(array = SDDS_dataset->array + i)) {
1114 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_ReadAsciiArrays)");
1115 return (0);
1116 }
1117 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
1118 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_ReadAsciiArrays)");
1119 return (0);
1120 }
1121 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
1122 SDDS_SetError("Unable to read array--definition copy failed (SDDS_ReadAsciiArrays)");
1123 return (0);
1124 }
1125 /*if (array->dimension) free(array->dimension); */
1126 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
1127 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadAsciiArrays)");
1128 return (0);
1129 }
1130 array->elements = 1;
1131 if ((length = strlen(bigBuffer)) >= bufferSize) {
1132 if (!(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * (bufferSize = 2 * length)))) {
1133 SDDS_SetError("Unable to scan data--allocation failure (SDDS_ReadAsciiArrays");
1134 return (0);
1135 }
1136 }
1137 for (j = 0; j < array->definition->dimensions; j++) {
1138 if (SDDS_GetToken(bigBuffer, buffer, SDDS_MAXLINE) <= 0 || sscanf(buffer, "%" SCNd32, array->dimension + j) != 1 || array->dimension[j] < 0) {
1139 SDDS_SetError("Unable to read array--dimensions missing or negative (SDDS_ReadAsciiArrays)");
1140 return (0);
1141 }
1142 array->elements *= array->dimension[j];
1143 }
1144 if (!array->elements)
1145 continue;
1146 if (array->data)
1147 free(array->data);
1148 array->data = array->pointer = NULL;
1149 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
1150 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadAsciiArrays)");
1151 return (0);
1152 }
1153 SDDS_ZeroMemory(array->data, array->elements * SDDS_type_size[array->definition->type - 1]);
1154 j = 0;
1155 bigBuffer[0] = 0;
1156 do {
1157 if (SDDS_StringIsBlank(bigBuffer)) {
1158 bigBuffer[0] = 0;
1159#if defined(zLib)
1160 if (SDDS_dataset->layout.gzipFile) {
1161 if (!fgetsGZipSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, gzfp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1162 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1163 return (0);
1164 }
1165 } else {
1166#endif
1167 if (SDDS_dataset->layout.lzmaFile) {
1168 if (!fgetsLZMASkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, lzmafp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1169 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1170 return (0);
1171 }
1172 } else {
1173 if (!fgetsSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, fp, '!') || SDDS_StringIsBlank(bigBuffer)) {
1174 SDDS_SetError("Unable to read array--dimensions missing (SDDS_ReadAsciiArrays)");
1175 return (0);
1176 }
1177 }
1178#if defined(zLib)
1179 }
1180#endif
1181 }
1182 /* copy the bigBuffer because SDDS_ScanData2 will change the bigBufferCopy pointer that SDDS_ScanData
1183 cannot do becuase bigBuffer is a static variable. This change was implemented to greatly improve
1184 the speed of reading a very large line of array elements. The previous version just did a lot of
1185 strcpy commands to these huge lines which was really slow. */
1186 bigBufferCopy = bigBuffer;
1187 bigBufferCopySize = strlen(bigBufferCopy);
1188 do {
1189 if (!SDDS_ScanData2(bigBufferCopy, &bigBufferCopy, &bigBufferCopySize, array->definition->type, array->definition->field_length, array->data, j, 0)) {
1190 SDDS_SetError("Unable to read array--error scanning data element (SDDS_ReadAsciiArrays)");
1191 return (0);
1192 }
1193 } while (++j < array->elements && !SDDS_StringIsBlank(bigBufferCopy));
1194 bigBuffer[0] = 0;
1195 } while (j < array->elements);
1196 }
1197 if (buffer)
1198 free(buffer);
1199 if (bigBuffer)
1200 free(bigBuffer);
1201 return (1);
1202}
int32_t SDDS_ScanData2(char *string, char **pstring, int32_t *strlength, 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, optimized for long strings.
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
char * fgetsLZMASkipCommentsResize(SDDS_DATASET *SDDS_dataset, char **s, int32_t *slen, struct lzmafile *lzmafp, char skip_char)
Reads a line from a LZMA-compressed file with dynamic buffer resizing while skipping comment lines.
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
int32_t SDDS_FreeArrayDefinition(ARRAY_DEFINITION *source)
Frees memory allocated for an array definition.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
int32_t SDDS_GetToken(char *s, char *buffer, int32_t buflen)
Extracts the next token from a string, handling quoted substrings and escape characters.
ARRAY_DEFINITION * SDDS_CopyArrayDefinition(ARRAY_DEFINITION **target, ARRAY_DEFINITION *source)
Creates a copy of an array definition.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
char * fgetsSkipCommentsResize(SDDS_DATASET *SDDS_dataset, char **s, int32_t *slen, FILE *fp, char skip_char)
Reads a line from a file with dynamic buffer resizing while skipping comment lines.

◆ SDDS_ReadAsciiPage()

int32_t SDDS_ReadAsciiPage ( SDDS_DATASET * SDDS_dataset,
int64_t sparse_interval,
int64_t sparse_offset,
int32_t sparse_statistics )

Reads the next SDDS ASCII page into memory with optional data sparsity and statistics.

This function reads the next page of data from an ASCII SDDS file into the provided dataset. It supports reading data with specified sparsity (interval and offset) and can compute statistics such as average, median, minimum, or maximum over the sparse data.

Parameters
SDDS_datasetPointer to the SDDS dataset where the data will be stored.
sparse_intervalInterval for sparsity; read every nth row if greater than 1.
sparse_offsetOffset for sparsity; number of initial rows to skip.
sparse_statisticsStatistic to compute over the sparse data:
  • 0: None
  • 1: Average
  • 2: Median
  • 3: Minimum
  • 4: Maximum
Returns
Returns the page number on success, -1 if end-of-file is reached, or 0 on error.
Note
The function utilizes SDDS_ReadAsciiPageDetailed() to perform the actual reading.

Definition at line 1225 of file SDDS_ascii.c.

1225 {
1226 return SDDS_ReadAsciiPageDetailed(SDDS_dataset, sparse_interval, sparse_offset, 0, sparse_statistics);
1227}
int32_t SDDS_ReadAsciiPageDetailed(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows, int32_t sparse_statistics)
Reads a detailed page of data from an ASCII file into an SDDS dataset with optional sparsity and stat...

◆ SDDS_ReadAsciiPageDetailed()

int32_t SDDS_ReadAsciiPageDetailed ( SDDS_DATASET * SDDS_dataset,
int64_t sparse_interval,
int64_t sparse_offset,
int64_t last_rows,
int32_t sparse_statistics )

Reads a detailed page of data from an ASCII file into an SDDS dataset with optional sparsity and statistics.

This function reads a page of data from an ASCII SDDS file into the provided dataset, supporting various options for data sparsity and statistical processing. It allows specifying a sparse interval and offset to read every nth row starting from a specific offset, as well as reading only the last specified number of rows. Additionally, it can compute statistical measures over the sparse data, such as average, median, minimum, or maximum.

Parameters
SDDS_datasetPointer to the SDDS dataset where the data will be stored.
sparse_intervalInterval for sparsity; reads every nth row if greater than 1. Use 1 to read every row.
sparse_offsetOffset from the first row to start reading. Rows before this offset are skipped.
last_rowsNumber of last rows to read. If greater than 0, only the last last_rows rows are read, overriding sparse_interval and sparse_offset. Use 0 to read all rows according to sparse_interval and sparse_offset.
sparse_statisticsStatistical operation to perform over the sparse data:
  • 0: None (no statistical operation)
  • 1: Average
  • 2: Median
  • 3: Minimum
  • 4: Maximum
Returns
Returns the page number on success, -1 if end-of-file is reached before any data is read, 0 on error.
Note
This function handles reading from regular files, as well as GZIP and LZMA compressed files if enabled. It updates the internal state of the dataset, including the page number and number of rows read. If last_rows is specified and greater than 0, it overrides sparse_interval and sparse_offset. In case of errors during reading, the function attempts to recover if autoRecover is enabled in the dataset.

Definition at line 1273 of file SDDS_ascii.c.

1273 {
1274 SDDS_LAYOUT *layout;
1275 int32_t no_row_counts, end_of_data, retval, lineCount;
1276 int64_t n_rows, i, j, k, rows_to_store;
1277 /* int32_t page_number; */
1278 char s[SDDS_MAXLINE];
1279 char *dataRead, *bigBufferCopy;
1280 int32_t bigBufferCopySize;
1281 char *bigBuffer = NULL;
1282 int32_t bigBufferSize = 0;
1283 /* char *ptr; */
1284#if defined(zLib)
1285 gzFile gzfp = NULL;
1286#endif
1287 FILE *fp = NULL;
1288 void **statData=NULL;
1289 double statResult;
1290 struct lzmafile *lzmafp = NULL;
1291 /* double value; */
1292
1293 if (SDDS_dataset->autoRecovered)
1294 return -1;
1295
1296 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
1297
1298#if defined(zLib)
1299 if (SDDS_dataset->layout.gzipFile) {
1300 gzfp = SDDS_dataset->layout.gzfp;
1301 } else {
1302#endif
1303 if (SDDS_dataset->layout.lzmaFile) {
1304 lzmafp = SDDS_dataset->layout.lzmafp;
1305 } else {
1306 fp = SDDS_dataset->layout.fp;
1307 }
1308#if defined(zLib)
1309 }
1310#endif
1311 if (SDDS_dataset->page_number == -1)
1312 /* end of file already hit */
1313 return -1;
1314#if defined(zLib)
1315 if (SDDS_dataset->layout.gzipFile) {
1316 if (gzeof(gzfp) && SDDS_dataset->page_number > 0)
1317 /* end of file and not first page about to be read */
1318 return SDDS_dataset->page_number = -1;
1319 } else {
1320#endif
1321 if (SDDS_dataset->layout.lzmaFile) {
1322 if (lzma_eof(lzmafp) && SDDS_dataset->page_number > 0)
1323 /* end of file and not first page about to be read */
1324 return SDDS_dataset->page_number = -1;
1325 } else {
1326 if (feof(fp) && SDDS_dataset->page_number > 0)
1327 /* end of file and not first page about to be read */
1328 return SDDS_dataset->page_number = -1;
1329 }
1330#if defined(zLib)
1331 }
1332#endif
1333 if (!SDDS_AsciiDataExpected(SDDS_dataset) && SDDS_dataset->page_number != 0)
1334 /* if no columns or arrays and only fixed value parameters, then only one "page" allowed */
1335 return (SDDS_dataset->page_number = -1);
1336
1337#if defined(zLib)
1338 if (SDDS_dataset->layout.gzipFile) {
1339 if (SDDS_dataset->page_number == 0)
1340 for (i = 0; i < SDDS_dataset->layout.data_mode.additional_header_lines; i++) {
1341 if (!fgetsGZipSkipComments(SDDS_dataset, s, SDDS_MAXLINE, gzfp, '!'))
1342 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1343 }
1344 } else {
1345#endif
1346 if (SDDS_dataset->layout.lzmaFile) {
1347 if (SDDS_dataset->page_number == 0)
1348 for (i = 0; i < SDDS_dataset->layout.data_mode.additional_header_lines; i++) {
1349 if (!fgetsLZMASkipComments(SDDS_dataset, s, SDDS_MAXLINE, lzmafp, '!'))
1350 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1351 }
1352 } else {
1353 if (SDDS_dataset->page_number == 0)
1354 for (i = 0; i < SDDS_dataset->layout.data_mode.additional_header_lines; i++) {
1355 if (!fgetsSkipComments(SDDS_dataset, s, SDDS_MAXLINE, fp, '!'))
1356 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1357 }
1358 }
1359#if defined(zLib)
1360 }
1361#endif
1362
1363 /* the next call increments the page number */
1364 if (!SDDS_StartPage(SDDS_dataset, 0)) {
1365 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadAsciiPage)");
1366 return (0);
1367 }
1368
1369 layout = &SDDS_dataset->layout;
1370
1371 if ((retval = SDDS_ReadAsciiParameters(SDDS_dataset)) < 1) {
1372 if (retval)
1373 return (SDDS_dataset->page_number = retval);
1374 SDDS_SetError("Unable to read page--couldn't read parameters (SDDS_ReadAsciiPage)");
1375 return (0);
1376 }
1377 if ((retval = SDDS_ReadAsciiArrays(SDDS_dataset)) < 1) {
1378 if (retval)
1379 return (SDDS_dataset->page_number = retval);
1380 SDDS_SetError("Unable to read page--couldn't read arrays (SDDS_ReadAsciiPage)");
1381 return (0);
1382 }
1383
1384 if (last_rows < 0)
1385 last_rows = 0;
1386 if (sparse_interval <= 0)
1387 sparse_interval = 1;
1388 if (sparse_offset < 0)
1389 sparse_offset = 0;
1390
1391 SDDS_dataset->rowcount_offset = -1;
1392 if (layout->n_columns) {
1393 if (!(bigBuffer = SDDS_Malloc(sizeof(*bigBuffer) * (bigBufferSize = INITIAL_BIG_BUFFER_SIZE)))) {
1394 SDDS_SetError("Unable to read parameters--buffer allocation failure (SDDS_ReadAsciiPage)");
1395 return (0);
1396 }
1397
1398 n_rows = 0;
1399 no_row_counts = 0;
1400 if (!SDDS_dataset->layout.data_mode.no_row_counts) {
1401 /* read the number of rows */
1402#if defined(zLib)
1403 if (SDDS_dataset->layout.gzipFile) {
1404 if (!fgetsGZipSkipComments(SDDS_dataset, s, SDDS_MAXLINE, gzfp, '!')) {
1405 if (bigBuffer)
1406 free(bigBuffer);
1407 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1408 }
1409 } else {
1410#endif
1411 if (SDDS_dataset->layout.lzmaFile) {
1412 if (!fgetsLZMASkipComments(SDDS_dataset, s, SDDS_MAXLINE, lzmafp, '!')) {
1413 if (bigBuffer)
1414 free(bigBuffer);
1415 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1416 }
1417 } else {
1418 do {
1419 SDDS_dataset->rowcount_offset = ftell(fp);
1420 if (!fgets(s, SDDS_MAXLINE, fp)) {
1421 if (bigBuffer)
1422 free(bigBuffer);
1423 return (SDDS_dataset->page_number = -1); /* indicates end of data */
1424 }
1425 } while (s[0] == '!');
1426 }
1427#if defined(zLib)
1428 }
1429#endif
1430 if (sscanf(s, "%" SCNd64, &n_rows) != 1 || n_rows < 0) {
1431 SDDS_SetError("Unable to read page--file has no (valid) number-of-rows entry (SDDS_ReadAsciiPage)");
1432 return (0);
1433 }
1434 if (n_rows > SDDS_GetRowLimit()) {
1435 /* number of rows is "unreasonably" large---treat like end-of-file */
1436 if (bigBuffer)
1437 free(bigBuffer);
1438 return (SDDS_dataset->page_number = -1);
1439 }
1440 if (last_rows) {
1441 sparse_interval = 1;
1442 sparse_offset = n_rows - last_rows;
1443 if (sparse_offset < 0)
1444 sparse_offset = 0;
1445 }
1446 rows_to_store = (n_rows - sparse_offset) / sparse_interval + 2;
1447 } else {
1448 // fix last_rows when no row count is available
1449 no_row_counts = 1;
1450 n_rows = TABLE_LENGTH_INCREMENT;
1451 rows_to_store = n_rows;
1452 }
1453
1454 if (rows_to_store >= SDDS_dataset->n_rows_allocated) {
1455 /* lengthen the page */
1456 if (!SDDS_LengthenTable(SDDS_dataset, rows_to_store - SDDS_dataset->n_rows_allocated)) {
1457 SDDS_SetError("Unable to read page--couldn't lengthen data page (SDDS_ReadAsciiPage)");
1458 return (0);
1459 }
1460 }
1461
1462 /* read the page values */
1463 j = end_of_data = k = 0;
1464 s[0] = 0;
1465 if (!no_row_counts && n_rows == 0) {
1466 SDDS_dataset->n_rows = 0;
1467 if (bigBuffer)
1468 free(bigBuffer);
1469 return (SDDS_dataset->page_number);
1470 }
1471 bigBuffer[0] = 0;
1472 bigBufferCopy = bigBuffer;
1473 do {
1474 if (j >= SDDS_dataset->n_rows_allocated) {
1475 /* lengthen the page */
1476 if (!SDDS_LengthenTable(SDDS_dataset, TABLE_LENGTH_INCREMENT)) {
1477 SDDS_SetError("Unable to read page--couldn't lengthen data page (SDDS_ReadAsciiPage)");
1478 return (0);
1479 }
1480 }
1481 lineCount = 0;
1482 dataRead = NULL;
1483 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
1484 if (k == 0) {
1485 if (sparse_statistics != 0) {
1486 // Allocate buffer space for statistical sparsing
1487 if (i == 0) {
1488 statData = (void**)malloc(SDDS_dataset->layout.n_columns * sizeof(void*));
1489 }
1490 if (SDDS_FLOATING_TYPE(layout->column_definition[i].type)) {
1491 // Not ideal for SDDS_LONGDOUBLE but we may never run across this error
1492 statData[i] = (double*)calloc(sparse_interval, sizeof(double));
1493 }
1494 }
1495 }
1496
1497 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1498 continue;
1499 if (SDDS_StringIsBlank(bigBufferCopy)) {
1500 bigBuffer[0] = 0;
1501 bigBufferCopy = bigBuffer;
1502 dataRead = NULL;
1503#if defined(zLib)
1504 if (SDDS_dataset->layout.gzipFile) {
1505 if (!(dataRead = fgetsGZipSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, gzfp, '!')) || SDDS_StringIsBlank(bigBuffer)) {
1506 SDDS_dataset->n_rows = j;
1507 if (no_row_counts) {
1508 /* legitmate end of data set */
1509 end_of_data = 1;
1510 break;
1511 }
1512 /* error, but may be recoverable */
1513 gzseek(gzfp, 0L, SEEK_END);
1514 if (SDDS_dataset->autoRecover) {
1515 SDDS_dataset->autoRecovered = 1;
1517 if (bigBuffer)
1518 free(bigBuffer);
1519 return (SDDS_dataset->page_number);
1520 }
1521 SDDS_SetError("Unable to read page (SDDS_ReadAsciiPage)");
1522 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
1523 return (0);
1524 }
1525 } else {
1526#endif
1527 if (SDDS_dataset->layout.lzmaFile) {
1528 if (!(dataRead = fgetsLZMASkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, lzmafp, '!')) || SDDS_StringIsBlank(bigBuffer)) {
1529 SDDS_dataset->n_rows = j;
1530 if (no_row_counts) {
1531 /* legitmate end of data set */
1532 end_of_data = 1;
1533 break;
1534 }
1535 /* error, but may be recoverable */
1536 lzma_seek(lzmafp, 0L, SEEK_END);
1537 if (SDDS_dataset->autoRecover) {
1538 SDDS_dataset->autoRecovered = 1;
1540 if (bigBuffer)
1541 free(bigBuffer);
1542 return (SDDS_dataset->page_number);
1543 }
1544 SDDS_SetError("Unable to read page (SDDS_ReadAsciiPage)");
1545 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
1546 return (0);
1547 }
1548 } else {
1549 if (!(dataRead = fgetsSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, fp, '!')) || SDDS_StringIsBlank(bigBuffer)) {
1550 SDDS_dataset->n_rows = j;
1551 if (no_row_counts) {
1552 /* legitmate end of data set */
1553 end_of_data = 1;
1554 break;
1555 }
1556 /* error, but may be recoverable */
1557 fseek(fp, 0L, SEEK_END);
1558 if (SDDS_dataset->autoRecover) {
1559 SDDS_dataset->autoRecovered = 1;
1561 if (bigBuffer)
1562 free(bigBuffer);
1563 return (SDDS_dataset->page_number);
1564 }
1565 SDDS_SetError("Unable to read page (SDDS_ReadAsciiPage)");
1566 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
1567 return (0);
1568 }
1569 }
1570#if defined(zLib)
1571 }
1572#endif
1573 lineCount++;
1574 bigBufferCopy = bigBuffer;
1575 bigBufferCopySize = strlen(bigBufferCopy);
1576 }
1577 if (!SDDS_ScanData2(bigBufferCopy, &bigBufferCopy, &bigBufferCopySize, layout->column_definition[i].type, layout->column_definition[i].field_length, SDDS_dataset->data[i], j, 0)) {
1578 /* error, but may be recoverable */
1579 SDDS_dataset->n_rows = j;
1580#if defined(zLib)
1581 if (SDDS_dataset->layout.gzipFile) {
1582 gzseek(gzfp, 0L, SEEK_END);
1583 } else {
1584#endif
1585 if (SDDS_dataset->layout.lzmaFile) {
1586 lzma_seek(lzmafp, 0L, SEEK_END);
1587 } else {
1588 fseek(fp, 0L, SEEK_END);
1589 }
1590#if defined(zLib)
1591 }
1592#endif
1593 if (SDDS_dataset->autoRecover) {
1594 SDDS_dataset->autoRecovered = 1;
1596 if (bigBuffer)
1597 free(bigBuffer);
1598 return (SDDS_dataset->page_number);
1599 }
1600 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
1601 SDDS_SetError("Unable to read page--scanning error (SDDS_ReadAsciiPage)");
1602 return (0);
1603 }
1604 if (sparse_statistics != 0) {
1605 switch (layout->column_definition[i].type) {
1606 case SDDS_FLOAT:
1607 ((double*)statData[i])[k % sparse_interval] = (double)(((float*)SDDS_dataset->data[i])[j]);
1608 break;
1609 case SDDS_DOUBLE:
1610 ((double*)statData[i])[k % sparse_interval] = ((double*)SDDS_dataset->data[i])[j];
1611 break;
1612 case SDDS_LONGDOUBLE:
1613 ((double*)statData[i])[k % sparse_interval] = (double)(((long double*)SDDS_dataset->data[i])[j]);
1614 break;
1615 }
1616 if (SDDS_FLOATING_TYPE(layout->column_definition[i].type)) {
1617 if (sparse_statistics == 1) {
1618 // Sparse and get average statistics
1619 compute_average(&statResult, (double*)statData[i], (k % sparse_interval) + 1);
1620 } else if (sparse_statistics == 2) {
1621 // Sparse and get median statistics
1622 compute_median(&statResult, (double*)statData[i], (k % sparse_interval) + 1);
1623 } else if (sparse_statistics == 3) {
1624 // Sparse and get minimum statistics
1625 statResult = min_in_array((double*)statData[i], (k % sparse_interval) + 1);
1626 } else if (sparse_statistics == 4) {
1627 // Sparse and get maximum statistics
1628 statResult = max_in_array((double*)statData[i], (k % sparse_interval) + 1);
1629 }
1630 }
1631 switch (layout->column_definition[i].type) {
1632 case SDDS_FLOAT:
1633 ((float*)SDDS_dataset->data[i])[j] = statResult;
1634 break;
1635 case SDDS_DOUBLE:
1636 ((double*)SDDS_dataset->data[i])[j] = statResult;
1637 break;
1638 case SDDS_LONGDOUBLE:
1639 ((long double*)SDDS_dataset->data[i])[j] = statResult;
1640 break;
1641 }
1642 }
1643
1644#if defined(DEBUG)
1645 fprintf(stderr, "line remaining = %s\n", bigBuffer);
1646#endif
1647 }
1648 if (end_of_data)
1649 /* ran out of data for no_row_counts=1 */
1650 break;
1651 if (layout->data_mode.lines_per_row != 0 && lineCount != layout->data_mode.lines_per_row) {
1652 sprintf(s, "Unable to read page--line layout error at line %" PRId64 " of page %" PRId32 " (SDDS_ReadAsciiPage)", j + 1, SDDS_dataset->page_number);
1653 SDDS_SetError(s);
1654 /* data ends prematurely, which is an error that may be recoverable */
1655#if defined(zLib)
1656 if (SDDS_dataset->layout.gzipFile) {
1657 gzseek(gzfp, 0L, SEEK_END);
1658 } else {
1659#endif
1660 if (SDDS_dataset->layout.lzmaFile) {
1661 lzma_seek(lzmafp, 0L, SEEK_END);
1662 } else {
1663 fseek(fp, 0L, SEEK_END);
1664 }
1665#if defined(zLib)
1666 }
1667#endif
1668 if (SDDS_dataset->autoRecover) {
1669 SDDS_dataset->autoRecovered = 1;
1671 if (bigBuffer)
1672 free(bigBuffer);
1673 return (SDDS_dataset->page_number);
1674 }
1675 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
1676 SDDS_dataset->n_rows = j;
1677 return (0);
1678 }
1679 if (layout->data_mode.lines_per_row != 0) {
1680 bigBuffer[0] = 0;
1681 bigBufferCopy = bigBuffer;
1682 }
1683 if (--sparse_offset < 0 &&
1684 (((sparse_statistics == 0) && (k % sparse_interval == 0)) || ((sparse_statistics != 0) && (k % sparse_interval == sparse_interval - 1))))
1685 j++;
1686 k++;
1687 } while (k < n_rows || no_row_counts);
1688
1689 if (sparse_statistics != 0) {
1690 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
1691 if (SDDS_FLOATING_TYPE(layout->column_definition[i].type)) {
1692 free(statData[i]);
1693 }
1694 }
1695 free(statData);
1696 }
1697
1698 if (end_of_data && !(SDDS_dataset->page_number == 1) && j == 0 && !dataRead) {
1699 /* For end of data in no_row_counts=1 mode for any page other than the first,
1700 * an end-of-file is not a valid way to end an empty page (only an incomplete line is)
1701 */
1702 if (bigBuffer)
1703 free(bigBuffer);
1704 return SDDS_dataset->page_number = -1;
1705 }
1706 SDDS_dataset->n_rows = j;
1707 }
1708 if (bigBuffer)
1709 free(bigBuffer);
1710
1711 return (SDDS_dataset->page_number);
1712}
int32_t SDDS_AsciiDataExpected(SDDS_DATASET *SDDS_dataset)
Checks whether the SDDS dataset expects ASCII data input.
int32_t SDDS_ReadAsciiArrays(SDDS_DATASET *SDDS_dataset)
Reads the arrays from an ASCII file into the SDDS dataset.
int32_t SDDS_ReadAsciiParameters(SDDS_DATASET *SDDS_dataset)
Reads the parameters from an ASCII file into the SDDS dataset.
Definition SDDS_ascii.c:927
void SDDS_SetReadRecoveryMode(SDDS_DATASET *SDDS_dataset, int32_t mode)
Sets the read recovery mode for an SDDS dataset.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int64_t SDDS_GetRowLimit()
char * fgetsLZMASkipComments(SDDS_DATASET *SDDS_dataset, char *s, int32_t slen, struct lzmafile *lzmafp, char skip_char)
Reads a line from a LZMA-compressed file while skipping comment lines.
char * fgetsSkipComments(SDDS_DATASET *SDDS_dataset, char *s, int32_t slen, FILE *fp, char skip_char)
Reads a line from a file while skipping comment lines.
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
Definition SDDS_utils.c:318
#define SDDS_FLOATING_TYPE(type)
Checks if the given type identifier corresponds to a floating-point type.
Definition SDDStypes.h:124

◆ SDDS_ReadAsciiPageLastRows()

int32_t SDDS_ReadAsciiPageLastRows ( SDDS_DATASET * SDDS_dataset,
int64_t last_rows )

Reads the last specified number of rows from an ASCII page of an SDDS dataset.

This function reads only the last specified number of rows from the next ASCII page in the SDDS dataset.

Parameters
SDDS_datasetPointer to the SDDS dataset where the data will be stored.
last_rowsNumber of rows to read from the end of the page.
Returns
Returns the page number on success, -1 if end-of-file is reached, or 0 on error.
Note
The function utilizes SDDS_ReadAsciiPageDetailed() to perform the actual reading.

Definition at line 1241 of file SDDS_ascii.c.

1241 {
1242 return SDDS_ReadAsciiPageDetailed(SDDS_dataset, 1, 0, last_rows, 0);
1243}

◆ SDDS_ReadAsciiParameters()

int32_t SDDS_ReadAsciiParameters ( SDDS_DATASET * SDDS_dataset)

Reads the parameters from an ASCII file into the SDDS dataset.

This function reads parameter data from an ASCII file and stores it in the provided SDDS dataset. It supports reading from regular files, as well as GZIP and LZMA compressed files if enabled.

Parameters
SDDS_datasetPointer to the SDDS dataset where the parameters will be stored.
Returns
Returns 1 on success, 0 on error, or -1 if end-of-file is reached before any parameters are read.
Note
The function checks the dataset for consistency before reading. It handles fixed-value parameters appropriately. The function reads each parameter line by line, skipping comments, and stores the values after scanning them according to their data type.

Definition at line 927 of file SDDS_ascii.c.

927 {
928 int32_t i, first_read;
929 SDDS_LAYOUT *layout;
930#if defined(zLib)
931 gzFile gzfp;
932#endif
933 FILE *fp;
934 struct lzmafile *lzmafp;
935 char *bigBuffer = NULL;
936 int32_t bigBufferSize = 0;
937
938 layout = &SDDS_dataset->layout;
939 first_read = 1;
940 if (layout->n_parameters > 0) {
941 if (!(bigBuffer = SDDS_Malloc(sizeof(*bigBuffer) * (bigBufferSize = INITIAL_BIG_BUFFER_SIZE)))) {
942 SDDS_SetError("Unable to read parameters--buffer allocation failure (SDDS_ReadAsciiParameters)");
943 return (0);
944 }
945 }
946#if defined(zLib)
947 if (SDDS_dataset->layout.gzipFile) {
948 gzfp = layout->gzfp;
949 for (i = 0; i < layout->n_parameters; i++) {
950 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
951 continue;
952 bigBuffer[0] = 0;
953 if (!layout->parameter_definition[i].fixed_value) {
954 if (!fgetsGZipSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, gzfp, '!')) {
955 if (first_read) {
956 if (bigBuffer)
957 free(bigBuffer);
958 return (-1);
959 }
960 SDDS_SetError("Unable to read parameters--data ends prematurely (SDDS_ReadAsciiParameters)");
961 return (0);
962 }
963 first_read = 0;
964 bigBuffer[strlen(bigBuffer) - 1] = 0;
965 } else
966 strcpy(bigBuffer, layout->parameter_definition[i].fixed_value);
967 if (!SDDS_ScanData(bigBuffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
968 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadAsciiParameters)");
969 return (0);
970 }
971 }
972 } else {
973#endif
974 if (SDDS_dataset->layout.lzmaFile) {
975 lzmafp = layout->lzmafp;
976 for (i = 0; i < layout->n_parameters; i++) {
977 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
978 continue;
979 bigBuffer[0] = 0;
980 if (!layout->parameter_definition[i].fixed_value) {
981 if (!fgetsLZMASkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, lzmafp, '!')) {
982 if (first_read) {
983 if (bigBuffer)
984 free(bigBuffer);
985 return (-1);
986 }
987 SDDS_SetError("Unable to read parameters--data ends prematurely (SDDS_ReadAsciiParameters)");
988 return (0);
989 }
990 first_read = 0;
991 bigBuffer[strlen(bigBuffer) - 1] = 0;
992 } else
993 strcpy(bigBuffer, layout->parameter_definition[i].fixed_value);
994 if (!SDDS_ScanData(bigBuffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
995 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadAsciiParameters)");
996 return (0);
997 }
998 }
999 } else {
1000 fp = layout->fp;
1001 for (i = 0; i < layout->n_parameters; i++) {
1002 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1003 continue;
1004 bigBuffer[0] = 0;
1005 if (!layout->parameter_definition[i].fixed_value) {
1006 if (!fgetsSkipCommentsResize(SDDS_dataset, &bigBuffer, &bigBufferSize, fp, '!')) {
1007 if (first_read) {
1008 if (bigBuffer)
1009 free(bigBuffer);
1010 return (-1);
1011 }
1012 SDDS_SetError("Unable to read parameters--data ends prematurely (SDDS_ReadAsciiParameters)");
1013 return (0);
1014 }
1015 first_read = 0;
1016 bigBuffer[strlen(bigBuffer) - 1] = 0;
1017 } else
1018 strcpy(bigBuffer, layout->parameter_definition[i].fixed_value);
1019 if (!SDDS_ScanData(bigBuffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
1020 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadAsciiParameters)");
1021 return (0);
1022 }
1023 }
1024 }
1025#if defined(zLib)
1026 }
1027#endif
1028 if (bigBuffer)
1029 free(bigBuffer);
1030 return (1);
1031}
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_ScanData()

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.

This function extracts data from a string and stores it in the provided data pointer. It handles various SDDS data types, including integers, floating-point numbers, strings, and characters. The function supports both fixed-field and variable-field formats and can process parameters and column data.

Parameters
stringPointer to the input string containing the data to be scanned.
typeThe SDDS data type to interpret the scanned data as. Valid types include:
  • SDDS_SHORT
  • SDDS_USHORT
  • SDDS_LONG
  • SDDS_ULONG
  • SDDS_LONG64
  • SDDS_ULONG64
  • SDDS_FLOAT
  • SDDS_DOUBLE
  • SDDS_LONGDOUBLE
  • SDDS_STRING
  • SDDS_CHARACTER
field_lengthField length for fixed-field formats. Set to 0 for variable-field formats. If negative, indicates left-padding should be removed.
dataVoid pointer to the data storage where the scanned value will be saved. Must be pre-allocated and appropriate for the specified data type.
indexThe index within the data array where the value should be stored.
is_parameterSet to 1 if the data is from an SDDS parameter; set to 0 for column data.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function allocates a buffer internally to process the input string. It handles escape sequences for strings and characters using SDDS_InterpretEscapes(). For string data types, the function manages memory allocation for the data array elements.

Definition at line 1748 of file SDDS_ascii.c.

1748 {
1749 char *buffer = NULL;
1750 int32_t abs_field_length, length;
1751 int32_t bufferSize = 0;
1752
1753 abs_field_length = abs(field_length);
1754 if (!string) {
1755 SDDS_SetError("Unable to scan data--input string is NULL (SDDS_ScanData)");
1756 return (0);
1757 }
1758 if (!data) {
1759 SDDS_SetError("Unable to scan data--data pointer is NULL (SDDS_ScanData)");
1760 return (0);
1761 }
1762 if (!(buffer = SDDS_Malloc(sizeof(*buffer) * (bufferSize = SDDS_MAXLINE)))) {
1763 SDDS_SetError("Unable to scan data--allocation failure (SDDS_ScanData)");
1764 return (0);
1765 }
1766 if ((length = strlen(string)) < abs_field_length)
1767 length = abs_field_length;
1768 if (bufferSize <= length) {
1769 if (!(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * (bufferSize = 2 * length)))) {
1770 /* I allocate 2*length in the hopes that I won't need to realloc too often if I do this */
1771 SDDS_SetError("Unable to scan data--allocation failure (SDDS_ScanData)");
1772 return (0);
1773 }
1774 }
1775 if (type != SDDS_STRING) {
1776 /* for non-string data, fill buffer with string to be scanned */
1777 if (field_length) {
1778 /* fill with fixed number of characters */
1779 if (abs_field_length > (int32_t)strlen(string)) {
1780 strcpy(buffer, string);
1781 *string = 0;
1782 } else {
1783 strncpy(buffer, string, abs_field_length);
1784 buffer[field_length] = 0;
1785 strcpy(string, string + abs_field_length);
1786 }
1787 } else if (SDDS_GetToken(string, buffer, bufferSize) < 0) {
1788 SDDS_SetError("Unable to scan data--tokenizing error (SDDS_ScanData)");
1789 return (0);
1790 }
1791 }
1792 switch (type) {
1793 case SDDS_SHORT:
1794 if (sscanf(buffer, "%hd", ((short *)data) + index) == 1) {
1795 if (buffer)
1796 free(buffer);
1797 return (1);
1798 }
1799 break;
1800 case SDDS_USHORT:
1801 if (sscanf(buffer, "%hu", ((unsigned short *)data) + index) == 1) {
1802 if (buffer)
1803 free(buffer);
1804 return (1);
1805 }
1806 break;
1807 case SDDS_LONG:
1808 if (sscanf(buffer, "%" SCNd32, ((int32_t *)data) + index) == 1) {
1809 if (buffer)
1810 free(buffer);
1811 return (1);
1812 }
1813 break;
1814 case SDDS_ULONG:
1815 if (sscanf(buffer, "%" SCNu32, ((uint32_t *)data) + index) == 1) {
1816 if (buffer)
1817 free(buffer);
1818 return (1);
1819 }
1820 break;
1821 case SDDS_LONG64:
1822 if (sscanf(buffer, "%" SCNd64, ((int64_t *)data) + index) == 1) {
1823 if (buffer)
1824 free(buffer);
1825 return (1);
1826 }
1827 break;
1828 case SDDS_ULONG64:
1829 if (sscanf(buffer, "%" SCNu64, ((uint64_t *)data) + index) == 1) {
1830 if (buffer)
1831 free(buffer);
1832 return (1);
1833 }
1834 break;
1835 case SDDS_FLOAT:
1836 if (sscanf(buffer, "%f", ((float *)data) + index) == 1) {
1837 if (buffer)
1838 free(buffer);
1839 return (1);
1840 }
1841 break;
1842 case SDDS_DOUBLE:
1843 if (sscanf(buffer, "%lf", ((double *)data) + index) == 1) {
1844 if (buffer)
1845 free(buffer);
1846 return (1);
1847 }
1848 break;
1849 case SDDS_LONGDOUBLE:
1850 if (sscanf(buffer, "%Lf", ((long double *)data) + index) == 1) {
1851 if (buffer)
1852 free(buffer);
1853 return (1);
1854 }
1855 break;
1856 case SDDS_STRING:
1857 if (is_parameter) {
1858 int32_t len;
1859 if (((char **)data)[index]) {
1860 free(((char **)data)[index]);
1861 ((char **)data)[index] = NULL;
1862 }
1863 if ((len = strlen(string)) > 0) {
1864 if (string[len - 1] == '\r')
1865 string[len - 1] = 0;
1866 }
1867 if (string[0] == '"')
1868 SDDS_GetToken(string, buffer, bufferSize);
1869 else
1870 strcpy(buffer, string);
1871 SDDS_InterpretEscapes(buffer);
1872 if (SDDS_CopyString(((char **)data) + index, buffer)) {
1873 if (buffer)
1874 free(buffer);
1875 return (1);
1876 }
1877 } else {
1878 if (field_length) {
1879 if (abs_field_length > (int32_t)strlen(string)) {
1880 strcpy(buffer, string);
1881 *string = 0;
1882 } else {
1883 strncpy(buffer, string, abs_field_length);
1884 buffer[abs_field_length] = 0;
1885 strcpy(string, string + abs_field_length);
1886 }
1887 if (field_length < 0)
1888 SDDS_RemovePadding(buffer);
1889 } else if (SDDS_GetToken(string, buffer, bufferSize) < 0)
1890 break;
1891 if (((char **)data)[index]) {
1892 free(((char **)data)[index]);
1893 ((char **)data)[index] = NULL;
1894 }
1895 SDDS_InterpretEscapes(buffer);
1896 if (SDDS_CopyString(((char **)data) + index, buffer)) {
1897 if (buffer)
1898 free(buffer);
1899 return (1);
1900 }
1901 }
1902 break;
1903 case SDDS_CHARACTER:
1904 SDDS_InterpretEscapes(buffer);
1905 *(((char *)data) + index) = buffer[0];
1906 if (buffer)
1907 free(buffer);
1908 return (1);
1909 default:
1910 SDDS_SetError("Unknown data type encountered (SDDS_ScanData)");
1911 return (0);
1912 }
1913 SDDS_SetError("Unable to scan data--scanning or allocation error (SDDS_ScanData)");
1914 return (0);
1915}
void SDDS_InterpretEscapes(char *s)
Interprets and converts escape sequences in a string.
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
void SDDS_RemovePadding(char *s)
Removes leading and trailing whitespace from a string.

◆ SDDS_ScanData2()

int32_t SDDS_ScanData2 ( char * string,
char ** pstring,
int32_t * strlength,
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, optimized for long strings.

This function is similar to SDDS_ScanData but optimized for very long strings. It modifies the input string by advancing the string pointer and reducing its length after each call, which can improve performance when processing large amounts of data.

Parameters
stringPointer to the input string containing the data to be scanned.
pstringPointer to the string pointer; this is updated to point to the next unread character.
strlengthPointer to the length of the string; this is updated as the string is consumed.
typeThe SDDS data type to interpret the scanned data as. Valid types include:
  • SDDS_SHORT
  • SDDS_USHORT
  • SDDS_LONG
  • SDDS_ULONG
  • SDDS_LONG64
  • SDDS_ULONG64
  • SDDS_FLOAT
  • SDDS_DOUBLE
  • SDDS_LONGDOUBLE
  • SDDS_STRING
  • SDDS_CHARACTER
field_lengthField length for fixed-field formats. Set to 0 for variable-field formats. If negative, indicates left-padding should be removed.
dataVoid pointer to the data storage where the scanned value will be saved. Must be pre-allocated and appropriate for the specified data type.
indexThe index within the data array where the value should be stored.
is_parameterSet to 1 if the data is from an SDDS parameter; set to 0 for column data.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
This function modifies the input string by advancing the pointer and reducing the length, which can lead to the original string being altered after each call. It is more efficient for processing very long strings compared to SDDS_ScanData.

Definition at line 1953 of file SDDS_ascii.c.

1953 {
1954 char *buffer = NULL;
1955 int32_t abs_field_length, length;
1956 int32_t bufferSize = 0;
1957
1958 abs_field_length = abs(field_length);
1959 if (!string) {
1960 SDDS_SetError("Unable to scan data--input string is NULL (SDDS_ScanData2)");
1961 return (0);
1962 }
1963 if (!data) {
1964 SDDS_SetError("Unable to scan data--data pointer is NULL (SDDS_ScanData2)");
1965 return (0);
1966 }
1967 if (!(buffer = SDDS_Malloc(sizeof(*buffer) * (bufferSize = SDDS_MAXLINE)))) {
1968 SDDS_SetError("Unable to scan data--allocation failure (SDDS_ScanData2)");
1969 return (0);
1970 }
1971 length = *strlength;
1972 if (length < abs_field_length)
1973 length = abs_field_length;
1974 if (bufferSize <= length) {
1975 if (!(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * (bufferSize = 2 * length)))) {
1976 /* I allocate 2*length in the hopes that I won't need to realloc too often if I do this */
1977 SDDS_SetError("Unable to scan data--allocation failure (SDDS_ScanData2)");
1978 return (0);
1979 }
1980 }
1981 if (type != SDDS_STRING) {
1982 /* for non-string data, fill buffer with string to be scanned */
1983 if (field_length) {
1984 /* fill with fixed number of characters */
1985 if (abs_field_length > *strlength) {
1986 strcpy(buffer, string);
1987 **pstring = 0;
1988 *strlength = 0;
1989 } else {
1990 strncpy(buffer, string, abs_field_length);
1991 buffer[abs_field_length] = 0;
1992 *pstring += abs_field_length;
1993 *strlength -= abs_field_length;
1994 }
1995 } else if (SDDS_GetToken2(string, pstring, strlength, buffer, bufferSize) < 0) {
1996 SDDS_SetError("Unable to scan data--tokenizing error (SDDS_ScanData2)");
1997 return (0);
1998 }
1999 }
2000 switch (type) {
2001 case SDDS_SHORT:
2002 if (sscanf(buffer, "%hd", ((short *)data) + index) == 1) {
2003 if (buffer)
2004 free(buffer);
2005 return (1);
2006 }
2007 break;
2008 case SDDS_USHORT:
2009 if (sscanf(buffer, "%hu", ((unsigned short *)data) + index) == 1) {
2010 if (buffer)
2011 free(buffer);
2012 return (1);
2013 }
2014 break;
2015 case SDDS_LONG:
2016 if (sscanf(buffer, "%" SCNd32, ((int32_t *)data) + index) == 1) {
2017 if (buffer)
2018 free(buffer);
2019 return (1);
2020 }
2021 break;
2022 case SDDS_ULONG:
2023 if (sscanf(buffer, "%" SCNu32, ((uint32_t *)data) + index) == 1) {
2024 if (buffer)
2025 free(buffer);
2026 return (1);
2027 }
2028 break;
2029 case SDDS_LONG64:
2030 if (sscanf(buffer, "%" SCNd64, ((int64_t *)data) + index) == 1) {
2031 if (buffer)
2032 free(buffer);
2033 return (1);
2034 }
2035 break;
2036 case SDDS_ULONG64:
2037 if (sscanf(buffer, "%" SCNu64, ((uint64_t *)data) + index) == 1) {
2038 if (buffer)
2039 free(buffer);
2040 return (1);
2041 }
2042 break;
2043 case SDDS_FLOAT:
2044 if (sscanf(buffer, "%f", ((float *)data) + index) == 1) {
2045 if (buffer)
2046 free(buffer);
2047 return (1);
2048 }
2049 break;
2050 case SDDS_DOUBLE:
2051 if (sscanf(buffer, "%lf", ((double *)data) + index) == 1) {
2052 if (buffer)
2053 free(buffer);
2054 return (1);
2055 }
2056 break;
2057 case SDDS_LONGDOUBLE:
2058 if (sscanf(buffer, "%Lf", ((long double *)data) + index) == 1) {
2059 if (buffer)
2060 free(buffer);
2061 return (1);
2062 }
2063 break;
2064 case SDDS_STRING:
2065 if (is_parameter) {
2066 int32_t len;
2067 if (((char **)data)[index]) {
2068 free(((char **)data)[index]);
2069 ((char **)data)[index] = NULL;
2070 }
2071 if ((len = *strlength) > 0) {
2072 if (*pstring[len - 1] == '\r') {
2073 *pstring[len - 1] = 0;
2074 *strlength -= 1;
2075 }
2076 }
2077 if (*pstring[0] == '"')
2078 SDDS_GetToken2(*pstring, pstring, strlength, buffer, bufferSize);
2079 else
2080 strcpy(buffer, string);
2081 SDDS_InterpretEscapes(buffer);
2082 if (SDDS_CopyString(((char **)data) + index, buffer)) {
2083 if (buffer)
2084 free(buffer);
2085 return (1);
2086 }
2087 } else {
2088 if (field_length) {
2089 if (abs_field_length > *strlength) {
2090 strcpy(buffer, string);
2091 **pstring = 0;
2092 *strlength = 0;
2093 } else {
2094 strncpy(buffer, string, abs_field_length);
2095 buffer[abs_field_length] = 0;
2096 *pstring += abs_field_length;
2097 *strlength -= abs_field_length;
2098 }
2099 if (field_length < 0)
2100 SDDS_RemovePadding(buffer);
2101 } else if (SDDS_GetToken2(string, pstring, strlength, buffer, bufferSize) < 0)
2102 break;
2103 if (((char **)data)[index]) {
2104 free(((char **)data)[index]);
2105 ((char **)data)[index] = NULL;
2106 }
2107 SDDS_InterpretEscapes(buffer);
2108 if (SDDS_CopyString(((char **)data) + index, buffer)) {
2109 if (buffer)
2110 free(buffer);
2111 return (1);
2112 }
2113 }
2114 break;
2115 case SDDS_CHARACTER:
2116 SDDS_InterpretEscapes(buffer);
2117 *(((char *)data) + index) = buffer[0];
2118 if (buffer)
2119 free(buffer);
2120 return 1;
2121 default:
2122 SDDS_SetError("Unknown data type encountered (SDDS_ScanData2)");
2123 return (0);
2124 }
2125 SDDS_SetError("Unable to scan data--scanning or allocation error (SDDS_ScanData2)");
2126 return (0);
2127}
int32_t SDDS_GetToken2(char *s, char **st, int32_t *strlength, char *buffer, int32_t buflen)
Extracts the next token from a string, handling quoted substrings and escape characters,...

◆ SDDS_UpdateAsciiPage()

int32_t SDDS_UpdateAsciiPage ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Updates the current ASCII page of an SDDS dataset with new data.

This function updates the ASCII page of the provided SDDS dataset, appending any new rows that have been added since the last write. It handles updating the row count in the file and ensures data consistency. If the dataset is not currently writing a page, it initiates a new page write.

Parameters
SDDS_datasetPointer to the SDDS dataset to update.
modeMode flags that control the update behavior. Common modes include:
  • FLUSH_TABLE: Flushes the data table after writing.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
This function cannot be used with compressed files (GZIP or LZMA). It requires a regular ASCII file. It also handles updating internal state variables such as the number of rows written and the last row written.

Definition at line 2167 of file SDDS_ascii.c.

2167 {
2168 FILE *fp;
2169 int32_t code;
2170 int64_t i, rows, offset;
2171 SDDS_FILEBUFFER *fBuffer;
2172
2173#ifdef DEBUG
2174 fprintf(stderr, "%" PRId64 " virtual rows present, first=%" PRId32 "\n", SDDS_CountRowsOfInterest(SDDS_dataset), SDDS_dataset->first_row_in_mem);
2175#endif
2176 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_UpdateAsciiPage"))
2177 return (0);
2178#if defined(zLib)
2179 if (SDDS_dataset->layout.gzipFile) {
2180 SDDS_SetError("Unable to perform page updates on a gzip file (SDDS_UpdateAsciiPage)");
2181 return 0;
2182 }
2183#endif
2184 if (SDDS_dataset->layout.lzmaFile) {
2185 SDDS_SetError("Unable to perform page updates on an .lzma or .xz file (SDDS_UpdateAsciiPage)");
2186 return 0;
2187 }
2188 if (!SDDS_dataset->writing_page) {
2189 if (!(code = SDDS_WriteAsciiPage(SDDS_dataset)))
2190 return 0;
2191 if (mode & FLUSH_TABLE) {
2192 SDDS_FreeTableStrings(SDDS_dataset);
2193 SDDS_dataset->first_row_in_mem = SDDS_CountRowsOfInterest(SDDS_dataset);
2194 SDDS_dataset->last_row_written = -1;
2195 SDDS_dataset->n_rows = 0;
2196 }
2197 return code;
2198 }
2199 if (!(fp = SDDS_dataset->layout.fp)) {
2200 SDDS_SetError("Unable to update page--file pointer is NULL (SDDS_UpdateAsciiPage)");
2201 return (0);
2202 }
2203 fBuffer = &SDDS_dataset->fBuffer;
2204 if (!SDDS_FlushBuffer(fp, fBuffer)) {
2205 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateAsciiPage)");
2206 return 0;
2207 }
2208 offset = ftell(fp);
2209
2210 rows = SDDS_CountRowsOfInterest(SDDS_dataset) + SDDS_dataset->first_row_in_mem;
2211 if (rows == SDDS_dataset->n_rows_written)
2212 return (1);
2213 if (rows < SDDS_dataset->n_rows_written) {
2214 SDDS_SetError("Unable to update page--new number of rows less than previous number (SDDS_UpdateAsciiPage)");
2215 return (0);
2216 }
2217 if ((!SDDS_dataset->layout.data_mode.fixed_row_count) || (((rows + rows - SDDS_dataset->n_rows_written) / SDDS_dataset->layout.data_mode.fixed_row_increment) != (rows / SDDS_dataset->layout.data_mode.fixed_row_increment))) {
2218 if (!SDDS_dataset->layout.data_mode.no_row_counts) {
2219 if (SDDS_fseek(fp, SDDS_dataset->rowcount_offset, SEEK_SET) == -1) {
2220 SDDS_SetError("Unable to update page--failure doing fseek (SDDS_UpdateAsciiPage)");
2221 return (0);
2222 }
2223 /* overwrite the existing row count */
2224 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
2225 if ((rows - SDDS_dataset->n_rows_written) + 1 > SDDS_dataset->layout.data_mode.fixed_row_increment) {
2226 SDDS_dataset->layout.data_mode.fixed_row_increment = (rows - SDDS_dataset->n_rows_written) + 1;
2227 }
2228 fprintf(fp, "%20" PRId64 "\n", ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment);
2229 } else
2230 fprintf(fp, "%20" PRId64 "\n", rows);
2231 if (SDDS_fseek(fp, offset, SEEK_SET) == -1) {
2232 SDDS_SetError("Unable to update page--failure doing fseek to end of page (SDDS_UpdateAsciiPage)");
2233 return (0);
2234 }
2235 }
2236 }
2237 for (i = SDDS_dataset->last_row_written + 1; i < SDDS_dataset->n_rows; i++)
2238 if (SDDS_dataset->row_flag[i])
2239 SDDS_WriteAsciiRow(SDDS_dataset, i, fp);
2240 if (!SDDS_FlushBuffer(fp, fBuffer)) {
2241 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateAsciiPage)");
2242 return 0;
2243 }
2244 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
2245 SDDS_dataset->n_rows_written = rows;
2246 if (mode & FLUSH_TABLE) {
2247 SDDS_FreeTableStrings(SDDS_dataset);
2248 SDDS_dataset->first_row_in_mem = rows;
2249 SDDS_dataset->last_row_written = -1;
2250 SDDS_dataset->n_rows = 0;
2251 }
2252 return (1);
2253}
int32_t SDDS_WriteAsciiPage(SDDS_DATASET *SDDS_dataset)
Writes a page of data in ASCII format to the SDDS dataset.
Definition SDDS_ascii.c:410
int32_t SDDS_WriteAsciiRow(SDDS_DATASET *SDDS_dataset, int64_t row, FILE *fp)
Writes a single row of data in ASCII format to a file.
Definition SDDS_ascii.c:775
int32_t SDDS_FlushBuffer(FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_fseek(FILE *fp, int64_t offset, int32_t dir)
Sets the file position indicator for a given file stream with retry logic.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void SDDS_FreeTableStrings(SDDS_DATASET *SDDS_dataset)

◆ SDDS_WriteAsciiArrays()

int32_t SDDS_WriteAsciiArrays ( SDDS_DATASET * SDDS_dataset,
FILE * fp )

Writes the arrays of an SDDS dataset in ASCII format to a file.

This function writes all arrays contained in the provided SDDS dataset to the specified file pointer in ASCII format. For each array, it writes the dimensions, a description line, and the array elements formatted according to their data type.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the arrays to be written.
fpFile pointer to the ASCII file where the array data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_WriteTypedValue() to write each array element according to its data type. Each array element is written, with up to 6 elements per line.

Definition at line 635 of file SDDS_ascii.c.

635 {
636 int32_t i, j;
637 SDDS_LAYOUT *layout;
638 /* char *predefined_format; */
639 ARRAY_DEFINITION *array_definition;
640 SDDS_ARRAY *array;
641
642 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteAsciiArrays"))
643 return (0);
644 layout = &SDDS_dataset->layout;
645 for (j = 0; j < layout->n_arrays; j++) {
646 array_definition = layout->array_definition + j;
647 array = &SDDS_dataset->array[j];
648 for (i = 0; i < array_definition->dimensions; i++)
649 fprintf(fp, "%" PRId32 " ", array->dimension[i]);
650 fprintf(fp, " ! %" PRId32 "-dimensional array %s:\n", array_definition->dimensions, array_definition->name);
651 for (i = 0; i < array->elements;) {
652 if (!SDDS_WriteTypedValue(array->data, i, array_definition->type, NULL, fp)) {
653 SDDS_SetError("Unable to write array--couldn't write ASCII data (SDDS_WriteAsciiArrays)");
654 return (0);
655 }
656 i++;
657 if (i % 6 == 0 || i == array->elements)
658 fputc('\n', fp);
659 else
660 fputc(' ', fp);
661 }
662 }
663 return (1);
664}
int32_t SDDS_WriteTypedValue(void *data, int64_t index, int32_t type, char *format, FILE *fp)
Writes a typed value to an ASCII file stream.
Definition SDDS_ascii.c:57

◆ SDDS_WriteAsciiPage()

int32_t SDDS_WriteAsciiPage ( SDDS_DATASET * SDDS_dataset)

Writes a page of data in ASCII format to the SDDS dataset.

This function writes the current page of data from the SDDS dataset to an ASCII file. It handles writing to regular files, as well as LZMA and GZIP compressed files if enabled. The function writes the page number, parameters, arrays, and rows of data according to the SDDS format.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the data to be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
This function checks the dataset for consistency before writing. It also updates internal state variables such as the last row written and the number of rows written.

Definition at line 410 of file SDDS_ascii.c.

410 {
411#if defined(zLib)
412 gzFile gzfp;
413#endif
414 FILE *fp;
415 struct lzmafile *lzmafp;
416 int64_t i, rows;
417
418 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteAsciiPage"))
419 return (0);
420#if defined(zLib)
421 if (SDDS_dataset->layout.gzipFile) {
422 if (!(gzfp = SDDS_dataset->layout.gzfp)) {
423 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteAsciiPage)");
424 return (0);
425 }
426 if (SDDS_dataset->layout.data_mode.no_row_counts && (SDDS_dataset->page_number > 1 || SDDS_dataset->file_had_data))
427 gzputc(gzfp, '\n');
428 gzprintf(gzfp, "! page number %" PRId32 "\n", SDDS_dataset->page_number);
429
430 if (!SDDS_GZipWriteAsciiParameters(SDDS_dataset, gzfp) || !SDDS_GZipWriteAsciiArrays(SDDS_dataset, gzfp))
431 return 0;
432 rows = 0;
433 if (SDDS_dataset->layout.n_columns) {
434 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
435 if (!SDDS_dataset->layout.data_mode.no_row_counts) {
436 SDDS_dataset->rowcount_offset = gztell(gzfp);
437 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
438 gzprintf(gzfp, "%20" PRId64 "\n", ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment);
439 } else
440 gzprintf(gzfp, "%20" PRId64 "\n", rows);
441 }
442 for (i = 0; i < SDDS_dataset->n_rows; i++)
443 if (SDDS_dataset->row_flag[i] && !SDDS_GZipWriteAsciiRow(SDDS_dataset, i, gzfp))
444 return 0;
445 }
446 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
447 SDDS_dataset->n_rows_written = rows;
448 SDDS_dataset->writing_page = 1;
449 /*gzflush(gzfp, Z_FULL_FLUSH); */
450 } else {
451#endif
452 if (SDDS_dataset->layout.lzmaFile) {
453 if (!(lzmafp = SDDS_dataset->layout.lzmafp)) {
454 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteAsciiPage)");
455 return (0);
456 }
457 if (SDDS_dataset->layout.data_mode.no_row_counts && (SDDS_dataset->page_number > 1 || SDDS_dataset->file_had_data))
458 lzma_putc('\n', lzmafp);
459 lzma_printf(lzmafp, "! page number %" PRId32 "\n", SDDS_dataset->page_number);
460
461 if (!SDDS_LZMAWriteAsciiParameters(SDDS_dataset, lzmafp) || !SDDS_LZMAWriteAsciiArrays(SDDS_dataset, lzmafp))
462 return 0;
463 rows = 0;
464 if (SDDS_dataset->layout.n_columns) {
465 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
466 if (!SDDS_dataset->layout.data_mode.no_row_counts) {
467 SDDS_dataset->rowcount_offset = lzma_tell(lzmafp);
468 if (SDDS_dataset->layout.data_mode.fixed_row_count)
469 lzma_printf(lzmafp, "%20" PRId64 "\n", ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment);
470 else
471 lzma_printf(lzmafp, "%20" PRId64 "\n", rows);
472 }
473 for (i = 0; i < SDDS_dataset->n_rows; i++)
474 if (SDDS_dataset->row_flag[i] && !SDDS_LZMAWriteAsciiRow(SDDS_dataset, i, lzmafp))
475 return 0;
476 }
477 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
478 SDDS_dataset->n_rows_written = rows;
479 SDDS_dataset->writing_page = 1;
480 } else {
481 if (!(fp = SDDS_dataset->layout.fp)) {
482 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteAsciiPage)");
483 return (0);
484 }
485 if (SDDS_dataset->layout.data_mode.no_row_counts && (SDDS_dataset->page_number > 1 || SDDS_dataset->file_had_data))
486 fputc('\n', fp);
487 fprintf(fp, "! page number %" PRId32 "\n", SDDS_dataset->page_number);
488
489 if (!SDDS_WriteAsciiParameters(SDDS_dataset, fp) || !SDDS_WriteAsciiArrays(SDDS_dataset, fp))
490 return 0;
491 rows = 0;
492 if (SDDS_dataset->layout.n_columns) {
493 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
494 if (!SDDS_dataset->layout.data_mode.no_row_counts) {
495 SDDS_dataset->rowcount_offset = ftell(fp);
496 if (SDDS_dataset->layout.data_mode.fixed_row_count)
497 fprintf(fp, "%20" PRId64 "\n", ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment);
498 else
499 fprintf(fp, "%20" PRId64 "\n", rows);
500 }
501 for (i = 0; i < SDDS_dataset->n_rows; i++)
502 if (SDDS_dataset->row_flag[i] && !SDDS_WriteAsciiRow(SDDS_dataset, i, fp))
503 return 0;
504 }
505 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
506 SDDS_dataset->n_rows_written = rows;
507 SDDS_dataset->writing_page = 1;
508 fflush(fp);
509 }
510#if defined(zLib)
511 }
512#endif
513
514 return (1);
515}
int32_t SDDS_LZMAWriteAsciiArrays(SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
Writes the arrays of an SDDS dataset in ASCII format to an LZMA compressed file.
Definition SDDS_ascii.c:680
int32_t SDDS_LZMAWriteAsciiParameters(SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
Writes the parameter data of an SDDS dataset in ASCII format to an LZMA compressed file.
Definition SDDS_ascii.c:565
int32_t SDDS_WriteAsciiParameters(SDDS_DATASET *SDDS_dataset, FILE *fp)
Writes the parameter data of an SDDS dataset in ASCII format to a file.
Definition SDDS_ascii.c:531
int32_t SDDS_LZMAWriteAsciiRow(SDDS_DATASET *SDDS_dataset, int64_t row, struct lzmafile *lzmafp)
Writes a single row of data in ASCII format to an LZMA compressed file.
Definition SDDS_ascii.c:826
int32_t SDDS_WriteAsciiArrays(SDDS_DATASET *SDDS_dataset, FILE *fp)
Writes the arrays of an SDDS dataset in ASCII format to a file.
Definition SDDS_ascii.c:635

◆ SDDS_WriteAsciiParameters()

int32_t SDDS_WriteAsciiParameters ( SDDS_DATASET * SDDS_dataset,
FILE * fp )

Writes the parameter data of an SDDS dataset in ASCII format to a file.

This function writes all parameters of the SDDS dataset to the provided file pointer in ASCII format. Only parameters that do not have fixed values are written. Each parameter value is written on a new line.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the parameter data.
fpFile pointer to the ASCII file where the parameter data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_WriteTypedValue() to write each parameter value according to its data type.

Definition at line 531 of file SDDS_ascii.c.

531 {
532 int32_t i;
533 SDDS_LAYOUT *layout;
534 /* char *predefined_format; */
535
536 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteAsciiParameters"))
537 return (0);
538 layout = &SDDS_dataset->layout;
539 for (i = 0; i < layout->n_parameters; i++) {
540 if (layout->parameter_definition[i].fixed_value)
541 continue;
542 if (!SDDS_WriteTypedValue(SDDS_dataset->parameter[i], 0, layout->parameter_definition[i].type, NULL, fp)) {
543 SDDS_SetError("Unable to write ascii parameters (SDDS_WriteAsciiParameters)");
544 return 0;
545 }
546 fputc('\n', fp);
547 }
548 return (1);
549}

◆ SDDS_WriteAsciiRow()

int32_t SDDS_WriteAsciiRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
FILE * fp )

Writes a single row of data in ASCII format to a file.

This function writes the specified row from the SDDS dataset to the provided file pointer in ASCII format. The data is formatted according to the data types of the columns. Supports multi-line rows as specified by the data mode settings in the dataset layout.

Parameters
SDDS_datasetPointer to the SDDS dataset containing the data.
rowZero-based index of the row to write.
fpFile pointer to the ASCII file where the row data will be written.
Returns
Returns 1 on success, or 0 on error. If an error occurs, an error message is set via SDDS_SetError().
Note
The function checks the dataset for consistency before writing. It uses SDDS_WriteTypedValue() to write each column value according to its data type. The number of values per line is determined by the lines_per_row setting in the dataset layout.

Definition at line 775 of file SDDS_ascii.c.

775 {
776 int32_t newline_needed;
777 int64_t i, n_per_line, line;
778 /* int32_t embedded_quotes_present; */
779 SDDS_LAYOUT *layout;
780 /* char *predefined_format, *s; */
781
782 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteAsciiRow"))
783 return (0);
784 layout = &SDDS_dataset->layout;
785 if (SDDS_dataset->layout.data_mode.lines_per_row <= 0)
786 SDDS_dataset->layout.data_mode.lines_per_row = 1;
787 n_per_line = SDDS_dataset->layout.n_columns / SDDS_dataset->layout.data_mode.lines_per_row;
788 line = 1;
789 newline_needed = 0;
790 for (i = 0; i < layout->n_columns; i++) {
791 if (!SDDS_WriteTypedValue(SDDS_dataset->data[i], row, layout->column_definition[i].type, NULL, fp)) {
792 SDDS_SetError("Unable to write ascii row (SDDS_WriteAsciiRow)");
793 return 0;
794 }
795 if ((i + 1) % n_per_line == 0 && line != SDDS_dataset->layout.data_mode.lines_per_row) {
796 newline_needed = 0;
797 fputc('\n', fp);
798 line++;
799 } else {
800 fputc(' ', fp);
801 newline_needed = 1;
802 }
803 }
804 if (newline_needed)
805 fputc('\n', fp);
806 return (1);
807}

◆ SDDS_WriteTypedValue()

int32_t SDDS_WriteTypedValue ( void * data,
int64_t index,
int32_t type,
char * format,
FILE * fp )

Writes a typed value to an ASCII file stream.

This function writes a value of a specified SDDS data type to an ASCII file stream. The data is provided as a void pointer, and the function handles various data types by casting the pointer appropriately based on the type parameter. For string data, special characters are escaped according to SDDS conventions.

Parameters
dataPointer to the data to be written. Should be castable to the type specified by type.
indexArray index of the data to be printed; use 0 if not an array.
typeThe SDDS data type of the data variable. Possible values include SDDS_SHORT, SDDS_LONG, SDDS_FLOAT, etc.
formatOptional printf format string to use; pass NULL to use the default format for the data type.
fpThe FILE pointer to the ASCII file stream where the data will be written.
Returns
Returns 1 on success; 0 on error (e.g., if data or fp is NULL, or an unknown data type is specified).

Definition at line 57 of file SDDS_ascii.c.

57 {
58 char c, *s;
59 short hasWhitespace;
60
61 if (!data) {
62 SDDS_SetError("Unable to write value--data pointer is NULL (SDDS_WriteTypedValue)");
63 return (0);
64 }
65 if (!fp) {
66 SDDS_SetError("Unable to print value--file pointer is NULL (SDDS_WriteTypedValue)");
67 return (0);
68 }
69 switch (type) {
70 case SDDS_SHORT:
71 fprintf(fp, format ? format : "%hd", *((short *)data + index));
72 break;
73 case SDDS_USHORT:
74 fprintf(fp, format ? format : "%hu", *((unsigned short *)data + index));
75 break;
76 case SDDS_LONG:
77 fprintf(fp, format ? format : "%" PRId32, *((int32_t *)data + index));
78 break;
79 case SDDS_ULONG:
80 fprintf(fp, format ? format : "%" PRIu32, *((uint32_t *)data + index));
81 break;
82 case SDDS_LONG64:
83 fprintf(fp, format ? format : "%" PRId64, *((int64_t *)data + index));
84 break;
85 case SDDS_ULONG64:
86 fprintf(fp, format ? format : "%" PRIu64, *((uint64_t *)data + index));
87 break;
88 case SDDS_FLOAT:
89 fprintf(fp, format ? format : "%15.8e", *((float *)data + index));
90 break;
91 case SDDS_DOUBLE:
92 fprintf(fp, format ? format : "%22.15e", *((double *)data + index));
93 break;
94 case SDDS_LONGDOUBLE:
95 if (LDBL_DIG == 18) {
96 fprintf(fp, format ? format : "%22.18Le", *((long double *)data + index));
97 } else {
98 fprintf(fp, format ? format : "%22.15Le", *((long double *)data + index));
99 }
100 break;
101 case SDDS_STRING:
102 /* ignores format string */
103 s = *((char **)data + index);
104 hasWhitespace = 0;
106 fputc('"', fp);
107 hasWhitespace = 1;
108 }
109 while (s && *s) {
110 c = *s++;
111 if (c == '!')
112 fputs("\\!", fp);
113 else if (c == '\\')
114 fputs("\\\\", fp);
115 else if (c == '"')
116 fputs("\\\"", fp);
117 else if (c == ' ')
118 fputc(' ', fp); /* don't escape plain spaces */
119 else if (isspace(c) || !isprint(c))
120 fprintf(fp, "\\%03o", c);
121 else
122 fputc(c, fp);
123 }
124 if (hasWhitespace)
125 fputc('"', fp);
126 break;
127 case SDDS_CHARACTER:
128 /* ignores format string */
129 c = *((char *)data + index);
130 if (c == '!')
131 fputs("\\!", fp);
132 else if (c == '\\')
133 fputs("\\\\", fp);
134 else if (c == '"')
135 fputs("\\\"", fp);
136 else if (!c || isspace(c) || !isprint(c))
137 fprintf(fp, "\\%03o", c);
138 else
139 fputc(c, fp);
140 break;
141 default:
142 SDDS_SetError("Unable to write value--unknown data type (SDDS_WriteTypedValue)");
143 return (0);
144 }
145 return (1);
146}