SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDS_input.c File Reference

Detailed Description

This file contains the functions related to reading SDDS files.

The SDDS_input.c file provides functions for reading data from SDDS files. It includes functions for opening and closing SDDS files, reading headers, and reading data tables.

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_input.c.

#include "mdb.h"
#include "match_string.h"
#include "SDDS.h"
#include "SDDS_internal.h"
#include "mdb_thread.h"
#include "namelist.h"
#include "scan.h"
#include <signal.h>

Go to the source code of this file.

Functions

int32_t SDDS_InitializeInput (SDDS_DATASET *SDDS_dataset, char *filename)
 
int32_t SDDS_InitializeHeaderlessInput (SDDS_DATASET *SDDS_dataset, char *filename)
 Initializes the SDDS dataset for headerless input.
 
int32_t SDDS_IsQuoted (char *string, char *position, char quotation_mark)
 Checks if a position in a string is within a quoted section.
 
int32_t SDDS_GetNamelist (SDDS_DATASET *SDDS_dataset, char *buffer, int32_t buflen, FILE *fp)
 Reads a namelist from a file into a buffer.
 
int32_t SDDS_GetLZMANamelist (SDDS_DATASET *SDDS_dataset, char *buffer, int32_t buflen, struct lzmafile *lzmafp)
 Reads a namelist from an LZMA-compressed file into a buffer.
 
int32_t SDDS_ReadLayout (SDDS_DATASET *SDDS_dataset, FILE *fp)
 
int32_t SDDS_LZMAReadLayout (SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
 
int32_t SDDS_ReadPage (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_CheckEndOfFile (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_ReadPageSparse (SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset, int32_t sparse_statistics)
 
int32_t SDDS_ReadPageLastRows (SDDS_DATASET *SDDS_dataset, int64_t last_rows)
 
static int64_t SDDS_GetLockedRowLimit (void)
 
int64_t SDDS_SetRowLimit (int64_t limit)
 
int64_t SDDS_GetRowLimit ()
 
int32_t SDDS_GotoPage (SDDS_DATASET *SDDS_dataset, int32_t page_number)
 Sets the current page of the SDDS dataset to the specified page number.
 
int32_t SDDS_GetTerminateMode (void)
 
void SDDS_SetTerminateMode (uint32_t mode)
 
void SDDS_SetColumnMemoryMode (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 
int32_t SDDS_GetColumnMemoryMode (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_FreeStringData (SDDS_DATASET *SDDS_dataset)
 
void SDDS_FreeTableStrings (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_Terminate (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_UpdateRowCount (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_SetAutoReadRecovery (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 
int32_t SDDS_InitializeInputFromSearchPath (SDDS_DATASET *SDDSin, char *file)
 

Function Documentation

◆ SDDS_CheckEndOfFile()

int32_t SDDS_CheckEndOfFile ( SDDS_DATASET * SDDS_dataset)

Checks if the end of the SDDS dataset file has been reached.

Parameters
SDDS_datasetThe SDDS dataset structure.
Returns
Returns 1 if the end of file has been reached, 0 if not, and 2 on error.

Definition at line 1021 of file SDDS_input.c.

1021 {
1022 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_EndOfFile"))
1023 return (0);
1024 if (SDDS_dataset->layout.disconnected) {
1025 SDDS_SetError("Can't check status--file is disconnected (SDDS_EndOfFile)");
1026 return 2;
1027 }
1028#if defined(zLib)
1029 if (SDDS_dataset->layout.gzipFile) {
1030 if (!SDDS_dataset->layout.gzfp) {
1031 SDDS_SetError("Unable to check status--NULL file pointer (SDDS_EndOfFile)");
1032 return 2;
1033 }
1034 } else {
1035#endif
1036 if (SDDS_dataset->layout.lzmaFile) {
1037 if (!SDDS_dataset->layout.lzmafp) {
1038 SDDS_SetError("Unable to check status--NULL file pointer (SDDS_EndOfFile)");
1039 return 2;
1040 }
1041 } else {
1042 if (!SDDS_dataset->layout.fp) {
1043 SDDS_SetError("Unable to check status--NULL file pointer (SDDS_EndOfFile)");
1044 return 2;
1045 }
1046 }
1047#if defined(zLib)
1048 }
1049#endif
1050 if (SDDS_dataset->fBuffer.bufferSize && SDDS_dataset->fBuffer.bytesLeft) {
1051 return 0;
1052 }
1053
1054#if defined(zLib)
1055 if (SDDS_dataset->layout.gzipFile) {
1056 if (gzeof(SDDS_dataset->layout.gzfp))
1057 return 1;
1058 } else {
1059#endif
1060 if (SDDS_dataset->layout.lzmaFile) {
1061 if (lzma_eof(SDDS_dataset->layout.lzmafp))
1062 return 1;
1063 } else {
1064 if (feof(SDDS_dataset->layout.fp))
1065 return 1;
1066 }
1067#if defined(zLib)
1068 }
1069#endif
1070 return 0;
1071}
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:618

◆ SDDS_FreeStringData()

int32_t SDDS_FreeStringData ( SDDS_DATASET * SDDS_dataset)

Frees all allocated string data in the SDDS dataset.

This function frees any strings allocated for parameters, arrays, and columns within the SDDS dataset. It is typically called during termination to clean up allocated memory.

Parameters
SDDS_datasetThe SDDS dataset to free string data from.
Returns
Returns 1 on success, 0 on failure.

Definition at line 1397 of file SDDS_input.c.

1397 {
1398 SDDS_LAYOUT *layout;
1399 char **ptr;
1400 int64_t i, j;
1401 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_Terminate"))
1402 return (0);
1403 layout = &SDDS_dataset->original_layout;
1404
1405 if (SDDS_dataset->parameter) {
1406 for (i = 0; i < layout->n_parameters; i++) {
1407 if (layout->parameter_definition[i].type == SDDS_STRING) {
1408 free(*(char **)(SDDS_dataset->parameter[i]));
1409 *(char **)(SDDS_dataset->parameter[i]) = NULL;
1410 }
1411 }
1412 }
1413 if (SDDS_dataset->array) {
1414 for (i = 0; i < layout->n_arrays; i++) {
1415 if (layout->array_definition[i].type == SDDS_STRING) {
1416 for (j = 0; j < SDDS_dataset->array[i].elements; j++)
1417 if (((char **)SDDS_dataset->array[i].data)[j]) {
1418 free(((char **)SDDS_dataset->array[i].data)[j]);
1419 ((char **)SDDS_dataset->array[i].data)[j] = NULL;
1420 }
1421 }
1422 }
1423 }
1424 if (SDDS_dataset->data) {
1425 for (i = 0; i < layout->n_columns; i++)
1426 if (SDDS_dataset->data[i]) {
1427 if (layout->column_definition[i].type == SDDS_STRING) {
1428 ptr = (char **)SDDS_dataset->data[i];
1429 for (j = 0; j < SDDS_dataset->n_rows_allocated; j++, ptr++)
1430 if (*ptr) {
1431 free(*ptr);
1432 *ptr = NULL;
1433 }
1434 }
1435 }
1436 }
1437 return (1);
1438}
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85

◆ SDDS_FreeTableStrings()

void SDDS_FreeTableStrings ( SDDS_DATASET * SDDS_dataset)

Frees the strings in the current table of the SDDS dataset.

This function frees any strings stored in the data columns of the current table. It does not free strings from parameters or arrays.

Parameters
SDDS_datasetThe SDDS dataset to free table strings from.

Definition at line 1448 of file SDDS_input.c.

1448 {
1449 int64_t i, j;
1450 char **ptr;
1451 /* free stored strings */
1452 if (!SDDS_dataset)
1453 return;
1454 for (i = 0; i < SDDS_dataset->layout.n_columns; i++)
1455 if (SDDS_dataset->layout.column_definition[i].type == SDDS_STRING) {
1456 ptr = (char **)SDDS_dataset->data[i];
1457 for (j = 0; j < SDDS_dataset->n_rows; j++, ptr++)
1458 if (*ptr) {
1459 free(*ptr);
1460 *ptr = NULL;
1461 }
1462 }
1463}

◆ SDDS_GetColumnMemoryMode()

int32_t SDDS_GetColumnMemoryMode ( SDDS_DATASET * SDDS_dataset)

Retrieves the current column memory mode for the SDDS dataset.

Parameters
SDDS_datasetThe SDDS dataset to query.
Returns
The current column memory mode.

Definition at line 1381 of file SDDS_input.c.

1381 {
1382 return (SDDS_dataset->layout.data_mode.column_memory_mode);
1383}

◆ SDDS_GetLockedRowLimit()

static int64_t SDDS_GetLockedRowLimit ( void )
static

Definition at line 1229 of file SDDS_input.c.

1229 {
1230 int64_t limit;
1231 mdb_thread_lock(&SDDS_RowLimitLock);
1232 limit = SDDS_RowLimit;
1233 mdb_thread_unlock(&SDDS_RowLimitLock);
1234 return limit;
1235}
static MDB_THREAD_LOCK SDDS_RowLimitLock
Global variable to set a limit on the number of rows read.

◆ SDDS_GetLZMANamelist()

int32_t SDDS_GetLZMANamelist ( SDDS_DATASET * SDDS_dataset,
char * buffer,
int32_t buflen,
struct lzmafile * lzmafp )

Reads a namelist from an LZMA-compressed file into a buffer.

This function reads a namelist from an LZMA-compressed file stream into the provided buffer, handling comments and skipping them appropriately.

Parameters
SDDS_datasetThe SDDS dataset structure.
bufferThe buffer where the namelist will be stored.
buflenThe length of the buffer.
lzmafpThe LZMA file stream to read from.
Returns
Returns 1 if a namelist is successfully read, 0 otherwise.

Definition at line 345 of file SDDS_input.c.

345 {
346 char *ptr, *flag, *buffer0;
347 /* char *ptr1 */
348 int32_t n;
349 /* int32_t namelistStarted; */
350
351 while ((flag = fgetsLZMASkipComments(SDDS_dataset, buffer, buflen, lzmafp, '!'))) {
352 if ((ptr = strchr(buffer, '&')) && !SDDS_IsQuoted(buffer, ptr, '"'))
353 break;
354 }
355 if (!flag)
356 return 0;
357 n = strlen(buffer) - 1;
358 if (buffer[n] == '\n') {
359 buffer[n] = ' ';
360 if ((n - 1 >= 0) && (buffer[n - 1] == '\r'))
361 buffer[n - 1] = ' ';
362 }
363
364 /* check for the beginning of a namelist (an unquoted &) */
365 ptr = buffer;
366 while (*ptr) {
367 if (*ptr == '"') {
368 /* skip quoted section */
369 ptr++;
370 while (*ptr != '"' && *ptr)
371 ptr++;
372 if (*ptr)
373 ptr++;
374 continue;
375 }
376 if (*ptr == '&') {
377 if (strncmp(ptr, "&end", 4) == 0)
378 return 0;
379 break;
380 }
381 ptr++;
382 }
383 if (!*ptr)
384 return 0;
385
386 /* remove the trailing &end if there is one */
387 if ((n = strlen(buffer)) >= 4) {
388 ptr = buffer + n - 4;
389 while (1) {
390 if (*ptr == '&' && (ptr == buffer || *(ptr - 1) != '\\') && strncmp(ptr, "&end", 4) == 0 && !SDDS_IsQuoted(buffer, ptr, '"')) {
391 *ptr = 0;
392 return 1;
393 }
394 if (ptr == buffer)
395 break;
396 ptr--;
397 }
398 }
399
400 /* read in the remainder of the namelist */
401 buffer0 = buffer;
402 buflen -= strlen(buffer);
403 buffer += strlen(buffer);
404 while ((flag = fgetsLZMASkipComments(SDDS_dataset, buffer, buflen, lzmafp, '!'))) {
405 n = strlen(buffer) - 1;
406 if (buffer[n] == '\n') {
407 buffer[n] = ' ';
408 if ((n - 1 >= 0) && (buffer[n - 1] == '\r'))
409 buffer[n - 1] = ' ';
410 }
411 if ((ptr = strstr(buffer, "&end")) && !SDDS_IsQuoted(buffer0, ptr, '"'))
412 return 1;
413 buflen -= strlen(buffer);
414 buffer += strlen(buffer);
415 if (buflen == 0)
416 return 0;
417 }
418 return 0;
419}
int32_t SDDS_IsQuoted(char *string, char *position, char quotation_mark)
Checks if a position in a string is within a quoted section.
Definition SDDS_input.c:218
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.

◆ SDDS_GetNamelist()

int32_t SDDS_GetNamelist ( SDDS_DATASET * SDDS_dataset,
char * buffer,
int32_t buflen,
FILE * fp )

Reads a namelist from a file into a buffer.

This function reads a namelist from the given file stream into the provided buffer, handling comments and skipping them appropriately.

Parameters
SDDS_datasetThe SDDS dataset structure.
bufferThe buffer where the namelist will be stored.
buflenThe length of the buffer.
fpThe file stream to read from.
Returns
Returns 1 if a namelist is successfully read, 0 otherwise.

Definition at line 249 of file SDDS_input.c.

249 {
250 char *ptr, *flag, *buffer0;
251 /* char *ptr1 */
252 int32_t n, i;
253 /* int32_t namelistStarted; */
254
255 while ((flag = fgetsSkipComments(SDDS_dataset, buffer, buflen, fp, '!'))) {
256 if ((ptr = strchr(buffer, '&')) && !SDDS_IsQuoted(buffer, ptr, '"'))
257 break;
258 }
259 if (!flag)
260 return 0;
261 n = strlen(buffer) - 1;
262 if (buffer[n] == '\n') {
263 buffer[n] = ' ';
264 if ((n - 1 >= 0) && (buffer[n - 1] == '\r'))
265 buffer[n - 1] = ' ';
266 }
267
268 /* check for the beginning of a namelist (an unquoted &) */
269 ptr = buffer;
270 while (*ptr) {
271 if (*ptr == '"') {
272 /* skip quoted section */
273 ptr++;
274 while (*ptr != '"' && *ptr)
275 ptr++;
276 if (*ptr)
277 ptr++;
278 continue;
279 }
280 if (*ptr == '&') {
281 if (strncmp(ptr, "&end", 4) == 0)
282 return 0;
283 break;
284 }
285 ptr++;
286 }
287 if (!*ptr)
288 return 0;
289
290 /* remove the trailing &end if there is one */
291 if ((n = strlen(buffer)) >= 4) {
292 ptr = buffer + n - 4;
293 while (1) {
294 if (*ptr == '&' && (ptr == buffer || *(ptr - 1) != '\\') && strncmp(ptr, "&end", 4) == 0 && !SDDS_IsQuoted(buffer, ptr, '"')) {
295 *ptr = 0;
296 return 1;
297 }
298 if (ptr == buffer)
299 break;
300 ptr--;
301 }
302 }
303
304 /* read in the remainder of the namelist */
305 buffer0 = buffer;
306 buflen -= strlen(buffer);
307 buffer += strlen(buffer);
308 i = 0;
309 while ((flag = fgetsSkipComments(SDDS_dataset, buffer, buflen, fp, '!'))) {
310 n = strlen(buffer) - 1;
311 if (buffer[n] == '\n') {
312 buffer[n] = ' ';
313 if ((n - 1 >= 0) && (buffer[n - 1] == '\r'))
314 buffer[n - 1] = ' ';
315 }
316 if ((ptr = strstr(buffer, "&end")) && !SDDS_IsQuoted(buffer0, ptr, '"'))
317 return 1;
318 buflen -= strlen(buffer);
319 buffer += strlen(buffer);
320 if (buflen == 0)
321 return 0;
322 /* this was needed after encountering a file that had binary crap
323 dumpted into the header. sddscheck will now report badHeader
324 instead of getting stuck in an endless loop here. */
325 i++;
326 if (i > 10000) {
327 return 0;
328 }
329 }
330 return 0;
331}
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.

◆ SDDS_GetRowLimit()

int64_t SDDS_GetRowLimit ( )

Retrieves the current row limit for the SDDS dataset.

Returns
The current row limit.

Definition at line 1259 of file SDDS_input.c.

1259 {
1260 return SDDS_GetLockedRowLimit();
1261}

◆ SDDS_GetTerminateMode()

int32_t SDDS_GetTerminateMode ( void )

Definition at line 1346 of file SDDS_input.c.

1346 {
1347 int32_t mode;
1348 mdb_thread_lock(&terminateModeLock);
1349 mode = terminateMode;
1350 mdb_thread_unlock(&terminateModeLock);
1351 return mode;
1352}
static MDB_THREAD_LOCK terminateModeLock
Global variable to set the terminate mode for the SDDS dataset.

◆ SDDS_GotoPage()

int32_t SDDS_GotoPage ( SDDS_DATASET * SDDS_dataset,
int32_t page_number )

Sets the current page of the SDDS dataset to the specified page number.

This function is used to navigate to a specific page of the SDDS dataset. It is only supported for non-zip files and does not work for pipe input.

Parameters
SDDS_datasetThe SDDS dataset to operate on.
page_numberThe page number to navigate to.
Returns
Returns 1 on success, 0 on failure.

Definition at line 1273 of file SDDS_input.c.

1273 {
1274 int64_t offset;
1275
1276 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_GotoPage"))
1277 return (0);
1278 if (SDDS_dataset->layout.disconnected) {
1279 SDDS_SetError("Can't go to page--file is disconnected (SDDS_GotoPage)");
1280 return 0;
1281 }
1282 if (SDDS_dataset->layout.popenUsed || !SDDS_dataset->layout.filename) {
1283 SDDS_SetError("Can't go to page of pipe is used (SDDS_GotoPage)");
1284 return 0;
1285 }
1286#if defined(zLib)
1287 if (SDDS_dataset->layout.gzipFile) {
1288 SDDS_SetError("Can not go to page of a gzip file (SDDS_GotoPage)");
1289 return (0);
1290 } else {
1291#endif
1292 if (SDDS_dataset->layout.lzmaFile) {
1293 SDDS_SetError("Can not go to page of an .lzma or .xz file (SDDS_GotoPage)");
1294 return (0);
1295 } else {
1296 if (!SDDS_dataset->layout.fp) {
1297 SDDS_SetError("Unable to go to page--NULL file pointer (SDDS_GotoPage)");
1298 return (0);
1299 }
1300 }
1301#if defined(zLib)
1302 }
1303#endif
1304 if (!SDDS_dataset->layout.filename) {
1305 SDDS_SetError("Can't go to page--NULL filename pointer (SDDS_GotoPage)");
1306 return 0;
1307 }
1308 if (SDDS_dataset->mode != SDDS_READMODE) {
1309 SDDS_SetError("Can't go to page--file mode has to be reading mode (SDDS_GotoPage)");
1310 return 0;
1311 }
1312 if (SDDS_dataset->fBuffer.bufferSize) {
1313 SDDS_SetError("Can't go to page--file buffering is turned on (SDDS_GotoPage)");
1314 return 0;
1315 }
1316 if (page_number < 1) {
1317 SDDS_SetError("The page_number can not be less than 1 (SDDS_GotoPage)");
1318 return (0);
1319 }
1320 if (page_number > SDDS_dataset->pages_read) {
1321 offset = SDDS_dataset->pagecount_offset[SDDS_dataset->pages_read] - ftell(SDDS_dataset->layout.fp);
1322 fseek(SDDS_dataset->layout.fp, offset, 1);
1323 SDDS_dataset->page_number = SDDS_dataset->pages_read;
1324 while (SDDS_dataset->pages_read < page_number) {
1325 if (SDDS_ReadPageSparse(SDDS_dataset, 0, SDDS_dataset->layout.data_mode.column_major ? 1 : 10000, 0, 0) <= 0) {
1326 SDDS_SetError("The page_number is greater than the total pages (SDDS_GotoPage)");
1327 return (0);
1328 }
1329 }
1330 } else {
1331 offset = SDDS_dataset->pagecount_offset[page_number - 1] - ftell(SDDS_dataset->layout.fp);
1332 fseek(SDDS_dataset->layout.fp, offset, 1); /*seek to the position from current offset */
1333 SDDS_dataset->page_number = page_number - 1;
1334 }
1335 return 1;
1336}
int32_t SDDS_ReadPageSparse(SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset, int32_t sparse_statistics)

◆ SDDS_InitializeHeaderlessInput()

int32_t SDDS_InitializeHeaderlessInput ( SDDS_DATASET * SDDS_dataset,
char * filename )

Initializes the SDDS dataset for headerless input.

This function initializes the SDDS dataset structure for reading data from a file without a header.

Parameters
SDDS_datasetA pointer to the SDDS_DATASET structure to be initialized.
filenameThe name of the file to read data from.
Returns
Returns 1 on success, 0 on failure.

Definition at line 176 of file SDDS_input.c.

176 {
177 /* char *ptr, *datafile; */
178
179 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_InitializeInput"))
180 return (0);
181 if (!SDDS_ZeroMemory((void *)SDDS_dataset, sizeof(SDDS_DATASET))) {
182 SDDS_SetError("Unable to initialize input--can't zero SDDS_DATASET structure (SDDS_InitializeInput)");
183 return (0);
184 }
185 SDDS_dataset->layout.gzipFile = SDDS_dataset->layout.lzmaFile = 0;
186 SDDS_dataset->layout.depth = SDDS_dataset->layout.data_command_seen = SDDS_dataset->layout.commentFlags = SDDS_dataset->deferSavingLayout = 0;
187 if (!(SDDS_dataset->layout.fp = fopen(filename, FOPEN_READ_MODE))) {
188 SDDS_SetError("Unable to open file (SDDS_InitializeInput)");
189 return (0);
190 }
191 if (!SDDS_CopyString(&SDDS_dataset->layout.filename, filename)) {
192 SDDS_SetError("Memory allocation failure (SDDS_InitializeInput)");
193 return (0);
194 }
195 SDDS_dataset->mode = SDDS_READMODE; /*reading */
196 SDDS_dataset->page_number = SDDS_dataset->page_started = 0;
197 SDDS_dataset->pages_read = 0;
198 SDDS_dataset->pagecount_offset = malloc(sizeof(*SDDS_dataset->pagecount_offset));
199 SDDS_dataset->pagecount_offset[0] = ftell(SDDS_dataset->layout.fp);
200 fseek(SDDS_dataset->layout.fp, 0, 2); /*point to the end of the file */
201 SDDS_dataset->endOfFile_offset = ftell(SDDS_dataset->layout.fp);
202 fseek(SDDS_dataset->layout.fp, SDDS_dataset->pagecount_offset[0], 0);
203 /*point to the beginning of the first page */
204 return (1);
205}
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:922

◆ SDDS_InitializeInput()

int32_t SDDS_InitializeInput ( SDDS_DATASET * SDDS_dataset,
char * filename )

Initializes a SDDS_DATASET structure for use in reading data from a SDDS file. This involves opening the file and reading the SDDS header.

Parameters
SDDS_datasetAddress of the SDDS_DATASET structure for the data set.
filenameA NULL-terminated character string giving the name of the file to set up for input.
Returns
1 on success. On failure, returns 0 and records an error message.

Definition at line 50 of file SDDS_input.c.

50 {
51 /* char *ptr, *datafile, *headerfile; */
52 char s[SDDS_MAXLINE];
53#if defined(zLib)
54 char *extension;
55#endif
56 if (sizeof(gzFile) != sizeof(void *)) {
57 SDDS_SetError("gzFile is not the same size as void *, possible corruption of the SDDS_LAYOUT structure");
58 return (0);
59 }
60 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_InitializeInput"))
61 return (0);
62
63 if (!SDDS_ZeroMemory((void *)SDDS_dataset, sizeof(SDDS_DATASET))) {
64 sprintf(s, "Unable to initialize input for file %s--can't zero SDDS_DATASET structure (SDDS_InitializeInput)", filename);
66 return (0);
67 }
68 SDDS_dataset->layout.gzipFile = SDDS_dataset->layout.lzmaFile = SDDS_dataset->layout.disconnected = SDDS_dataset->layout.popenUsed = 0;
69 SDDS_dataset->layout.depth = SDDS_dataset->layout.data_command_seen = SDDS_dataset->layout.commentFlags = SDDS_dataset->deferSavingLayout = 0;
70 SDDS_dataset->layout.data_mode.column_memory_mode = DEFAULT_COLUMN_MEMORY_MODE;
71 if (!filename)
72 SDDS_dataset->layout.filename = NULL;
73 else if (!SDDS_CopyString(&SDDS_dataset->layout.filename, filename)) {
74 sprintf(s, "Memory allocation failure initializing file \"%s\" (SDDS_InitializeInput)", filename);
76 return (0);
77 }
78 if (!filename) {
79#if defined(_WIN32)
80 if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
81 sprintf(s, "unable to set stdin to binary mode");
83 return 0;
84 }
85#endif
86 SDDS_dataset->layout.fp = stdin;
87 } else {
88#if defined(zLib)
89 if (!(extension = strrchr(filename, '.')) || strcmp(extension, ".gz") != 0) {
90#endif
91 if ((extension = strrchr(filename, '.')) && ((strcmp(extension, ".lzma") == 0) || (strcmp(extension, ".xz") == 0))) {
92 SDDS_dataset->layout.lzmaFile = 1;
93 if (!(SDDS_dataset->layout.lzmafp = UnpackLZMAOpen(filename))) {
94 sprintf(s, "Unable to open file \"%s\" for reading (SDDS_InitializeInput)", filename);
96 return (0);
97 }
98 SDDS_dataset->layout.fp = SDDS_dataset->layout.lzmafp->fp;
99 } else {
100 if (!(SDDS_dataset->layout.fp = UnpackFopen(filename, UNPACK_REQUIRE_SDDS | UNPACK_USE_PIPE, &SDDS_dataset->layout.popenUsed, NULL))) {
101 sprintf(s, "Unable to open file \"%s\" for reading (SDDS_InitializeInput)", filename);
102 SDDS_SetError(s);
103 return (0);
104 }
105 }
106#if defined(zLib)
107 } else {
108 SDDS_dataset->layout.gzipFile = 1;
109 if (!(SDDS_dataset->layout.gzfp = gzopen(filename, "rb"))) {
110 sprintf(s, "Unable to open file \"%s\" for reading (SDDS_InitializeInput)", filename);
111 SDDS_SetError(s);
112 return (0);
113 }
114 }
115#endif
116 }
117 SDDS_dataset->page_number = SDDS_dataset->page_started = 0;
118 SDDS_dataset->file_had_data = 0;
119 SDDS_DeferSavingLayout(SDDS_dataset, 1);
120#if defined(zLib)
121 if (SDDS_dataset->layout.gzipFile) {
122 if (!SDDS_GZipReadLayout(SDDS_dataset, SDDS_dataset->layout.gzfp))
123 return (0);
124 } else {
125#endif
126 if (SDDS_dataset->layout.lzmaFile) {
127 if (!SDDS_LZMAReadLayout(SDDS_dataset, SDDS_dataset->layout.lzmafp))
128 return (0);
129 } else {
130 if (!SDDS_ReadLayout(SDDS_dataset, SDDS_dataset->layout.fp))
131 return (0);
132 }
133#if defined(zLib)
134 }
135#endif
136 SDDS_dataset->layout.layout_written = 0;
137 SDDS_DeferSavingLayout(SDDS_dataset, 0);
138 if (!SDDS_SaveLayout(SDDS_dataset))
139 return 0;
140 if (SDDS_dataset->layout.n_columns &&
141 ((!(SDDS_dataset->column_flag = (int32_t *)SDDS_Malloc(sizeof(int32_t) * SDDS_dataset->layout.n_columns)) ||
142 !(SDDS_dataset->column_order = (int32_t *)SDDS_Malloc(sizeof(int32_t) * SDDS_dataset->layout.n_columns))) ||
143 (!SDDS_SetMemory(SDDS_dataset->column_flag, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)1, (int32_t)0) ||
144 !SDDS_SetMemory(SDDS_dataset->column_order, SDDS_dataset->layout.n_columns, SDDS_LONG, (int32_t)0, (int32_t)1)))) {
145 SDDS_SetError("Unable to initialize input--memory allocation failure (SDDS_InitializeInput)");
146 return (0);
147 }
148 SDDS_dataset->mode = SDDS_READMODE; /*reading */
149 SDDS_dataset->pagecount_offset = NULL;
150 if (!SDDS_dataset->layout.gzipFile && !SDDS_dataset->layout.lzmaFile && !SDDS_dataset->layout.popenUsed && SDDS_dataset->layout.filename) {
151 /* Data is not:
152 1. from a gzip file
153 2. from a file that is being internally decompressed by a command executed with popen()
154 3. from a pipe set up externally (e.g., -pipe=in on commandline)
155 */
156 SDDS_dataset->pages_read = 0;
157 SDDS_dataset->pagecount_offset = malloc(sizeof(*SDDS_dataset->pagecount_offset));
158 SDDS_dataset->pagecount_offset[0] = ftell(SDDS_dataset->layout.fp);
159 fseek(SDDS_dataset->layout.fp, 0, 2); /*point to the end of the file */
160 SDDS_dataset->endOfFile_offset = ftell(SDDS_dataset->layout.fp);
161 fseek(SDDS_dataset->layout.fp, SDDS_dataset->pagecount_offset[0], 0);
162 /*point to the beginning of the first page */
163 }
164 return (1);
165}
void SDDS_DeferSavingLayout(SDDS_DATASET *SDDS_dataset, int32_t mode)
Definition SDDS_copy.c:603
int32_t SDDS_SaveLayout(SDDS_DATASET *SDDS_dataset)
Definition SDDS_copy.c:615
int32_t SDDS_ReadLayout(SDDS_DATASET *SDDS_dataset, FILE *fp)
Definition SDDS_input.c:518
int32_t SDDS_LZMAReadLayout(SDDS_DATASET *SDDS_dataset, struct lzmafile *lzmafp)
Definition SDDS_input.c:681
int32_t SDDS_SetMemory(void *mem, int64_t n_elements, int32_t data_type,...)
Initializes a memory block with a sequence of values based on a specified data type.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:705
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
FILE * UnpackFopen(char *filename, unsigned long mode, short *popenUsed, char **tmpFileUsed)
Opens a file, potentially unpacking it based on its extension and mode.
Definition unpack.c:89

◆ SDDS_InitializeInputFromSearchPath()

int32_t SDDS_InitializeInputFromSearchPath ( SDDS_DATASET * SDDSin,
char * file )

Initializes the SDDS_DATASET structure for input from the search path.

The search path is defined by calling setSearchPath. This function attempts to find the file in the search path and initializes the SDDS dataset for input.

Parameters
SDDSinThe SDDS_DATASET structure to be initialized.
fileThe name of the file to be opened for input.
Returns
1 on success, 0 on failure.

Definition at line 1811 of file SDDS_input.c.

1811 {
1812 char *filename;
1813 int32_t value;
1814 if (!(filename = findFileInSearchPath(file))) {
1815 char *s;
1816 if (!(s = SDDS_Malloc(sizeof(*s) * (strlen(file) + 100))))
1817 SDDS_SetError("file does not exist in search path (InitializeInputFromSearchPath)");
1818 else {
1819 sprintf(s, "file %s does not exist in search path (InitializeInputFromSearchPath)", file);
1820 SDDS_SetError(s);
1821 free(s);
1822 }
1823 return 0;
1824 }
1825 value = SDDS_InitializeInput(SDDSin, filename);
1826 free(filename);
1827 return value;
1828}
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
char * findFileInSearchPath(const char *filename)
Finds a file within the configured search path.
Definition searchPath.c:57

◆ SDDS_IsQuoted()

int32_t SDDS_IsQuoted ( char * string,
char * position,
char quotation_mark )

Checks if a position in a string is within a quoted section.

Determines whether the specified position within a string falls inside a quoted section delimited by the given quotation mark.

Parameters
stringThe string to examine.
positionThe position within the string to check.
quotation_markThe character used as the quotation mark.
Returns
Returns 1 if the position is within a quoted section, 0 otherwise.

Definition at line 218 of file SDDS_input.c.

218 {
219 int32_t in_quoted_section;
220 char *string0;
221
222 if (*position == quotation_mark)
223 return (1);
224
225 in_quoted_section = 0;
226 string0 = string;
227 while (*string) {
228 if (*string == quotation_mark && (string == string0 || *(string - 1) != '\\'))
229 in_quoted_section = !in_quoted_section;
230 else if (string == position)
231 return (in_quoted_section);
232 string++;
233 }
234 return (0);
235}

◆ SDDS_LZMAReadLayout()

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

Reads the header layout of an SDDS dataset from a file with LZMA compression.

Parameters
SDDS_datasetThe SDDS dataset structure to store the layout information.
lzmafpThe LZMA file pointer to the SDDS file.
Returns
Returns 1 on success, 0 on failure.

Definition at line 681 of file SDDS_input.c.

681 {
682 char buffer[SDDS_MAXLINE];
683 char *groupName, *ptr;
684 FILE *fp1;
685 int32_t retval, bigEndianMachine;
686 uint32_t commentFlags;
687
688 if (!lzmafp) {
689 SDDS_SetError("Unable to read layout--NULL file pointer (SDDS_LZMAReadLayout)");
690 return (0);
691 }
692 if (SDDS_dataset->layout.depth == 0) {
693 if (SDDS_dataset->layout.disconnected) {
694 SDDS_SetError("Can't read layout--file is disconnected (SDDS_LZMAReadLayout)");
695 return 0;
696 }
697 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_LZMAReadLayout")) {
698 lzma_close(lzmafp);
699 return (0);
700 }
701 SDDS_dataset->layout.layout_written = 1; /* it is already in the file */
702 if (!lzma_gets(SDDS_dataset->layout.s, SDDS_MAXLINE, lzmafp)) {
703 lzma_close(lzmafp);
704 SDDS_SetError("Unable to read layout--no header lines found (SDDS_LZMAReadLayout)");
705 return (0);
706 }
707 if (strncmp(SDDS_dataset->layout.s, "SDDS", 4) != 0) {
708 lzma_close(lzmafp);
709 SDDS_SetError("Unable to read layout--no header lines found (SDDS_LZMAReadLayout)");
710 return (0);
711 }
712 if (sscanf(SDDS_dataset->layout.s + 4, "%" SCNd32, &SDDS_dataset->layout.version) != 1) {
713 lzma_close(lzmafp);
714 SDDS_SetError("Unable to read layout--no version number on first line (SDDS_LZMAReadLayout)");
715 return (0);
716 }
717 SDDS_ResetSpecialCommentsModes(SDDS_dataset);
718 SDDS_dataset->layout.data_command_seen = 0;
719 }
720 while (SDDS_GetLZMANamelist(SDDS_dataset, SDDS_dataset->layout.s, SDDS_MAXLINE, lzmafp)) {
721#if DEBUG
722 strcpy(buffer, SDDS_dataset->layout.s);
723#endif
724 groupName = SDDS_dataset->layout.s + 1;
725 if (!(ptr = strpbrk(SDDS_dataset->layout.s, " \t"))) {
726 SDDS_SetError("Unable to read layout---no groupname in namelist (SDDS_LZMAReadLayout)");
727 return 0;
728 }
729 *ptr = 0;
730 switch (match_string(groupName, SDDS_command, SDDS_NUM_COMMANDS, EXACT_MATCH)) {
731 case SDDS_DESCRIPTION_COMMAND:
732 if (!SDDS_ProcessDescription(SDDS_dataset, ptr + 1)) {
733 lzma_close(lzmafp);
734 SDDS_SetError("Unable to process description (SDDS_LZMAReadLayout)");
735 return (0);
736 }
737 break;
738 case SDDS_COLUMN_COMMAND:
739 if (!SDDS_ProcessColumnDefinition(SDDS_dataset, ptr + 1)) {
740 lzma_close(lzmafp);
741 SDDS_SetError("Unable to process column definition (SDDS_LZMAReadLayout)");
742 return (0);
743 }
744 break;
745 case SDDS_PARAMETER_COMMAND:
746 if (!SDDS_ProcessParameterDefinition(SDDS_dataset, ptr + 1)) {
747 lzma_close(lzmafp);
748 SDDS_SetError("Unable to process parameter definition (SDDS_LZMAReadLayout)");
749 return (0);
750 }
751 break;
752 case SDDS_ASSOCIATE_COMMAND:
753#if RW_ASSOCIATES != 0
754 if (!SDDS_ProcessAssociateDefinition(SDDS_dataset, ptr + 1)) {
755 lzma_close(lzmafp);
756 SDDS_SetError("Unable to process associate definition (SDDS_LZMAReadLayout)");
757 return (0);
758 }
759#endif
760 break;
761 case SDDS_DATA_COMMAND:
762 if (!SDDS_ProcessDataMode(SDDS_dataset, ptr + 1)) {
763 lzma_close(lzmafp);
764 SDDS_SetError("Unable to process data mode (SDDS_LZMAReadLayout)");
765 return (0);
766 }
767 if (SDDS_dataset->layout.data_command_seen) {
768 /* should never happen */
769 lzma_close(lzmafp);
770 SDDS_SetError("Unable to read layout--multiple data commands (SDDS_LZMAReadLayout)");
771 return (0);
772 }
773 if (!SDDS_SaveLayout(SDDS_dataset)) {
774 SDDS_SetError("Unable to read layout--couldn't save layout (SDDS_LZMAReadLayout)");
775 return (0);
776 }
777 SDDS_dataset->layout.data_command_seen = 1;
778 commentFlags = SDDS_GetSpecialCommentsModes(SDDS_dataset);
779 if ((commentFlags & SDDS_BIGENDIAN_SEEN) && (commentFlags & SDDS_LITTLEENDIAN_SEEN)) {
780 SDDS_SetError("Unable to read data as it says it is both big and little endian (SDDS_LZMAReadLayout)");
781 return (0);
782 }
783 bigEndianMachine = SDDS_IsBigEndianMachine();
784 SDDS_dataset->swapByteOrder = SDDS_dataset->layout.byteOrderDeclared = 0;
785 SDDS_dataset->autoRecover = 0;
786 if ((commentFlags & SDDS_BIGENDIAN_SEEN) || (SDDS_dataset->layout.data_mode.endian == SDDS_BIGENDIAN)) {
787 SDDS_dataset->layout.byteOrderDeclared = SDDS_BIGENDIAN_SEEN;
788 if (!bigEndianMachine)
789 SDDS_dataset->swapByteOrder = 1;
790 }
791 if ((commentFlags & SDDS_LITTLEENDIAN_SEEN) || (SDDS_dataset->layout.data_mode.endian == SDDS_LITTLEENDIAN)) {
792 SDDS_dataset->layout.byteOrderDeclared = SDDS_LITTLEENDIAN_SEEN;
793 if (bigEndianMachine)
794 SDDS_dataset->swapByteOrder = 1;
795 }
796 if ((commentFlags & SDDS_FIXED_ROWCOUNT_SEEN) || (SDDS_dataset->layout.data_mode.fixed_row_count))
797 if (!SDDS_SetAutoReadRecovery(SDDS_dataset, SDDS_AUTOREADRECOVER))
798 return (0);
799 return (1);
800 case SDDS_INCLUDE_COMMAND:
801 if (!(fp1 = SDDS_ProcessIncludeCommand(SDDS_dataset, ptr + 1))) {
802 lzma_close(lzmafp);
803 SDDS_SetError("Unable to process include command (SDDS_LZMAReadLayout)");
804 return (0);
805 }
806 SDDS_dataset->layout.depth += 1;
807 retval = SDDS_ReadLayout(SDDS_dataset, fp1);
808 SDDS_dataset->layout.depth -= 1;
809 fclose(fp1);
810 if (retval == 0) {
811 return (0);
812 }
813 if (SDDS_dataset->layout.data_command_seen) {
814 return (1);
815 }
816 break;
817 case SDDS_ARRAY_COMMAND:
818 if (!SDDS_ProcessArrayDefinition(SDDS_dataset, ptr + 1)) {
819 lzma_close(lzmafp);
820 SDDS_SetError("Unable to process array definition (SDDS_LZMAReadLayout)");
821 return (0);
822 }
823 break;
824 default:
825 lzma_close(lzmafp);
826 sprintf(buffer, "Unknown layout entry %s given (SDDS_LZMAReadLayout)", groupName);
827 SDDS_SetError(buffer);
828 return (0);
829 }
830 }
831 /* on recursive calls, it's okay to hit EOF */
832 if ((lzma_eof(lzmafp) && SDDS_dataset->layout.depth != 0) || SDDS_dataset->layout.data_command_seen)
833 return (1);
834 return (0);
835}
char * SDDS_command[SDDS_NUM_COMMANDS]
Array of supported SDDS command names.
Definition SDDS_data.c:81
int32_t SDDS_SetAutoReadRecovery(SDDS_DATASET *SDDS_dataset, uint32_t mode)
int32_t SDDS_GetLZMANamelist(SDDS_DATASET *SDDS_dataset, char *buffer, int32_t buflen, struct lzmafile *lzmafp)
Reads a namelist from an LZMA-compressed file into a buffer.
Definition SDDS_input.c:345
int32_t SDDS_ProcessArrayDefinition(SDDS_DATASET *SDDS_dataset, char *s)
Process the array definition section of the SDDS dataset.
int32_t SDDS_ProcessParameterDefinition(SDDS_DATASET *SDDS_dataset, char *s)
Process the parameter definition section of the SDDS dataset.
int32_t SDDS_ProcessAssociateDefinition(SDDS_DATASET *SDDS_dataset, char *s)
Process the associate definition section of the SDDS dataset.
FILE * SDDS_ProcessIncludeCommand(SDDS_DATASET *SDDS_dataset, char *s)
Process the include command within the SDDS dataset.
int32_t SDDS_ProcessDataMode(SDDS_DATASET *SDDS_dataset, char *s)
Process the data mode section of the SDDS dataset.
uint32_t SDDS_GetSpecialCommentsModes(SDDS_DATASET *SDDS_dataset)
Retrieves the current special comments modes set in the SDDS dataset.
int32_t SDDS_ProcessDescription(SDDS_DATASET *SDDS_dataset, char *s)
Process the description section of the SDDS dataset.
void SDDS_ResetSpecialCommentsModes(SDDS_DATASET *SDDS_dataset)
Resets the special comments modes in the SDDS dataset.
int32_t SDDS_ProcessColumnDefinition(SDDS_DATASET *SDDS_dataset, char *s)
Process the column definition section of the SDDS dataset.
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.

◆ SDDS_ReadLayout()

int32_t SDDS_ReadLayout ( SDDS_DATASET * SDDS_dataset,
FILE * fp )

Reads the header layout of an SDDS dataset from a file.

Parameters
SDDS_datasetThe SDDS dataset structure to store the layout information.
fpThe file pointer to the SDDS file.
Returns
Returns 1 on success, 0 on failure.

Definition at line 518 of file SDDS_input.c.

518 {
519 char buffer[SDDS_MAXLINE];
520 char *groupName, *ptr;
521 FILE *fp1;
522 int32_t retval, bigEndianMachine;
523 uint32_t commentFlags;
524
525 if (!fp) {
526 SDDS_SetError("Unable to read layout--NULL file pointer (SDDS_ReadLayout)");
527 return (0);
528 }
529 if (SDDS_dataset->layout.depth == 0) {
530 if (SDDS_dataset->layout.disconnected) {
531 SDDS_SetError("Can't read layout--file is disconnected (SDDS_ReadLayout)");
532 return 0;
533 }
534 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadLayout")) {
535 fclose(fp);
536 return (0);
537 }
538 SDDS_dataset->layout.layout_written = 1; /* it is already in the file */
539 if (!fgets(SDDS_dataset->layout.s, SDDS_MAXLINE, fp)) {
540 fclose(fp);
541 SDDS_SetError("Unable to read layout--no header lines found (SDDS_ReadLayout)");
542 return (0);
543 }
544 if (strncmp(SDDS_dataset->layout.s, "SDDS", 4) != 0) {
545 fclose(fp);
546 SDDS_SetError("Unable to read layout--no header lines found (SDDS_ReadLayout)");
547 return (0);
548 }
549 if (sscanf(SDDS_dataset->layout.s + 4, "%" SCNd32, &SDDS_dataset->layout.version) != 1) {
550 fclose(fp);
551 SDDS_SetError("Unable to read layout--no version number on first line (SDDS_ReadLayout)");
552 return (0);
553 }
554 SDDS_ResetSpecialCommentsModes(SDDS_dataset);
555 SDDS_dataset->layout.data_command_seen = 0;
556 }
557 while (SDDS_GetNamelist(SDDS_dataset, SDDS_dataset->layout.s, SDDS_MAXLINE, fp)) {
558#if DEBUG
559 strcpy(buffer, SDDS_dataset->layout.s);
560#endif
561 groupName = SDDS_dataset->layout.s + 1;
562 if (!(ptr = strpbrk(SDDS_dataset->layout.s, " \t"))) {
563 SDDS_SetError("Unable to read layout---no groupname in namelist (SDDS_ReadLayout)");
564 return 0;
565 }
566 *ptr = 0;
567 switch (match_string(groupName, SDDS_command, SDDS_NUM_COMMANDS, EXACT_MATCH)) {
568 case SDDS_DESCRIPTION_COMMAND:
569 if (!SDDS_ProcessDescription(SDDS_dataset, ptr + 1)) {
570 fclose(fp);
571 SDDS_SetError("Unable to process description (SDDS_ReadLayout)");
572 return (0);
573 }
574 break;
575 case SDDS_COLUMN_COMMAND:
576 if (!SDDS_ProcessColumnDefinition(SDDS_dataset, ptr + 1)) {
577 fclose(fp);
578 SDDS_SetError("Unable to process column definition (SDDS_ReadLayout)");
579 return (0);
580 }
581 break;
582 case SDDS_PARAMETER_COMMAND:
583 if (!SDDS_ProcessParameterDefinition(SDDS_dataset, ptr + 1)) {
584 fclose(fp);
585 SDDS_SetError("Unable to process parameter definition (SDDS_ReadLayout)");
586 return (0);
587 }
588 break;
589 case SDDS_ASSOCIATE_COMMAND:
590#if RW_ASSOCIATES != 0
591 if (!SDDS_ProcessAssociateDefinition(SDDS_dataset, ptr + 1)) {
592 fclose(fp);
593 SDDS_SetError("Unable to process associate definition (SDDS_ReadLayout)");
594 return (0);
595 }
596#endif
597 break;
598 case SDDS_DATA_COMMAND:
599 if (!SDDS_ProcessDataMode(SDDS_dataset, ptr + 1)) {
600 fclose(fp);
601 SDDS_SetError("Unable to process data mode (SDDS_ReadLayout)");
602 return (0);
603 }
604 if (SDDS_dataset->layout.data_command_seen) {
605 /* should never happen */
606 fclose(fp);
607 SDDS_SetError("Unable to read layout--multiple data commands (SDDS_ReadLayout)");
608 return (0);
609 }
610 if (!SDDS_SaveLayout(SDDS_dataset)) {
611 SDDS_SetError("Unable to read layout--couldn't save layout (SDDS_ReadLayout)");
612 return (0);
613 }
614 SDDS_dataset->layout.data_command_seen = 1;
615 commentFlags = SDDS_GetSpecialCommentsModes(SDDS_dataset);
616 if ((commentFlags & SDDS_BIGENDIAN_SEEN) && (commentFlags & SDDS_LITTLEENDIAN_SEEN)) {
617 SDDS_SetError("Unable to read data as it says it is both big and little endian (SDDS_ReadLayout)");
618 return (0);
619 }
620 bigEndianMachine = SDDS_IsBigEndianMachine();
621 SDDS_dataset->swapByteOrder = SDDS_dataset->layout.byteOrderDeclared = 0;
622 SDDS_dataset->autoRecover = 0;
623 if ((commentFlags & SDDS_BIGENDIAN_SEEN) || (SDDS_dataset->layout.data_mode.endian == SDDS_BIGENDIAN)) {
624 SDDS_dataset->layout.byteOrderDeclared = SDDS_BIGENDIAN_SEEN;
625 if (!bigEndianMachine)
626 SDDS_dataset->swapByteOrder = 1;
627 }
628 if ((commentFlags & SDDS_LITTLEENDIAN_SEEN) || (SDDS_dataset->layout.data_mode.endian == SDDS_LITTLEENDIAN)) {
629 SDDS_dataset->layout.byteOrderDeclared = SDDS_LITTLEENDIAN_SEEN;
630 if (bigEndianMachine)
631 SDDS_dataset->swapByteOrder = 1;
632 }
633 if ((commentFlags & SDDS_FIXED_ROWCOUNT_SEEN) || (SDDS_dataset->layout.data_mode.fixed_row_count))
634 if (!SDDS_SetAutoReadRecovery(SDDS_dataset, SDDS_AUTOREADRECOVER))
635 return (0);
636 return (1);
637 case SDDS_INCLUDE_COMMAND:
638 if (!(fp1 = SDDS_ProcessIncludeCommand(SDDS_dataset, ptr + 1))) {
639 fclose(fp);
640 SDDS_SetError("Unable to process include command (SDDS_ReadLayout)");
641 return (0);
642 }
643 SDDS_dataset->layout.depth += 1;
644 retval = SDDS_ReadLayout(SDDS_dataset, fp1);
645 SDDS_dataset->layout.depth -= 1;
646 fclose(fp1);
647 if (retval == 0) {
648 return (0);
649 }
650 if (SDDS_dataset->layout.data_command_seen) {
651 return (1);
652 }
653 break;
654 case SDDS_ARRAY_COMMAND:
655 if (!SDDS_ProcessArrayDefinition(SDDS_dataset, ptr + 1)) {
656 fclose(fp);
657 SDDS_SetError("Unable to process array definition (SDDS_ReadLayout)");
658 return (0);
659 }
660 break;
661 default:
662 fclose(fp);
663 sprintf(buffer, "Unknown layout entry %s given (SDDS_ReadLayout)", groupName);
664 SDDS_SetError(buffer);
665 return (0);
666 }
667 }
668 /* on recursive calls, it's okay to hit EOF */
669 if ((feof(fp) && SDDS_dataset->layout.depth != 0) || SDDS_dataset->layout.data_command_seen)
670 return (1);
671 return (0);
672}
int32_t SDDS_GetNamelist(SDDS_DATASET *SDDS_dataset, char *buffer, int32_t buflen, FILE *fp)
Reads a namelist from a file into a buffer.
Definition SDDS_input.c:249

◆ SDDS_ReadPage()

int32_t SDDS_ReadPage ( SDDS_DATASET * SDDS_dataset)

Reads a page of an SDDS file. Usually called after SDDS_InitializeInput.

Parameters
SDDS_datasetAddress of the SDDS_DATASET structure for the data set.
Returns
Page number on success, -1 if it is the end-of-file, 0 on error.

Definition at line 1007 of file SDDS_input.c.

1007 {
1008#if SDDS_MPI_IO
1009 if (SDDS_dataset->parallel_io)
1010 return SDDS_MPI_ReadPage(SDDS_dataset);
1011#endif
1012 return SDDS_ReadPageSparse(SDDS_dataset, 0, 1, 0, 0);
1013}
int32_t SDDS_MPI_ReadPage(SDDS_DATASET *SDDS_dataset)
Reads a page from an SDDS dataset using MPI.

◆ SDDS_ReadPageLastRows()

int32_t SDDS_ReadPageLastRows ( SDDS_DATASET * SDDS_dataset,
int64_t last_rows )

Reads the last specified number of rows from the SDDS dataset.

Parameters
SDDS_datasetThe pointer to the SDDS dataset structure.
last_rowsThe number of rows to read from the end of the dataset.
Returns
Page number on success, -1 if it is the end-of-file, 0 on error.

Definition at line 1157 of file SDDS_input.c.

1157 {
1158 int32_t retval;
1159
1160 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadPageLastRows"))
1161 return (0);
1162 if (SDDS_dataset->layout.disconnected) {
1163 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadPageLastRows)");
1164 return 0;
1165 }
1166#if defined(zLib)
1167 if (SDDS_dataset->layout.gzipFile) {
1168 if (!SDDS_dataset->layout.gzfp) {
1169 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageLastRows)");
1170 return (0);
1171 }
1172 } else {
1173#endif
1174 if (SDDS_dataset->layout.lzmaFile) {
1175 if (!SDDS_dataset->layout.lzmafp) {
1176 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageLastRows)");
1177 return (0);
1178 }
1179 } else {
1180 if (!SDDS_dataset->layout.fp) {
1181 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageLastRows)");
1182 return (0);
1183 }
1184 }
1185#if defined(zLib)
1186 }
1187#endif
1188 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
1189 if ((retval = SDDS_ReadAsciiPageLastRows(SDDS_dataset, last_rows)) < 1) {
1190 return (retval);
1191 }
1192 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
1193 if ((retval = SDDS_ReadBinaryPageLastRows(SDDS_dataset, last_rows)) < 1) {
1194 return (retval);
1195 }
1196 } else {
1197 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadPageLastRows)");
1198 return (0);
1199 }
1200 if (!SDDS_dataset->layout.gzipFile && !SDDS_dataset->layout.lzmaFile && !SDDS_dataset->layout.popenUsed && SDDS_dataset->layout.filename && SDDS_dataset->pagecount_offset) {
1201 /* Data is not:
1202 1. from a gzip file
1203 2. from a file that is being internally decompressed by a command executed with popen()
1204 3. from a pipe set up externally (e.g., -pipe=in on commandline)
1205 and pagecount_offset has been allocate memory from SDDS_initializeInput()
1206 */
1207 if (SDDS_dataset->pagecount_offset[SDDS_dataset->pages_read] < SDDS_dataset->endOfFile_offset) {
1208 SDDS_dataset->pages_read++;
1209 if (!(SDDS_dataset->pagecount_offset = realloc(SDDS_dataset->pagecount_offset, sizeof(int64_t) * (SDDS_dataset->pages_read + 1)))) {
1210 SDDS_SetError("Unable to allocate memory for pagecount_offset (SDDS_ReadPageLastRows)");
1211 exit(1);
1212 }
1213 SDDS_dataset->pagecount_offset[SDDS_dataset->pages_read] = ftell(SDDS_dataset->layout.fp);
1214 }
1215 } else {
1216 SDDS_dataset->pages_read++;
1217 }
1218 return (retval);
1219}
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_ReadBinaryPageLastRows(SDDS_DATASET *SDDS_dataset, int64_t last_rows)
Reads the last specified number of rows from a binary page of an SDDS dataset.

◆ SDDS_ReadPageSparse()

int32_t SDDS_ReadPageSparse ( SDDS_DATASET * SDDS_dataset,
uint32_t mode,
int64_t sparse_interval,
int64_t sparse_offset,
int32_t sparse_statistics )

Reads a sparsed page of an SDDS file. Usually called after SDDS_InitializeInput.

Parameters
SDDS_datasetA pointer to an SDDS dataset.
modeNot used.
sparse_intervalThe column data can be sparsified over row intervals if this is greater than 1.
sparse_offsetThis is used to skip the initial rows of the column data.
sparse_statisticsNot used.
Returns
Page number on success, -1 if it is the end-of-file, 0 on error.

Definition at line 1083 of file SDDS_input.c.

1085{
1086 int32_t retval;
1087 /* SDDS_LAYOUT layout_copy; */
1088
1089 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadPageSparse"))
1090 return (0);
1091 if (SDDS_dataset->layout.disconnected) {
1092 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadPageSparse)");
1093 return 0;
1094 }
1095#if defined(zLib)
1096 if (SDDS_dataset->layout.gzipFile) {
1097 if (!SDDS_dataset->layout.gzfp) {
1098 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageSparse)");
1099 return (0);
1100 }
1101 } else {
1102#endif
1103 if (SDDS_dataset->layout.lzmaFile) {
1104 if (!SDDS_dataset->layout.lzmafp) {
1105 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageSparse)");
1106 return (0);
1107 }
1108 } else {
1109 if (!SDDS_dataset->layout.fp) {
1110 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadPageSparse)");
1111 return (0);
1112 }
1113 }
1114#if defined(zLib)
1115 }
1116#endif
1117 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
1118 if ((retval = SDDS_ReadAsciiPage(SDDS_dataset, sparse_interval, sparse_offset, sparse_statistics)) < 1) {
1119 return (retval);
1120 }
1121 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
1122 if ((retval = SDDS_ReadBinaryPage(SDDS_dataset, sparse_interval, sparse_offset, sparse_statistics)) < 1) {
1123 return (retval);
1124 }
1125 } else {
1126 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadPageSparse)");
1127 return (0);
1128 }
1129 if (!SDDS_dataset->layout.gzipFile && !SDDS_dataset->layout.lzmaFile && !SDDS_dataset->layout.popenUsed && SDDS_dataset->layout.filename && SDDS_dataset->pagecount_offset) {
1130 /* Data is not:
1131 1. from a gzip file
1132 2. from a file that is being internally decompressed by a command executed with popen()
1133 3. from a pipe set up externally (e.g., -pipe=in on commandline)
1134 and pagecount_offset has been allocate memory from SDDS_initializeInput()
1135 */
1136 if (SDDS_dataset->pagecount_offset[SDDS_dataset->pages_read] < SDDS_dataset->endOfFile_offset) {
1137 SDDS_dataset->pages_read++;
1138 if (!(SDDS_dataset->pagecount_offset = realloc(SDDS_dataset->pagecount_offset, sizeof(int64_t) * (SDDS_dataset->pages_read + 1)))) {
1139 SDDS_SetError("Unable to allocate memory for pagecount_offset (SDDS_ReadPageSparse)");
1140 exit(1);
1141 }
1142 SDDS_dataset->pagecount_offset[SDDS_dataset->pages_read] = ftell(SDDS_dataset->layout.fp);
1143 }
1144 } else {
1145 SDDS_dataset->pages_read++;
1146 }
1147 return (retval);
1148}
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_ReadBinaryPage(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int32_t sparse_statistics)
Reads a binary page from an SDDS dataset.

◆ SDDS_SetAutoReadRecovery()

int32_t SDDS_SetAutoReadRecovery ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Sets the auto-read recovery mode for the SDDS dataset.

Parameters
SDDS_datasetThe SDDS dataset to modify.
modeThe mode to set (SDDS_AUTOREADRECOVER or SDDS_NOAUTOREADRECOVER).
Returns
1 on success, 0 on error.

Definition at line 1787 of file SDDS_input.c.

1787 {
1788 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_SetAutoReadRecovery"))
1789 return 0;
1790 if (mode & SDDS_AUTOREADRECOVER) {
1791 SDDS_dataset->autoRecover = 1;
1792 } else if (mode & SDDS_NOAUTOREADRECOVER) {
1793 SDDS_dataset->autoRecover = 0;
1794 } else {
1795 SDDS_SetError("Invalid Auto Read Recovery mode (SDDS_SetAutoReadRecovery).");
1796 return 0;
1797 }
1798 return 1;
1799}

◆ SDDS_SetColumnMemoryMode()

void SDDS_SetColumnMemoryMode ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Sets the column memory mode for the SDDS dataset.

Parameters
SDDS_datasetThe SDDS dataset to operate on.
modeThe column memory mode to set.

Definition at line 1371 of file SDDS_input.c.

1371 {
1372 SDDS_dataset->layout.data_mode.column_memory_mode = mode;
1373}

◆ SDDS_SetRowLimit()

int64_t SDDS_SetRowLimit ( int64_t limit)

Sets the row limit for the SDDS dataset.

Parameters
limitThe maximum number of rows to read. If limit <= 0, the row limit is set to INT64_MAX.
Returns
The previous row limit value.

Definition at line 1243 of file SDDS_input.c.

1243 {
1244 int64_t previous;
1245 if (limit <= 0)
1246 limit = INT64_MAX;
1247 mdb_thread_lock(&SDDS_RowLimitLock);
1248 previous = SDDS_RowLimit;
1249 SDDS_RowLimit = limit;
1250 mdb_thread_unlock(&SDDS_RowLimitLock);
1251 return previous;
1252}

◆ SDDS_SetTerminateMode()

void SDDS_SetTerminateMode ( uint32_t mode)

Sets the terminate mode for the SDDS dataset.

Parameters
modeThe terminate mode to set.

Definition at line 1359 of file SDDS_input.c.

1359 {
1360 mdb_thread_lock(&terminateModeLock);
1361 terminateMode = mode;
1362 mdb_thread_unlock(&terminateModeLock);
1363}

◆ SDDS_Terminate()

int32_t SDDS_Terminate ( SDDS_DATASET * SDDS_dataset)

Closes an SDDS file and frees the related memory.

Parameters
SDDS_datasetA pointer to an SDDS dataset.
Returns
1 on success, 0 on error.

Definition at line 1471 of file SDDS_input.c.

1471 {
1472 SDDS_LAYOUT *layout;
1473 char **ptr;
1474 int64_t i, j;
1475 FILE *fp;
1476 char termBuffer[16384];
1477 int32_t terminateMode;
1478#if SDDS_MPI_IO
1479 if (SDDS_dataset->parallel_io)
1480 return SDDS_MPI_Terminate(SDDS_dataset);
1481#endif
1482 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_Terminate"))
1483 return (0);
1484 layout = &SDDS_dataset->original_layout;
1485 terminateMode = SDDS_GetTerminateMode();
1486
1487 fp = SDDS_dataset->layout.fp;
1488#if defined(zLib)
1489 if (SDDS_dataset->layout.gzipFile) {
1490 if (SDDS_dataset->layout.gzfp && layout->filename) {
1491 if ((SDDS_dataset->writing_page) && (SDDS_dataset->layout.data_mode.fixed_row_count)) {
1492 if (!SDDS_UpdateRowCount(SDDS_dataset))
1493 return (0);
1494 }
1495 gzclose(SDDS_dataset->layout.gzfp);
1496 }
1497 } else {
1498#endif
1499 if (SDDS_dataset->layout.lzmaFile) {
1500 if (SDDS_dataset->layout.lzmafp && layout->filename) {
1501 if ((SDDS_dataset->writing_page) && (SDDS_dataset->layout.data_mode.fixed_row_count)) {
1502 if (!SDDS_UpdateRowCount(SDDS_dataset))
1503 return (0);
1504 }
1505 lzma_close(SDDS_dataset->layout.lzmafp);
1506 }
1507 } else {
1508 if (fp && layout->filename) {
1509 if ((SDDS_dataset->writing_page) && (SDDS_dataset->layout.data_mode.fixed_row_count)) {
1510 if (!SDDS_UpdateRowCount(SDDS_dataset))
1511 return (0);
1512 }
1513 if (layout->popenUsed) {
1514 while (fread(termBuffer, sizeof(*termBuffer), 16384, fp)) {
1515 }
1516#if defined(vxWorks)
1517 fprintf(stderr, "pclose is not supported in vxWorks\n");
1518 exit(1);
1519#else
1520 pclose(fp);
1521#endif
1522 } else {
1523 fclose(fp);
1524 }
1525 }
1526 }
1527#if defined(zLib)
1528 }
1529#endif
1530
1531#if DEBUG
1532 fprintf(stderr, "Freeing data for file %s\n", SDDS_dataset->layout.filename ? SDDS_dataset->layout.filename : "NULL");
1533#endif
1534
1535 if (SDDS_dataset->pagecount_offset)
1536 free(SDDS_dataset->pagecount_offset);
1537 if (SDDS_dataset->row_flag)
1538 free(SDDS_dataset->row_flag);
1539 if (SDDS_dataset->column_order)
1540 free(SDDS_dataset->column_order);
1541 if (SDDS_dataset->column_flag)
1542 free(SDDS_dataset->column_flag);
1543 if (SDDS_dataset->fBuffer.buffer)
1544 free(SDDS_dataset->fBuffer.buffer);
1545#if DEBUG
1546 fprintf(stderr, "freeing parameter data...\n");
1547#endif
1548 if (SDDS_dataset->parameter) {
1549 for (i = 0; i < layout->n_parameters; i++) {
1550 if (layout->parameter_definition[i].type == SDDS_STRING && *(char **)(SDDS_dataset->parameter[i]))
1551 free(*(char **)(SDDS_dataset->parameter[i]));
1552 if (SDDS_dataset->parameter[i])
1553 free(SDDS_dataset->parameter[i]);
1554 }
1555 free(SDDS_dataset->parameter);
1556 }
1557#if DEBUG
1558 fprintf(stderr, "freeing array data...\n");
1559#endif
1560 if (SDDS_dataset->array) {
1561 for (i = 0; i < layout->n_arrays; i++) {
1562 if (layout->array_definition[i].type == SDDS_STRING && !(terminateMode & TERMINATE_DONT_FREE_ARRAY_STRINGS)) {
1563 for (j = 0; j < SDDS_dataset->array[i].elements; j++)
1564 if (((char **)SDDS_dataset->array[i].data)[j])
1565 free(((char **)SDDS_dataset->array[i].data)[j]);
1566 }
1567 /*
1568 if (SDDS_dataset->array[i].definition->type==SDDS_STRING &&
1569 !(SDDS_GetTerminateMode()&TERMINATE_DONT_FREE_ARRAY_STRINGS)) {
1570 for (j=0; j<SDDS_dataset->array[i].elements; j++)
1571 if (((char**)SDDS_dataset->array[i].data)[j])
1572 free(((char**)SDDS_dataset->array[i].data)[j]);
1573 }
1574 */
1575 if (SDDS_dataset->array[i].data)
1576 free(SDDS_dataset->array[i].data);
1577 /* should free the subpointers too, but it would be a lot of trouble for little benefit: */
1578 if (SDDS_dataset->array[i].pointer && SDDS_dataset->array[i].definition->dimensions != 1)
1579 free(SDDS_dataset->array[i].pointer);
1580 if (SDDS_dataset->array[i].dimension)
1581 free(SDDS_dataset->array[i].dimension);
1582 /* don't touch this--it's done below */
1583 if (SDDS_dataset->array[i].definition && SDDS_dataset->array[i].definition->name) {
1584 if (SDDS_dataset->array[i].definition->name != layout->array_definition[i].name)
1585 SDDS_FreeArrayDefinition(SDDS_dataset->array[i].definition);
1586 }
1587 SDDS_dataset->array[i].definition = NULL;
1588 }
1589 free(SDDS_dataset->array);
1590 }
1591#if DEBUG
1592 fprintf(stderr, "freeing tabular data...\n");
1593#endif
1594 if (SDDS_dataset->data) {
1595 for (i = 0; i < layout->n_columns; i++)
1596 if (SDDS_dataset->data[i]) {
1597 if ((SDDS_dataset->column_track_memory == NULL) || (SDDS_dataset->column_track_memory[i])) {
1598 if (layout->column_definition[i].type == SDDS_STRING && !(terminateMode & TERMINATE_DONT_FREE_TABLE_STRINGS)) {
1599 ptr = (char **)SDDS_dataset->data[i];
1600 for (j = 0; j < SDDS_dataset->n_rows_allocated; j++, ptr++)
1601 if (*ptr)
1602 free(*ptr);
1603 }
1604 free(SDDS_dataset->data[i]);
1605 }
1606 }
1607 free(SDDS_dataset->data);
1608 }
1609 if (SDDS_dataset->column_track_memory)
1610 free(SDDS_dataset->column_track_memory);
1611#if DEBUG
1612 fprintf(stderr, "freeing layout data...\n");
1613#endif
1614 if (layout->description)
1615 free(layout->description);
1616 if (layout->contents == (&SDDS_dataset->layout)->contents)
1617 (&SDDS_dataset->layout)->contents = NULL;
1618 if (layout->contents)
1619 free(layout->contents);
1620 if (layout->filename)
1621 free(layout->filename);
1622 if (layout->column_definition) {
1623 for (i = 0; i < layout->n_columns; i++) {
1624 if (layout->column_index[i])
1625 free(layout->column_index[i]);
1626 if (layout->column_definition[i].name)
1627 free(layout->column_definition[i].name);
1628 if (layout->column_definition[i].symbol)
1629 free(layout->column_definition[i].symbol);
1630 if (layout->column_definition[i].units)
1631 free(layout->column_definition[i].units);
1632 if (layout->column_definition[i].description)
1633 free(layout->column_definition[i].description);
1634 if (layout->column_definition[i].format_string)
1635 free(layout->column_definition[i].format_string);
1636 }
1637 free(layout->column_definition);
1638 free(layout->column_index);
1639 }
1640 if (layout->parameter_definition) {
1641 for (i = 0; i < layout->n_parameters; i++) {
1642 if (layout->parameter_index[i])
1643 free(layout->parameter_index[i]);
1644 if (layout->parameter_definition[i].name)
1645 free(layout->parameter_definition[i].name);
1646 if (layout->parameter_definition[i].symbol)
1647 free(layout->parameter_definition[i].symbol);
1648 if (layout->parameter_definition[i].units)
1649 free(layout->parameter_definition[i].units);
1650 if (layout->parameter_definition[i].description)
1651 free(layout->parameter_definition[i].description);
1652 if (layout->parameter_definition[i].format_string)
1653 free(layout->parameter_definition[i].format_string);
1654 if (layout->parameter_definition[i].fixed_value)
1655 free(layout->parameter_definition[i].fixed_value);
1656 }
1657 free(layout->parameter_definition);
1658 free(layout->parameter_index);
1659 }
1660 if (layout->array_definition) {
1661 for (i = 0; i < layout->n_arrays; i++) {
1662 if (layout->array_index[i])
1663 free(layout->array_index[i]);
1664 if (layout->array_definition[i].name)
1665 free(layout->array_definition[i].name);
1666 if (layout->array_definition[i].symbol)
1667 free(layout->array_definition[i].symbol);
1668 if (layout->array_definition[i].units)
1669 free(layout->array_definition[i].units);
1670 if (layout->array_definition[i].description)
1671 free(layout->array_definition[i].description);
1672 if (layout->array_definition[i].format_string)
1673 free(layout->array_definition[i].format_string);
1674 if (layout->array_definition[i].group_name)
1675 free(layout->array_definition[i].group_name);
1676 }
1677 free(layout->array_definition);
1678 free(layout->array_index);
1679 }
1680 if (layout->associate_definition) {
1681 for (i = 0; i < layout->n_associates; i++) {
1682 if (layout->associate_definition[i].name)
1683 free(layout->associate_definition[i].name);
1684 if (layout->associate_definition[i].filename)
1685 free(layout->associate_definition[i].filename);
1686 if (layout->associate_definition[i].path)
1687 free(layout->associate_definition[i].path);
1688 if (layout->associate_definition[i].description)
1689 free(layout->associate_definition[i].description);
1690 if (layout->associate_definition[i].contents)
1691 free(layout->associate_definition[i].contents);
1692 }
1693 free(layout->associate_definition);
1694 }
1695 SDDS_ZeroMemory(&SDDS_dataset->original_layout, sizeof(SDDS_LAYOUT));
1696 layout = &SDDS_dataset->layout;
1697 if (layout->contents)
1698 free(layout->contents);
1699 if (layout->column_definition)
1700 free(layout->column_definition);
1701 if (layout->array_definition)
1702 free(layout->array_definition);
1703 if (layout->associate_definition)
1704 free(layout->associate_definition);
1705 if (layout->parameter_definition)
1706 free(layout->parameter_definition);
1707 if (layout->column_index)
1708 free(layout->column_index);
1709 if (layout->parameter_index)
1710 free(layout->parameter_index);
1711 if (layout->array_index)
1712 free(layout->array_index);
1713 SDDS_ZeroMemory(&SDDS_dataset->layout, sizeof(SDDS_LAYOUT));
1714 SDDS_ZeroMemory(SDDS_dataset, sizeof(SDDS_DATASET));
1715#if DEBUG
1716 fprintf(stderr, "done\n");
1717#endif
1718 return (1);
1719}
int32_t SDDS_UpdateRowCount(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_FreeArrayDefinition(ARRAY_DEFINITION *source)
Frees memory allocated for an array definition.
int32_t SDDS_MPI_Terminate(SDDS_DATASET *SDDS_dataset)
Terminates the SDDS dataset by freeing all allocated resources and closing MPI files.

◆ SDDS_UpdateRowCount()

int32_t SDDS_UpdateRowCount ( SDDS_DATASET * SDDS_dataset)

Updates the row count in the SDDS file for fixed row count mode.

Parameters
SDDS_datasetThe SDDS dataset to update.
Returns
1 on success, 0 on error.

Definition at line 1727 of file SDDS_input.c.

1727 {
1728 FILE *fp;
1729 SDDS_FILEBUFFER *fBuffer;
1730 int64_t offset, rows;
1731 int32_t rows32;
1732 char *outputEndianess = NULL;
1733
1734 if ((SDDS_dataset->layout.gzipFile) || (SDDS_dataset->layout.lzmaFile))
1735 return (1);
1736 if (!(fp = SDDS_dataset->layout.fp)) {
1737 SDDS_SetError("Unable to update page--file pointer is NULL (SDDS_UpdateRowCount)");
1738 return (0);
1739 }
1740#if DEBUG
1741 fprintf(stderr, "Updating rowcount in file %s with pointer %p\n", SDDS_dataset->layout.filename ? SDDS_dataset->layout.filename : "NULL", fp);
1742#endif
1743 fBuffer = &SDDS_dataset->fBuffer;
1744 if (!SDDS_FlushBuffer(fp, fBuffer)) {
1745 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateRowCount)");
1746 return (0);
1747 }
1748 offset = ftell(fp);
1749 if (SDDS_fseek(fp, SDDS_dataset->rowcount_offset, 0) == -1) {
1750 SDDS_SetError("Unable to update page--failure doing fseek (SDDS_UpdateRowCount)");
1751 return (0);
1752 }
1753 rows = SDDS_CountRowsOfInterest(SDDS_dataset) + SDDS_dataset->first_row_in_mem;
1754 if (SDDS_dataset->layout.data_mode.mode == SDDS_ASCII) {
1755 fprintf(fp, "%20" PRId64 "\n", rows);
1756 } else {
1757
1758 if (rows > INT32_MAX) {
1759 // Don't go over this limit because it has a different format
1760 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateRowCount)");
1761 return (0);
1762 }
1763 rows32 = (int32_t)rows;
1764 if ((outputEndianess = getenv("SDDS_OUTPUT_ENDIANESS"))) {
1765 if (((strncmp(outputEndianess, "big", 3) == 0) && (SDDS_IsBigEndianMachine() == 0)) || ((strncmp(outputEndianess, "little", 6) == 0) && (SDDS_IsBigEndianMachine() == 1)))
1766 SDDS_SwapLong(&rows32);
1767 }
1768 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
1769 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateRowCount)");
1770 return (0);
1771 }
1772 }
1773 if (SDDS_fseek(fp, offset, 0) == -1) {
1774 SDDS_SetError("Unable to update page--failure doing fseek to end of page (SDDS_UpdateRowCount)");
1775 return (0);
1776 }
1777 return (1);
1778}
int32_t SDDS_FlushBuffer(FILE *fp, SDDS_FILEBUFFER *fBuffer)
void SDDS_SwapLong(int32_t *data)
Swaps the endianness of a 32-bit integer.
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.