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

Detailed Description

SDDS binary data input and output routines.

This file contains the implementation of binary file handling functions for the SDDS (Self-Describing Data Sets) library. It includes functions for reading and writing binary data files in the SDDS format.

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

#include "SDDS.h"
#include "SDDS_internal.h"
#include "mdb.h"
#include "mdb_thread.h"
#include <string.h>
#include <errno.h>
#include <unistd.h>

Go to the source code of this file.

Functions

double makeFloat64FromFloat80 (unsigned char x[16], int32_t byteOrder)
 Converts a 16-byte array representing a float80 value to a double.
 
static int32_t SDDS_GetLockedDefaultIOBufferSize (void)
 
int32_t SDDS_SetBufferedRead (int32_t dummy)
 Obsolete routine retained for backward compatibility.
 
int32_t SDDS_SetDefaultIOBufferSize (int32_t newValue)
 
int32_t SDDS_BufferedRead (void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t type, int32_t byteOrder)
 
int32_t SDDS_LZMABufferedRead (void *target, int64_t targetSize, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t type, int32_t byteOrder)
 
int32_t SDDS_BufferedWrite (void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer)
 
int32_t SDDS_LZMABufferedWrite (void *target, int64_t targetSize, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
 
int32_t SDDS_FlushBuffer (FILE *fp, SDDS_FILEBUFFER *fBuffer)
 
int32_t SDDS_LZMAFlushBuffer (struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
 
int32_t SDDS_WriteBinaryPage (SDDS_DATASET *SDDS_dataset)
 
int32_t SDDS_UpdateBinaryPage (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 Updates the binary page of an SDDS dataset.
 
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.
 
int32_t SDDS_lzmaseek (struct lzmafile *lzmafp, int64_t offset, int32_t dir)
 Sets the file position indicator for a given LZMA file stream with retry logic.
 
int32_t SDDS_WriteBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Writes the binary parameters of the SDDS dataset.
 
int32_t SDDS_WriteBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Writes the binary arrays of the SDDS dataset to a file.
 
int32_t SDDS_WriteBinaryColumns (SDDS_DATASET *SDDS_dataset)
 Writes the binary columns of an SDDS dataset to the associated file.
 
int32_t SDDS_WriteNonNativeBinaryColumns (SDDS_DATASET *SDDS_dataset)
 Writes non-native endian binary columns of an SDDS dataset to the associated file.
 
int32_t SDDS_WriteBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row)
 Writes a single binary row of an SDDS dataset to the associated file.
 
int32_t SDDS_ReadRecoveryPossible (SDDS_DATASET *SDDS_dataset)
 Checks if any data in an SDDS page was recovered after an error was detected.
 
void SDDS_SetReadRecoveryMode (SDDS_DATASET *SDDS_dataset, int32_t mode)
 Sets the read recovery mode for an SDDS dataset.
 
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.
 
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.
 
int32_t SDDS_ReadBinaryPageDetailed (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows, int32_t sparse_statistics)
 Reads a binary page from an SDDS dataset with detailed options.
 
int32_t SDDS_WriteBinaryString (char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
 Writes a binary string to a file with buffering.
 
int32_t SDDS_LZMAWriteBinaryString (char *string, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
 Writes a binary string to a file with LZMA compression.
 
char * SDDS_ReadBinaryString (FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Reads a binary string from a file with buffering.
 
char * SDDS_ReadLZMABinaryString (struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Reads a binary string from an LZMA-compressed file with buffering.
 
int32_t SDDS_ReadBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
 Reads a binary row from the specified SDDS dataset.
 
int32_t SDDS_ReadNewBinaryRows (SDDS_DATASET *SDDS_dataset)
 Reads new binary rows from the SDDS dataset.
 
int32_t SDDS_ReadBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Reads binary parameters from the specified SDDS dataset.
 
int32_t SDDS_ReadBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Reads binary arrays from an SDDS dataset.
 
int32_t SDDS_ReadBinaryColumns (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset)
 Reads the binary columns from an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryColumns (SDDS_DATASET *SDDS_dataset)
 Reads the non-native endian binary columns from an SDDS dataset.
 
int32_t SDDS_SwapEndsColumnData (SDDS_DATASET *SDDSin)
 Swaps the endianness of the column data in an SDDS dataset.
 
int32_t SDDS_SwapEndsParameterData (SDDS_DATASET *SDDSin)
 Swaps the endianness of the parameter data in an SDDS dataset.
 
int32_t SDDS_SwapEndsArrayData (SDDS_DATASET *SDDSin)
 Swaps the endianness of the array data in an SDDS dataset.
 
void SDDS_SwapShort (short *data)
 Swaps the endianness of a short integer.
 
void SDDS_SwapUShort (unsigned short *data)
 Swaps the endianness of an unsigned short integer.
 
void SDDS_SwapLong (int32_t *data)
 Swaps the endianness of a 32-bit integer.
 
void SDDS_SwapULong (uint32_t *data)
 Swaps the endianness of a 32-bit unsigned integer.
 
void SDDS_SwapLong64 (int64_t *data)
 Swaps the endianness of a 64-bit integer.
 
void SDDS_SwapULong64 (uint64_t *data)
 Swaps the endianness of a 64-bit unsigned integer.
 
void SDDS_SwapFloat (float *data)
 Swaps the endianness of a float.
 
void SDDS_SwapDouble (double *data)
 Swaps the endianness of a double.
 
void SDDS_SwapLongDouble (long double *data)
 Swaps the endianness of a long double.
 
int32_t SDDS_ReadNonNativePage (SDDS_DATASET *SDDS_dataset)
 Reads a non-native endian page from an SDDS dataset.
 
int32_t SDDS_ReadNonNativePageSparse (SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset)
 Reads a sparse non-native endian page from an SDDS dataset.
 
int32_t SDDS_ReadNonNativePageDetailed (SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows)
 Reads a detailed non-native endian page from an SDDS dataset.
 
int32_t SDDS_ReadNonNativePageLastRows (SDDS_DATASET *SDDS_dataset, int64_t last_rows)
 Reads the last few rows from a non-native endian page in an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryPage (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset)
 Reads a non-native endian binary page from an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryPageLastRows (SDDS_DATASET *SDDS_dataset, int64_t last_rows)
 Reads the last few rows from a non-native endian binary page in an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryPageDetailed (SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows)
 Reads a detailed non-native endian binary page from an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Reads non-native endian binary parameters from an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Reads non-native endian binary arrays from an SDDS dataset.
 
int32_t SDDS_ReadNonNativeBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
 Reads a non-native endian binary row from an SDDS dataset.
 
char * SDDS_ReadNonNativeBinaryString (FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Reads a non-native endian binary string from a file.
 
char * SDDS_ReadNonNativeLZMABinaryString (struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Reads a non-native endian binary string from an LZMA-compressed file.
 
int32_t SDDS_WriteNonNativeBinaryPage (SDDS_DATASET *SDDS_dataset)
 Writes a non-native endian binary page to an SDDS dataset.
 
int32_t SDDS_WriteNonNativeBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Writes non-native endian binary parameters to an SDDS dataset.
 
int32_t SDDS_WriteNonNativeBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Writes non-native endian binary arrays to an SDDS dataset.
 
int32_t SDDS_WriteNonNativeBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row)
 Writes a non-native endian binary row to an SDDS dataset.
 
int32_t SDDS_WriteNonNativeBinaryString (char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
 Writes a non-native endian binary string to a file.
 
int32_t SDDS_LZMAWriteNonNativeBinaryString (char *string, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
 Writes a non-native endian binary string to an LZMA-compressed file.
 
int32_t SDDS_UpdateNonNativeBinaryPage (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 Updates a non-native endian binary page in an SDDS dataset.
 

Function Documentation

◆ makeFloat64FromFloat80()

double makeFloat64FromFloat80 ( unsigned char x[16],
int32_t byteOrder )

Converts a 16-byte array representing a float80 value to a double.

This function converts a 16-byte array, which represents an 80-bit floating-point (float80) value, to a standard double-precision (64-bit) floating-point value. The conversion handles different byte orders, supporting both big-endian and little-endian formats. On systems where long double is implemented as 64-bit (such as Windows and Mac), this function allows reading SDDS_LONGDOUBLE SDDS files with a loss of precision by translating float80 values to double.

Parameters
[in]xThe 16-byte array representing the float80 value.
[in]byteOrderThe byte order of the array, either SDDS_BIGENDIAN_SEEN or SDDS_LITTLEENDIAN_SEEN.
Returns
double The converted double-precision floating-point value.
Note
This function assumes that the input array x is correctly formatted as an 80-bit floating-point value. On systems where long double is 80 bits, the conversion preserves as much precision as possible within the limitations of the double-precision format. On systems with 64-bit long double, the function translates the value with inherent precision loss.

Definition at line 6019 of file SDDS_binary.c.

6019 {
6020 int exponent;
6021 uint64_t mantissa;
6022 unsigned char d[8] = {0};
6023 double result;
6024
6025 if (byteOrder == SDDS_BIGENDIAN_SEEN) {
6026 /* conversion is done in little endian */
6027 char xx;
6028 int i;
6029 for (i = 0; i < 6; i++) {
6030 xx = x[0 + i];
6031 x[0 + i] = x[11 - i];
6032 x[11 - i] = xx;
6033 }
6034 }
6035
6036 exponent = (((x[9] << 8) | x[8]) & 0x7FFF);
6037 mantissa =
6038 ((uint64_t)x[7] << 56) | ((uint64_t)x[6] << 48) | ((uint64_t)x[5] << 40) | ((uint64_t)x[4] << 32) |
6039 ((uint64_t)x[3] << 24) | ((uint64_t)x[2] << 16) | ((uint64_t)x[1] << 8) | (uint64_t)x[0];
6040
6041 d[7] = x[9] & 0x80; /* Set sign. */
6042
6043 if ((exponent == 0x7FFF) || (exponent == 0)) {
6044 /* Infinite, NaN or denormal */
6045 if (exponent == 0x7FFF) {
6046 /* Infinite or NaN */
6047 d[7] |= 0x7F;
6048 d[6] = 0xF0;
6049 } else {
6050 /* Otherwise it's denormal. It cannot be represented as double. Translate as singed zero. */
6051 memcpy(&result, d, 8);
6052 return result;
6053 }
6054 } else {
6055 /* Normal number. */
6056 exponent = exponent - 0x3FFF + 0x03FF; /*< exponent for double precision. */
6057
6058 if (exponent <= -52) /*< Too small to represent. Translate as (signed) zero. */
6059 {
6060 memcpy(&result, d, 8);
6061 return result;
6062 } else if (exponent < 0) {
6063 /* Denormal, exponent bits are already zero here. */
6064 } else if (exponent >= 0x7FF) /*< Too large to represent. Translate as infinite. */
6065 {
6066 d[7] |= 0x7F;
6067 d[6] = 0xF0;
6068 memset(d, 0x00, 6);
6069 memcpy(&result, d, 8);
6070 return result;
6071 } else {
6072 /* Representable number */
6073 d[7] |= (exponent & 0x7F0) >> 4;
6074 d[6] |= (exponent & 0xF) << 4;
6075 }
6076 }
6077 /* Translate mantissa. */
6078
6079 mantissa >>= 11;
6080
6081 if (exponent < 0) {
6082 /* Denormal, further shifting is required here. */
6083 mantissa >>= (-exponent + 1);
6084 }
6085
6086 d[0] = mantissa & 0xFF;
6087 d[1] = (mantissa >> 8) & 0xFF;
6088 d[2] = (mantissa >> 16) & 0xFF;
6089 d[3] = (mantissa >> 24) & 0xFF;
6090 d[4] = (mantissa >> 32) & 0xFF;
6091 d[5] = (mantissa >> 40) & 0xFF;
6092 d[6] |= (mantissa >> 48) & 0x0F;
6093
6094 memcpy(&result, d, 8);
6095
6096 if (byteOrder == SDDS_BIGENDIAN_SEEN) {
6097 /* convert back to big endian */
6098 SDDS_SwapDouble(&result);
6099 }
6100
6101 return result;
6102}
void SDDS_SwapDouble(double *data)
Swaps the endianness of a double.

◆ SDDS_BufferedRead()

int32_t SDDS_BufferedRead ( void * target,
int64_t targetSize,
FILE * fp,
SDDS_FILEBUFFER * fBuffer,
int32_t type,
int32_t byteOrder )

Reads data from a file into a buffer, optimizing performance with buffering.

This function reads targetSize bytes from the file fp into the memory pointed to by target. It uses the provided fBuffer to buffer file data, improving read performance. If the data type is SDDS_LONGDOUBLE and the long double precision is not 18 digits, it handles conversion to double precision if the environment variable SDDS_LONGDOUBLE_64BITS is not set.

If target is NULL, the function skips over targetSize bytes in the file.

Parameters
targetPointer to the memory location where the data will be stored. If NULL, the data is skipped.
targetSizeThe number of bytes to read from the file.
fpThe file pointer from which data is read.
fBufferPointer to an SDDS_FILEBUFFER structure used for buffering file data.
typeThe SDDS data type of the data being read (e.g., SDDS_LONGDOUBLE).
byteOrderThe byte order of the data (SDDS_LITTLEENDIAN or SDDS_BIGENDIAN).
Returns
Returns 1 on success; returns 0 on error.

Definition at line 114 of file SDDS_binary.c.

114 {
115 int float80tofloat64 = 0;
116 if ((LDBL_DIG != 18) && (type == SDDS_LONGDOUBLE)) {
117 if (getenv("SDDS_LONGDOUBLE_64BITS") == NULL) {
118 targetSize *= 2;
119 float80tofloat64 = 1;
120 }
121 }
122 if (!fBuffer->bufferSize) {
123 /* just read into users buffer or seek if no buffer given */
124 if (!target)
125 return !fseek(fp, (long)targetSize, SEEK_CUR);
126 else {
127 if (float80tofloat64) {
128 unsigned char x[16];
129 double d;
130 int64_t shift = 0;
131 while (shift < targetSize) {
132 if (fread(&x, (size_t)1, 16, fp) != 16)
133 return 0;
134 d = makeFloat64FromFloat80(x, byteOrder);
135 memcpy((char *)target + shift, &d, 8);
136 shift += 16;
137 }
138 return 1;
139 } else {
140 return fread(target, (size_t)1, (size_t)targetSize, fp) == targetSize;
141 }
142 }
143 }
144 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
145 /* sufficient data is already in the buffer */
146 if (target) {
147 if (float80tofloat64) {
148 unsigned char x[16];
149 double d;
150 int64_t shift = 0;
151 while (shift < targetSize) {
152 memcpy(x, (char *)fBuffer->data + shift, 16);
153 d = makeFloat64FromFloat80(x, byteOrder);
154 memcpy((char *)target + shift, &d, 8);
155 shift += 16;
156 }
157 } else {
158 memcpy((char *)target, (char *)fBuffer->data, targetSize);
159 }
160 }
161 fBuffer->data += targetSize;
162 return 1;
163 } else {
164 /* need to read additional data into buffer */
165 int64_t bytesNeeded, offset;
166 fBuffer->bytesLeft += targetSize; /* adds back amount subtracted above */
167
168 /* first, use the data that is already available. this cleans out the buffer */
169 if ((offset = fBuffer->bytesLeft)) {
170 /* some data is available in the buffer */
171 if (target) {
172 if (float80tofloat64) {
173 unsigned char x[16];
174 double d;
175 int64_t shift = 0;
176 while (shift < offset) {
177 memcpy(x, (char *)fBuffer->data + shift, 16);
178 d = makeFloat64FromFloat80(x, byteOrder);
179 memcpy((char *)target + shift, &d, 8);
180 shift += 16;
181 }
182 } else {
183 memcpy((char *)target, (char *)fBuffer->data, offset);
184 }
185 }
186 bytesNeeded = targetSize - offset;
187 fBuffer->bytesLeft = 0;
188 } else {
189 bytesNeeded = targetSize;
190 }
191 fBuffer->data = fBuffer->buffer;
192
193 if (fBuffer->bufferSize < bytesNeeded) {
194 /* just read what is needed directly into user's memory or seek */
195 if (!target)
196 return !fseek(fp, (long)bytesNeeded, SEEK_CUR);
197 else {
198 if (float80tofloat64) {
199 unsigned char x[16];
200 double d;
201 int64_t shift = 0;
202 while (shift < bytesNeeded) {
203 if (fread(&x, (size_t)1, 16, fp) != 16)
204 return 0;
205 d = makeFloat64FromFloat80(x, byteOrder);
206 memcpy((char *)target + offset + shift, &d, 8);
207 shift += 16;
208 }
209 return 1;
210 } else {
211 return fread((char *)target + offset, (size_t)1, (size_t)bytesNeeded, fp) == bytesNeeded;
212 }
213 }
214 }
215
216 /* fill the buffer */
217 if ((fBuffer->bytesLeft = fread(fBuffer->data, (size_t)1, (size_t)fBuffer->bufferSize, fp)) < bytesNeeded)
218 return 0;
219 if (target) {
220 if (float80tofloat64) {
221 unsigned char x[16];
222 double d;
223 int64_t shift = 0;
224 while (shift < bytesNeeded) {
225 memcpy(x, (char *)fBuffer->data + shift, 16);
226 d = makeFloat64FromFloat80(x, byteOrder);
227 memcpy((char *)target + offset + shift, &d, 8);
228 shift += 16;
229 }
230 } else {
231 memcpy((char *)target + offset, (char *)fBuffer->data, bytesNeeded);
232 }
233 }
234 fBuffer->data += bytesNeeded;
235 fBuffer->bytesLeft -= bytesNeeded;
236 return 1;
237 }
238}
double makeFloat64FromFloat80(unsigned char x[16], int32_t byteOrder)
Converts a 16-byte array representing a float80 value to a double.
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31

◆ SDDS_BufferedWrite()

int32_t SDDS_BufferedWrite ( void * target,
int64_t targetSize,
FILE * fp,
SDDS_FILEBUFFER * fBuffer )

Writes data to a file using a buffer to optimize performance.

This function writes targetSize bytes from the memory pointed to by target to the file fp. It uses the provided fBuffer to buffer file data, improving write performance. If the buffer is full, it flushes the buffer to the file before writing more data.

Parameters
targetPointer to the memory location of the data to write.
targetSizeThe number of bytes to write to the file.
fpThe file pointer to which data is written.
fBufferPointer to an SDDS_FILEBUFFER structure used for buffering file data.
Returns
Returns 1 on success; returns 0 on error.

Definition at line 502 of file SDDS_binary.c.

502 {
503 if (!fBuffer->bufferSize) {
504 return fwrite(target, (size_t)1, (size_t)targetSize, fp) == targetSize;
505 }
506 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
507 memcpy((char *)fBuffer->data, (char *)target, targetSize);
508 fBuffer->data += targetSize;
509#ifdef DEBUG
510 fprintf(stderr, "SDDS_BufferedWrite of %" PRId64 " bytes done in-memory, %" PRId64 " bytes left\n", targetSize, fBuffer->bytesLeft);
511#endif
512 return 1;
513 } else {
514 int64_t lastLeft;
515 /* add back what was subtracted in test above.
516 * lastLeft is the number of bytes left in the buffer before doing anything
517 * and also the number of bytes from the users data that get copied into the buffer.
518 */
519 lastLeft = (fBuffer->bytesLeft += targetSize);
520 /* copy part of the data into the buffer and write the buffer out */
521 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
522 if (fwrite(fBuffer->buffer, (size_t)1, (size_t)fBuffer->bufferSize, fp) != fBuffer->bufferSize)
523 return 0;
524 if (fflush(fp)) {
525 SDDS_SetError("Problem flushing file (SDDS_BufferedWrite)");
526 SDDS_SetError(strerror(errno));
527 return 0;
528 }
529 /* reset the data pointer and the bytesLeft value.
530 * also, determine if the remaining data is too large for the buffer.
531 * if so, just write it out.
532 */
533 fBuffer->data = fBuffer->buffer;
534 if ((targetSize -= lastLeft) > (fBuffer->bytesLeft = fBuffer->bufferSize)) {
535 return fwrite((char *)target + lastLeft, (size_t)1, (size_t)targetSize, fp) == targetSize;
536 }
537 /* copy remaining data into the buffer.
538 * could do this with a recursive call, but this is more efficient.
539 */
540 memcpy((char *)fBuffer->data, (char *)target + lastLeft, targetSize);
541 fBuffer->data += targetSize;
542 fBuffer->bytesLeft -= targetSize;
543 return 1;
544 }
545}
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421

◆ SDDS_FlushBuffer()

int32_t SDDS_FlushBuffer ( FILE * fp,
SDDS_FILEBUFFER * fBuffer )

Flushes the buffered data to a file to ensure all data is written.

This function writes any remaining data in the buffer (fBuffer) to the file pointed to by fp. If the buffer contains data, it writes the data to the file, resets the buffer, and flushes the file's output buffer using fflush. This ensures that all buffered data is physically written to the file.

Parameters
fpThe file pointer to which buffered data will be written.
fBufferPointer to an SDDS_FILEBUFFER structure containing the buffered data.
Returns
Returns 1 on success; returns 0 on error.
Note
If fBuffer->bufferSize is zero, the function will only call fflush(fp).
Warning
If fp or fBuffer is NULL, the function sets an error message and returns 0.

Definition at line 650 of file SDDS_binary.c.

650 {
651 int64_t writeBytes;
652 if (!fp) {
653 SDDS_SetError("Unable to flush buffer: file pointer is NULL. (SDDS_FlushBuffer)");
654 return 0;
655 }
656 if (!fBuffer) {
657 SDDS_SetError("Unable to flush buffer: buffer pointer is NULL. (SDDS_FlushBuffer)");
658 return 0;
659 }
660 if (!fBuffer->bufferSize) {
661 if (fflush(fp)) {
662 SDDS_SetError("Problem flushing file (SDDS_FlushBuffer.1)");
663 SDDS_SetError(strerror(errno));
664 return 0;
665 }
666 return 1;
667 }
668 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
669 if (writeBytes < 0) {
670 SDDS_SetError("Unable to flush buffer: negative byte count (SDDS_FlushBuffer).");
671 return 0;
672 }
673#ifdef DEBUG
674 fprintf(stderr, "Writing %" PRId64 " bytes to disk\n", writeBytes);
675#endif
676 if (fwrite(fBuffer->buffer, 1, writeBytes, fp) != writeBytes) {
677 SDDS_SetError("Unable to flush buffer: write operation failed (SDDS_FlushBuffer).");
678 return 0;
679 }
680 fBuffer->bytesLeft = fBuffer->bufferSize;
681 fBuffer->data = fBuffer->buffer;
682 }
683 if (fflush(fp)) {
684 SDDS_SetError("Problem flushing file (SDDS_FlushBuffer.2)");
685 SDDS_SetError(strerror(errno));
686 return 0;
687 }
688 return 1;
689}

◆ SDDS_fseek()

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.

Attempts to set the file position indicator for the specified file stream (fp) to a new position defined by offset and dir. The function retries the fseek operation up to FSEEK_TRIES times in case of transient failures, implementing a delay between attempts.

Parameters
fpPointer to the FILE stream whose position indicator is to be set.
offsetNumber of bytes to offset from the position specified by dir.
dirPositioning directive, which can be one of:
  • SEEK_SET to set the position relative to the beginning of the file,
  • SEEK_CUR to set the position relative to the current position,
  • SEEK_END to set the position relative to the end of the file.
Returns
  • Returns 0 if the operation is successful.
  • Returns -1 if all retry attempts fail to set the file position.

The function attempts to set the file position using fseek. If fseek fails, it sleeps for 1 second (or 1 second using nanosleep on vxWorks systems) before retrying. After FSEEK_TRIES unsuccessful attempts, it reports a warning and returns -1.

Note
  • The function is designed to handle temporary file access issues by retrying the fseek operation.
  • It is not suitable for non-recoverable fseek errors, which will cause it to fail after retries.

Definition at line 1279 of file SDDS_binary.c.

1279 {
1280 int32_t try;
1281#if defined(vxWorks)
1282 struct timespec rqtp;
1283 rqtp.tv_sec = 1;
1284 rqtp.tv_nsec = 0;
1285#endif
1286 for (try = 0; try < FSEEK_TRIES; try++) {
1287 if (fseek(fp, offset, dir) == -1) {
1288#if defined(vxWorks)
1289 nanosleep(&rqtp, NULL);
1290#else
1291 sleep(1);
1292#endif
1293 } else
1294 break;
1295 }
1296 if (try == 0)
1297 return 0;
1298 if (try == FSEEK_TRIES) {
1299 fputs("warning: fseek problems--unable to recover\n", stderr);
1300 return -1;
1301 }
1302 fputs("warning: fseek problems--recovered\n", stderr);
1303 return 0;
1304}

◆ SDDS_GetLockedDefaultIOBufferSize()

static int32_t SDDS_GetLockedDefaultIOBufferSize ( void )
static

Definition at line 48 of file SDDS_binary.c.

48 {
49 int32_t size;
50 mdb_thread_lock(&defaultIOBufferSizeLock);
51 size = defaultIOBufferSize;
52 mdb_thread_unlock(&defaultIOBufferSizeLock);
53 return size;
54}

◆ SDDS_LZMABufferedRead()

int32_t SDDS_LZMABufferedRead ( void * target,
int64_t targetSize,
struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer,
int32_t type,
int32_t byteOrder )

Reads data from an LZMA-compressed file into a buffer, optimizing performance with buffering.

This function reads targetSize bytes from the LZMA-compressed file lzmafp into the memory pointed to by target. It uses the provided fBuffer to buffer file data, improving read performance. If the data type is SDDS_LONGDOUBLE and the long double precision is not 18 digits, it handles conversion to double precision if the environment variable SDDS_LONGDOUBLE_64BITS is not set.

If target is NULL, the function skips over targetSize bytes in the file.

Parameters
targetPointer to the memory location where the data will be stored. If NULL, the data is skipped.
targetSizeThe number of bytes to read from the file.
lzmafpThe LZMA file pointer from which data is read.
fBufferPointer to an SDDS_FILEBUFFER structure used for buffering file data.
typeThe SDDS data type of the data being read (e.g., SDDS_LONGDOUBLE).
byteOrderThe byte order of the data (SDDS_LITTLEENDIAN or SDDS_BIGENDIAN).
Returns
Returns 1 on success; returns 0 on error.
Note
This function requires that fBuffer->bufferSize is non-zero. If it is zero, an error is set.

Definition at line 261 of file SDDS_binary.c.

261 {
262 int float80tofloat64 = 0;
263 if (!fBuffer->bufferSize) {
264 SDDS_SetError("You must presently have a nonzero file buffer to use LZMA (reading/writing .lzma or .xz files)");
265 return 0;
266 }
267 if ((LDBL_DIG != 18) && (type == SDDS_LONGDOUBLE)) {
268 if (getenv("SDDS_LONGDOUBLE_64BITS") == NULL) {
269 targetSize *= 2;
270 float80tofloat64 = 1;
271 }
272 }
273 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
274 if (target) {
275 if (float80tofloat64) {
276 unsigned char x[16];
277 double d;
278 int64_t shift = 0;
279 while (shift < targetSize) {
280 memcpy(x, (char *)fBuffer->data + shift, 16);
281 d = makeFloat64FromFloat80(x, byteOrder);
282 memcpy((char *)target + shift, &d, 8);
283 shift += 16;
284 }
285 } else {
286 memcpy((char *)target, (char *)fBuffer->data, targetSize);
287 }
288 }
289 fBuffer->data += targetSize;
290 return 1;
291 } else {
292 int64_t bytesNeeded, offset;
293 fBuffer->bytesLeft += targetSize;
294 if ((offset = fBuffer->bytesLeft)) {
295 if (target) {
296 if (float80tofloat64) {
297 unsigned char x[16];
298 double d;
299 int64_t shift = 0;
300 while (shift < offset) {
301 memcpy(x, (char *)fBuffer->data + shift, 16);
302 d = makeFloat64FromFloat80(x, byteOrder);
303 memcpy((char *)target + shift, &d, 8);
304 shift += 16;
305 }
306 } else {
307 memcpy((char *)target, (char *)fBuffer->data, offset);
308 }
309 }
310 bytesNeeded = targetSize - offset;
311 fBuffer->bytesLeft = 0;
312 } else {
313 bytesNeeded = targetSize;
314 }
315 fBuffer->data = fBuffer->buffer;
316
317 if (fBuffer->bufferSize < bytesNeeded) {
318 /* just read what is needed directly into user's memory or seek */
319 if (!target)
320 return !lzma_seek(lzmafp, (long)bytesNeeded, SEEK_CUR);
321 else {
322 if (float80tofloat64) {
323 unsigned char x[16];
324 double d;
325 int64_t shift = 0;
326 while (shift < bytesNeeded) {
327 if (lzma_read(lzmafp, &x, 16) != 16)
328 return 0;
329 d = makeFloat64FromFloat80(x, byteOrder);
330 memcpy((char *)target + offset + shift, &d, 8);
331 shift += 16;
332 }
333 return 1;
334 } else {
335 return lzma_read(lzmafp, (char *)target + offset, (size_t)bytesNeeded) == bytesNeeded;
336 }
337 }
338 }
339
340 if ((fBuffer->bytesLeft = lzma_read(lzmafp, fBuffer->data, (size_t)fBuffer->bufferSize)) < bytesNeeded)
341 return 0;
342 if (target) {
343 if (float80tofloat64) {
344 unsigned char x[16];
345 double d;
346 int64_t shift = 0;
347 while (shift < bytesNeeded) {
348 memcpy(x, (char *)fBuffer->data + shift, 16);
349 d = makeFloat64FromFloat80(x, byteOrder);
350 memcpy((char *)target + offset + shift, &d, 8);
351 shift += 16;
352 }
353 } else {
354 memcpy((char *)target + offset, (char *)fBuffer->data, bytesNeeded);
355 }
356 }
357 fBuffer->data += bytesNeeded;
358 fBuffer->bytesLeft -= bytesNeeded;
359 return 1;
360 }
361}

◆ SDDS_LZMABufferedWrite()

int32_t SDDS_LZMABufferedWrite ( void * target,
int64_t targetSize,
struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer )

Writes data to an LZMA-compressed file using a buffer to optimize performance.

This function writes targetSize bytes from the memory pointed to by target to the LZMA-compressed file referenced by lzmafp. It uses the provided fBuffer to buffer data before writing to the file, which can improve write performance by reducing the number of write operations.

If there is enough space in the buffer (fBuffer), the data is copied into the buffer. If the buffer does not have enough space to hold the data, the buffer is flushed to the file, and the function recursively calls itself to handle the remaining data.

Parameters
targetPointer to the memory location of the data to write.
targetSizeThe number of bytes to write to the file.
lzmafpThe LZMA file pointer to which data is written.
fBufferPointer to an SDDS_FILEBUFFER structure used for buffering data.
Returns
Returns 1 on success; returns 0 on error.
Note
This function requires that fBuffer->bufferSize is non-zero. If it is zero, the function sets an error message and returns 0.

Definition at line 568 of file SDDS_binary.c.

568 {
569 if (!fBuffer->bufferSize) {
570 SDDS_SetError("You must presently have a nonzero file buffer to use lzma (reading/writing .xz files)");
571 return 0;
572 }
573 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
574 memcpy((char *)fBuffer->data, (char *)target, targetSize);
575 fBuffer->data += targetSize;
576 return 1;
577 } else {
578 int64_t lastLeft;
579 lastLeft = (fBuffer->bytesLeft += targetSize);
580 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
581 if (lzma_write(lzmafp, fBuffer->buffer, (size_t)fBuffer->bufferSize) != fBuffer->bufferSize)
582 return 0;
583 fBuffer->bytesLeft = fBuffer->bufferSize;
584 fBuffer->data = fBuffer->buffer;
585 return SDDS_LZMABufferedWrite((char *)target + lastLeft, targetSize - lastLeft, lzmafp, fBuffer);
586 }
587}
int32_t SDDS_LZMABufferedWrite(void *target, int64_t targetSize, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)

◆ SDDS_LZMAFlushBuffer()

int32_t SDDS_LZMAFlushBuffer ( struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer )

Flushes the buffered data to an LZMA-compressed file to ensure all data is written.

This function writes any remaining data in the buffer (fBuffer) to the LZMA-compressed file pointed to by lzmafp. If the buffer contains data, it writes the data to the file, resets the buffer, ensuring that all buffered data is physically written to the file.

Parameters
lzmafpThe LZMA file pointer to which buffered data will be written.
fBufferPointer to an SDDS_FILEBUFFER structure containing the buffered data.
Returns
Returns 1 on success; returns 0 on error.
Note
This function assumes that fBuffer->bufferSize is non-zero and fBuffer is properly initialized.

Definition at line 705 of file SDDS_binary.c.

705 {
706 int32_t writeBytes;
707 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
708 if (lzma_write(lzmafp, fBuffer->buffer, writeBytes) != writeBytes)
709 return 0;
710 fBuffer->bytesLeft = fBuffer->bufferSize;
711 fBuffer->data = fBuffer->buffer;
712 }
713 return 1;
714}

◆ SDDS_lzmaseek()

int32_t SDDS_lzmaseek ( struct lzmafile * lzmafp,
int64_t offset,
int32_t dir )

Sets the file position indicator for a given LZMA file stream with retry logic.

Attempts to set the file position indicator for the specified LZMA file stream (lzmafp) to a new position defined by offset and dir. The function retries the lzma_seek operation up to FSEEK_TRIES times in case of transient failures, implementing a delay between attempts.

Parameters
lzmafpPointer to the lzmafile stream whose position indicator is to be set.
offsetNumber of bytes to offset from the position specified by dir.
dirPositioning directive, which can be one of:
  • SEEK_SET to set the position relative to the beginning of the file,
  • SEEK_CUR to set the position relative to the current position,
  • SEEK_END to set the position relative to the end of the file.
Returns
  • Returns 0 if the operation is successful.
  • Returns -1 if all retry attempts fail to set the file position.

The function attempts to set the file position using lzma_seek. If lzma_seek fails, it sleeps for 1 second (or 1 second using nanosleep on vxWorks systems) before retrying. After FSEEK_TRIES unsuccessful attempts, it reports a warning and returns -1.

Note
  • The function is designed to handle temporary file access issues by retrying the lzma_seek operation.
  • It is not suitable for non-recoverable lzma_seek errors, which will cause it to fail after retries.

Definition at line 1333 of file SDDS_binary.c.

1333 {
1334 int32_t try;
1335#if defined(vxWorks)
1336 struct timespec rqtp;
1337 rqtp.tv_sec = 1;
1338 rqtp.tv_nsec = 0;
1339#endif
1340 for (try = 0; try < FSEEK_TRIES; try++) {
1341 if (lzma_seek(lzmafp, offset, dir) == -1) {
1342#if defined(vxWorks)
1343 nanosleep(&rqtp, NULL);
1344#else
1345 sleep(1);
1346#endif
1347 } else
1348 break;
1349 }
1350 if (try == 0)
1351 return 0;
1352 if (try == FSEEK_TRIES) {
1353 fputs("warning: lzma_seek problems--unable to recover\n", stderr);
1354 return -1;
1355 }
1356 fputs("warning: lzma_seek problems--recovered\n", stderr);
1357 return 0;
1358}

◆ SDDS_LZMAWriteBinaryString()

int32_t SDDS_LZMAWriteBinaryString ( char * string,
struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer )

Writes a binary string to a file with LZMA compression.

This function writes a binary string to the specified LZMA-compressed file by first writing the length of the string followed by the string's content. If the input string is NULL, an empty string is written instead. The writing operation utilizes LZMA buffered write functions to ensure data is compressed appropriately.

Parameters
[in]stringThe null-terminated string to be written. If NULL, an empty string is written.
[in]lzmafpThe LZMA file pointer to write to. Must be a valid, open LZMA-compressed file in write mode.
[in,out]fBufferPointer to the file buffer used for buffered writing operations.
Returns
int32_t Returns 1 on success, 0 on failure.
Return values
1Operation was successful.
0An error occurred during writing.

Definition at line 2674 of file SDDS_binary.c.

2674 {
2675 int32_t length;
2676 static const char dummy_string[] = "";
2677 if (!string)
2678 string = (char *)dummy_string;
2679 length = strlen(string);
2680 if (!SDDS_LZMABufferedWrite(&length, sizeof(length), lzmafp, fBuffer)) {
2681 SDDS_SetError("Unable to write string--error writing length");
2682 return (0);
2683 }
2684 if (length && !SDDS_LZMABufferedWrite(string, sizeof(*string) * length, lzmafp, fBuffer)) {
2685 SDDS_SetError("Unable to write string--error writing contents");
2686 return (0);
2687 }
2688 return (1);
2689}

◆ SDDS_LZMAWriteNonNativeBinaryString()

int32_t SDDS_LZMAWriteNonNativeBinaryString ( char * string,
struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer )

Writes a non-native endian binary string to an LZMA-compressed file.

This function writes a binary string to the specified LZMA-compressed file pointer, handling non-native endianness. It first writes the length of the string as a 32-bit integer with byte order swapped. If the string is not to be skipped, it then writes the string data itself followed by a null terminator. If the input string is NULL, an empty string is written instead.

Parameters
[in]stringThe string to write. If NULL, an empty string is written.
[in]lzmafpPointer to the LZMAFILE where the string will be written.
[in]fBufferPointer to the SDDS_FILEBUFFER structure used for buffered writing.
Returns
int32_t Returns 1 on successful writing of the string, or 0 if an error occurred.
Return values
1The string was successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures or memory allocation issues.
Note
The caller is responsible for ensuring that the LZMAFILE pointer lzmafp is valid and open for writing. This function does not perform memory allocation for the string; it assumes that the string is already allocated and managed appropriately.

Definition at line 5763 of file SDDS_binary.c.

5763 {
5764 int32_t length;
5765 static const char dummy_string[] = "";
5766 if (!string)
5767 string = (char *)dummy_string;
5768 length = strlen(string);
5769 SDDS_SwapLong(&length);
5770 if (!SDDS_LZMABufferedWrite(&length, sizeof(length), lzmafp, fBuffer)) {
5771 SDDS_SetError("Unable to write string--error writing length");
5772 return (0);
5773 }
5774 SDDS_SwapLong(&length);
5775 if (length && !SDDS_LZMABufferedWrite(string, sizeof(*string) * length, lzmafp, fBuffer)) {
5776 SDDS_SetError("Unable to write string--error writing contents");
5777 return (0);
5778 }
5779 return (1);
5780}
void SDDS_SwapLong(int32_t *data)
Swaps the endianness of a 32-bit integer.

◆ SDDS_ReadBinaryArrays()

int32_t SDDS_ReadBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Reads binary arrays from an SDDS dataset.

This function iterates through all array definitions within the specified SDDS dataset and reads their binary data from the underlying file. It handles various compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. For each array, the function reads its definition, dimensions, and data elements, allocating and managing memory as necessary. String arrays are handled by reading each string individually, while other data types are read in bulk.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successful reading of all arrays, or 0 if an error occurred.
Return values
1All arrays were successfully read and stored.
0An error occurred during the read operation, such as I/O failures, memory allocation issues, or corrupted array definitions.
Note
The caller is responsible for ensuring that the SDDS_dataset structure is properly initialized and that memory allocations for arrays are managed appropriately to prevent memory leaks.

Definition at line 3184 of file SDDS_binary.c.

3184 {
3185 int32_t i, j;
3186 SDDS_LAYOUT *layout;
3187 /* char *predefined_format; */
3188 /* static char buffer[SDDS_MAXLINE]; */
3189#if defined(zLib)
3190 gzFile gzfp = NULL;
3191#endif
3192 FILE *fp = NULL;
3193 struct lzmafile *lzmafp = NULL;
3194 SDDS_ARRAY *array;
3195 SDDS_FILEBUFFER *fBuffer;
3196
3197 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryArrays"))
3198 return (0);
3199 layout = &SDDS_dataset->layout;
3200 if (!layout->n_arrays)
3201 return (1);
3202#if defined(zLib)
3203 if (SDDS_dataset->layout.gzipFile) {
3204 gzfp = layout->gzfp;
3205 } else {
3206#endif
3207 if (SDDS_dataset->layout.lzmaFile) {
3208 lzmafp = layout->lzmafp;
3209 } else {
3210 fp = layout->fp;
3211 }
3212#if defined(zLib)
3213 }
3214#endif
3215 fBuffer = &SDDS_dataset->fBuffer;
3216 if (!SDDS_dataset->array) {
3217 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_ReadBinaryArrays)");
3218 return (0);
3219 }
3220 for (i = 0; i < layout->n_arrays; i++) {
3221 array = SDDS_dataset->array + i;
3222 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
3223 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_ReadBinaryArrays)");
3224 return (0);
3225 }
3226 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
3227 SDDS_SetError("Unable to read array--definition copy failed (SDDS_ReadBinaryArrays)");
3228 return (0);
3229 }
3230 /*if (array->dimension) free(array->dimension); */
3231 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
3232 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadBinaryArrays)");
3233 return (0);
3234 }
3235#if defined(zLib)
3236 if (SDDS_dataset->layout.gzipFile) {
3237 if (!SDDS_GZipBufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, gzfp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3238 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3239 return (0);
3240 }
3241 } else {
3242#endif
3243 if (SDDS_dataset->layout.lzmaFile) {
3244 if (!SDDS_LZMABufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, lzmafp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3245 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3246 return (0);
3247 }
3248 } else {
3249 if (!SDDS_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, fp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3250 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3251 return (0);
3252 }
3253 }
3254#if defined(zLib)
3255 }
3256#endif
3257 array->elements = 1;
3258 for (j = 0; j < array->definition->dimensions; j++)
3259 array->elements *= array->dimension[j];
3260 if (array->data)
3261 free(array->data);
3262 array->data = array->pointer = NULL;
3263 if (array->elements == 0)
3264 continue;
3265 if (array->elements < 0) {
3266 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_ReadBinaryArrays)");
3267 return (0);
3268 }
3269 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
3270 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadBinaryArrays)");
3271 return (0);
3272 }
3273 if (array->definition->type == SDDS_STRING) {
3274#if defined(zLib)
3275 if (SDDS_dataset->layout.gzipFile) {
3276 for (j = 0; j < array->elements; j++) {
3277 if (!(((char **)(array->data))[j] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
3278 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3279 return (0);
3280 }
3281 }
3282 } else {
3283#endif
3284 if (SDDS_dataset->layout.lzmaFile) {
3285 for (j = 0; j < array->elements; j++) {
3286 if (!(((char **)(array->data))[j] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3287 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3288 return (0);
3289 }
3290 }
3291 } else {
3292 for (j = 0; j < array->elements; j++) {
3293 if (!(((char **)(array->data))[j] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3294 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3295 return (0);
3296 }
3297 }
3298 }
3299#if defined(zLib)
3300 }
3301#endif
3302 } else {
3303#if defined(zLib)
3304 if (SDDS_dataset->layout.gzipFile) {
3305 if (!SDDS_GZipBufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, gzfp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3306 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3307 return (0);
3308 }
3309 } else {
3310#endif
3311 if (SDDS_dataset->layout.lzmaFile) {
3312 if (!SDDS_LZMABufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, lzmafp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3313 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3314 return (0);
3315 }
3316 } else {
3317 if (!SDDS_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, fp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3318 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3319 return (0);
3320 }
3321 }
3322#if defined(zLib)
3323 }
3324#endif
3325 }
3326 }
3327 return (1);
3328}
int32_t SDDS_LZMABufferedRead(void *target, int64_t targetSize, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t type, int32_t byteOrder)
char * SDDS_ReadBinaryString(FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Reads a binary string from a file with buffering.
int32_t SDDS_BufferedRead(void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t type, int32_t byteOrder)
char * SDDS_ReadLZMABinaryString(struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Reads a binary string from an LZMA-compressed file with buffering.
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
int32_t SDDS_FreeArrayDefinition(ARRAY_DEFINITION *source)
Frees memory allocated for an array definition.
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:618
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:743
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61

◆ SDDS_ReadBinaryColumns()

int32_t SDDS_ReadBinaryColumns ( SDDS_DATASET * SDDS_dataset,
int64_t sparse_interval,
int64_t sparse_offset )

Reads the binary columns from an SDDS dataset.

This function iterates through all column definitions within the specified SDDS dataset and reads their binary data from the underlying file. It handles various compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. For each column, the function reads data for each row, managing memory allocation for string columns as necessary. Non-string data types are read in bulk for each column.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successful reading of all columns, or 0 if an error occurred.
Return values
1All columns were successfully read and stored.
0An error occurred during the read operation, such as I/O failures, memory allocation issues, or corrupted column definitions.
Note
The caller is responsible for ensuring that the SDDS_dataset structure is properly initialized and that memory allocations for columns are managed appropriately to prevent memory leaks.

Definition at line 3349 of file SDDS_binary.c.

3349 {
3350 int64_t i, j, k, row;
3351 SDDS_LAYOUT *layout;
3352 /* char *predefined_format; */
3353 /* static char buffer[SDDS_MAXLINE]; */
3354#if defined(zLib)
3355 gzFile gzfp = NULL;
3356#endif
3357 FILE *fp = NULL;
3358 struct lzmafile *lzmafp = NULL;
3359 SDDS_FILEBUFFER *fBuffer;
3360
3361 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryColumns"))
3362 return (0);
3363 layout = &SDDS_dataset->layout;
3364 if (!layout->n_columns || !SDDS_dataset->n_rows)
3365 return (1);
3366#if defined(zLib)
3367 if (SDDS_dataset->layout.gzipFile) {
3368 gzfp = layout->gzfp;
3369 } else {
3370#endif
3371 if (SDDS_dataset->layout.lzmaFile) {
3372 lzmafp = layout->lzmafp;
3373 } else {
3374 fp = layout->fp;
3375 }
3376#if defined(zLib)
3377 }
3378#endif
3379 fBuffer = &SDDS_dataset->fBuffer;
3380
3381 for (i = 0; i < layout->n_columns; i++) {
3382 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
3383 continue;
3384 if (layout->column_definition[i].type == SDDS_STRING) {
3385#if defined(zLib)
3386 if (SDDS_dataset->layout.gzipFile) {
3387 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3388 if (((char ***)SDDS_dataset->data)[i][row])
3389 free((((char ***)SDDS_dataset->data)[i][row]));
3390 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
3391 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumns)");
3392 return (0);
3393 }
3394 }
3395 } else {
3396#endif
3397 if (SDDS_dataset->layout.lzmaFile) {
3398 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3399 if (((char ***)SDDS_dataset->data)[i][row])
3400 free((((char ***)SDDS_dataset->data)[i][row]));
3401 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3402 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumms)");
3403 return (0);
3404 }
3405 }
3406 } else {
3407 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3408 if (((char ***)SDDS_dataset->data)[i][row])
3409 free((((char ***)SDDS_dataset->data)[i][row]));
3410 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3411 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumms)");
3412 return (0);
3413 }
3414 }
3415 }
3416#if defined(zLib)
3417 }
3418#endif
3419 } else {
3420#if defined(zLib)
3421 if (SDDS_dataset->layout.gzipFile) {
3422 if (!SDDS_GZipBufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, gzfp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3423 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3424 return (0);
3425 }
3426 } else {
3427#endif
3428 if (SDDS_dataset->layout.lzmaFile) {
3429 if (!SDDS_LZMABufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, lzmafp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3430 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3431 return (0);
3432 }
3433 } else {
3434 if (!SDDS_BufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, fp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3435 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3436 return (0);
3437 }
3438 }
3439#if defined(zLib)
3440 }
3441#endif
3442 }
3443 }
3444
3445 if (sparse_interval == 1 && sparse_offset == 0) {
3446 return(1);
3447 }
3448
3449 j = SDDS_dataset->n_rows;
3450 for (i = 0; i < layout->n_columns; i++) {
3451 j = k = 0;
3452 switch (layout->column_definition[i].type) {
3453 case SDDS_SHORT:
3454 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3455 if (k % sparse_interval == 0) {
3456 ((short*)SDDS_dataset->data[i])[j] = ((short*)SDDS_dataset->data[i])[row];
3457 j++;
3458 }
3459 k++;
3460 }
3461 break;
3462 case SDDS_USHORT:
3463 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3464 if (k % sparse_interval == 0) {
3465 ((unsigned short*)SDDS_dataset->data[i])[j] = ((unsigned short*)SDDS_dataset->data[i])[row];
3466 j++;
3467 }
3468 k++;
3469 }
3470 break;
3471 case SDDS_LONG:
3472 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3473 if (k % sparse_interval == 0) {
3474 ((int32_t*)SDDS_dataset->data[i])[j] = ((int32_t*)SDDS_dataset->data[i])[row];
3475 j++;
3476 }
3477 k++;
3478 }
3479 break;
3480 case SDDS_ULONG:
3481 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3482 if (k % sparse_interval == 0) {
3483 ((uint32_t*)SDDS_dataset->data[i])[j] = ((uint32_t*)SDDS_dataset->data[i])[row];
3484 j++;
3485 }
3486 k++;
3487 }
3488 break;
3489 case SDDS_LONG64:
3490 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3491 if (k % sparse_interval == 0) {
3492 ((int64_t*)SDDS_dataset->data[i])[j] = ((int64_t*)SDDS_dataset->data[i])[row];
3493 j++;
3494 }
3495 k++;
3496 }
3497 break;
3498 case SDDS_ULONG64:
3499 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3500 if (k % sparse_interval == 0) {
3501 ((uint64_t*)SDDS_dataset->data[i])[j] = ((uint64_t*)SDDS_dataset->data[i])[row];
3502 j++;
3503 }
3504 k++;
3505 }
3506 break;
3507 case SDDS_FLOAT:
3508 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3509 if (k % sparse_interval == 0) {
3510 ((float*)SDDS_dataset->data[i])[j] = ((float*)SDDS_dataset->data[i])[row];
3511 j++;
3512 }
3513 k++;
3514 }
3515 break;
3516 case SDDS_DOUBLE:
3517 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3518 if (k % sparse_interval == 0) {
3519 ((double*)SDDS_dataset->data[i])[j] = ((double*)SDDS_dataset->data[i])[row];
3520 j++;
3521 }
3522 k++;
3523 }
3524 break;
3525 case SDDS_LONGDOUBLE:
3526 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3527 if (k % sparse_interval == 0) {
3528 ((long double*)SDDS_dataset->data[i])[j] = ((long double*)SDDS_dataset->data[i])[row];
3529 j++;
3530 }
3531 k++;
3532 }
3533 break;
3534 case SDDS_STRING:
3535 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3536 if (k % sparse_interval == 0) {
3537 ((char**)SDDS_dataset->data[i])[j] = ((char**)SDDS_dataset->data[i])[row];
3538 j++;
3539 }
3540 k++;
3541 }
3542 for (k=j; k<SDDS_dataset->n_rows; k++) {
3543 if (((char ***)SDDS_dataset->data)[i][k]) {
3544 free((((char ***)SDDS_dataset->data)[i][k]));
3545 ((char ***)SDDS_dataset->data)[i][k] = NULL;
3546 }
3547 }
3548
3549 break;
3550 case SDDS_CHARACTER:
3551 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3552 if (k % sparse_interval == 0) {
3553 ((char*)SDDS_dataset->data[i])[j] = ((char*)SDDS_dataset->data[i])[row];
3554 j++;
3555 }
3556 k++;
3557 }
3558 break;
3559 default:
3560 break;
3561 }
3562 }
3563
3564 SDDS_dataset->n_rows = j;
3565
3566 return (1);
3567}
#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_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#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_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49

◆ SDDS_ReadBinaryPage()

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.

This function reads a binary page from the specified SDDS dataset. It allows for sparse reading by specifying the sparse_interval and sparse_offset parameters, enabling the reading of data at specified intervals or starting from a specific offset.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
sparse_intervalInterval at which to read rows. A value greater than 1 enables sparse reading.
sparse_offsetNumber of initial rows to skip before starting to read data.
sparse_statisticsFlag indicating whether to compute statistics during sparse reading:
  • 0: No statistics.
  • 1: Compute average.
  • 2: Compute median.
  • 3: Compute minimum.
  • 4: Compute maximum.
Returns
  • Returns the page number on successful read.
  • Returns -1 if the end-of-file is reached.
  • Returns 0 on error.

The function internally calls SDDS_ReadBinaryPageDetailed with the provided parameters to perform the actual reading. It handles various scenarios, including non-native byte orders and different data layouts (row-major or column-major).

Note
  • This function is typically called to read data pages in bulk, allowing for efficient data access by skipping unnecessary rows.
  • Sparse statistics can be used to reduce the amount of data by computing aggregated values.
  • The function assumes that the dataset has been properly initialized and that the file pointers are correctly set up.

Definition at line 2141 of file SDDS_binary.c.

2141 {
2142 return SDDS_ReadBinaryPageDetailed(SDDS_dataset, sparse_interval, sparse_offset, 0, sparse_statistics);
2143}
int32_t SDDS_ReadBinaryPageDetailed(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows, int32_t sparse_statistics)
Reads a binary page from an SDDS dataset with detailed options.

◆ SDDS_ReadBinaryPageDetailed()

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

Reads a binary page from an SDDS dataset with detailed options.

This function reads a binary page from the specified SDDS dataset, providing detailed control over the reading process. It supports sparse reading, reading a specific number of rows from the end, and computing statistics on the data.

Typically, this function is not called directly. Instead, it is invoked through higher-level functions such as SDDS_ReadBinaryPage or SDDS_ReadBinaryPageLastRows, which provide simplified interfaces for common reading scenarios.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
sparse_intervalInterval at which to read rows. A value greater than 1 enables sparse reading.
sparse_offsetNumber of initial rows to skip before starting to read data.
last_rowsThe number of rows to read from the end of the dataset. If 0, all rows are read.
sparse_statisticsFlag indicating whether to compute statistics during sparse reading:
  • 0: No statistics.
  • 1: Compute average.
  • 2: Compute median.
  • 3: Compute minimum.
  • 4: Compute maximum.
Returns
  • Returns the page number on successful read.
  • Returns -1 if the end-of-file is reached.
  • Returns 0 on error.

The function performs the following steps:

  • Checks if the dataset has been auto-recovered; if so, it returns -1.
  • Determines if the dataset uses native or non-native byte order and delegates to SDDS_ReadNonNativePageDetailed if necessary.
  • Initializes file pointers based on the compression format (standard, gzip, LZMA).
  • Allocates and initializes the buffer for reading if not already allocated.
  • Reads the number of rows from the binary file, handling both 32-bit and 64-bit row counts.
  • Validates the row count and ensures it does not exceed predefined limits.
  • Adjusts for column-major layouts by calling SDDS_ReadBinaryColumns if necessary.
  • Handles sparse reading by skipping rows based on sparse_interval and sparse_offset.
  • If sparse_statistics is enabled, computes the specified statistics (average, median, min, max) on floating-point data.
  • Handles errors by setting appropriate error messages and managing recovery modes.
Note
  • This function provides extensive control over the reading process, allowing for optimized data access.
  • Ensure that all parameters are set correctly to avoid unintended data skips or miscomputations.
  • The function assumes that the dataset has been properly initialized and that the file pointers are correctly set up.
  • Compression support (zLib for gzip, LZMA libraries) must be enabled during compilation for handling compressed files.

Definition at line 2223 of file SDDS_binary.c.

2223 {
2224 int32_t n_rows32;
2225 int64_t n_rows, i, j, k, alloc_rows, rows_to_store, mod;
2226
2227 /* int32_t page_number, i; */
2228#if defined(zLib)
2229 gzFile gzfp = NULL;
2230#endif
2231 FILE *fp = NULL;
2232 struct lzmafile *lzmafp = NULL;
2233 SDDS_FILEBUFFER *fBuffer;
2234 void **statData=NULL;
2235 double statResult;
2236
2237 if (SDDS_dataset->autoRecovered)
2238 return -1;
2239 if (SDDS_dataset->swapByteOrder) {
2240 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, 0, sparse_interval, sparse_offset, last_rows);
2241 }
2242
2243 /* static char s[SDDS_MAXLINE]; */
2244 n_rows = 0;
2245 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
2246#if defined(zLib)
2247 if (SDDS_dataset->layout.gzipFile) {
2248 gzfp = SDDS_dataset->layout.gzfp;
2249 } else {
2250#endif
2251 if (SDDS_dataset->layout.lzmaFile) {
2252 lzmafp = SDDS_dataset->layout.lzmafp;
2253 } else {
2254 fp = SDDS_dataset->layout.fp;
2255 }
2256#if defined(zLib)
2257 }
2258#endif
2259 fBuffer = &SDDS_dataset->fBuffer;
2260 if (!fBuffer->buffer) {
2261 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
2262 if (bufferSize == 0 && (SDDS_dataset->layout.popenUsed || !SDDS_dataset->layout.filename) && (sparse_interval > 1 || sparse_offset > 0 || last_rows > 0)) {
2263 SDDS_SetError("The IO buffer size is 0 for data being read from a pipe with sparsing. This is not supported.");
2264 return 0;
2265 }
2266 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (bufferSize + 1)))) {
2267 SDDS_SetError("Unable to do buffered read--allocation failure");
2268 return 0;
2269 }
2270 fBuffer->bufferSize = bufferSize;
2271 fBuffer->bytesLeft = 0;
2272 }
2273 SDDS_dataset->rowcount_offset = -1;
2274#if defined(zLib)
2275 if (SDDS_dataset->layout.gzipFile) {
2276 if (!SDDS_GZipBufferedRead(&n_rows32, sizeof(n_rows32), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2277 if (gzeof(gzfp))
2278 return (SDDS_dataset->page_number = -1);
2279 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2280 return (0);
2281 }
2282 if (n_rows32 == INT32_MIN) {
2283 if (!SDDS_GZipBufferedRead(&n_rows, sizeof(n_rows), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2284 if (gzeof(gzfp))
2285 return (SDDS_dataset->page_number = -1);
2286 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2287 return (0);
2288 }
2289 } else {
2290 n_rows = n_rows32;
2291 }
2292 } else {
2293#endif
2294 /* This value will only be valid if read buffering is turned off, which is done for
2295 * certain append operations! Should really modify SDDS_BufferedRead and SDDS_BufferedWrite
2296 * to provide ftell capability.
2297 */
2298 if (SDDS_dataset->layout.lzmaFile) {
2299 if (!SDDS_LZMABufferedRead(&n_rows32, sizeof(n_rows32), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2300 if (lzma_eof(lzmafp))
2301 return (SDDS_dataset->page_number = -1);
2302 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2303 return (0);
2304 }
2305 if (n_rows32 == INT32_MIN) {
2306 if (!SDDS_LZMABufferedRead(&n_rows, sizeof(n_rows), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2307 if (lzma_eof(lzmafp))
2308 return (SDDS_dataset->page_number = -1);
2309 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2310 return (0);
2311 }
2312 } else {
2313 n_rows = n_rows32;
2314 }
2315 } else {
2316 SDDS_dataset->rowcount_offset = ftell(fp);
2317 if (!SDDS_BufferedRead(&n_rows32, sizeof(n_rows32), fp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2318 if (feof(fp))
2319 return (SDDS_dataset->page_number = -1);
2320 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2321 return (0);
2322 }
2323 if (n_rows32 == INT32_MIN) {
2324 if (!SDDS_BufferedRead(&n_rows, sizeof(n_rows), fp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2325 if (feof(fp))
2326 return (SDDS_dataset->page_number = -1);
2327 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2328 return (0);
2329 }
2330 } else {
2331 n_rows = n_rows32;
2332 }
2333 }
2334#if defined(zLib)
2335 }
2336#endif
2337
2338#if defined(DEBUG)
2339 fprintf(stderr, "Expect %" PRId64 " rows of data\n", n_rows);
2340#endif
2341 if (n_rows < 0) {
2342 SDDS_SetError("Unable to read page--negative number of rows (SDDS_ReadBinaryPageDetailed)");
2343 return (0);
2344 }
2345 if (SDDS_dataset->layout.byteOrderDeclared == 0) {
2346 if (n_rows > 10000000) {
2347 SDDS_SetError("Unable to read page--endian byte order not declared and suspected to be non-native. (SDDS_ReadBinaryPageDetailed)");
2348 return (0);
2349 }
2350 }
2351 if (n_rows > SDDS_GetRowLimit()) {
2352 /* the number of rows is "unreasonably" large---treat like end-of-file */
2353 return (SDDS_dataset->page_number = -1);
2354 }
2355 if (last_rows < 0)
2356 last_rows = 0;
2357 /* Fix this limitation later */
2358
2359 if (last_rows) {
2360 sparse_interval = 1;
2361 sparse_offset = n_rows - last_rows;
2362 }
2363 if (sparse_interval <= 0)
2364 sparse_interval = 1;
2365 if (sparse_offset < 0)
2366 sparse_offset = 0;
2367
2368 rows_to_store = (n_rows - sparse_offset) / sparse_interval + 2;
2369 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
2370
2371 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, alloc_rows)) {
2372 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadBinaryPageDetailed)");
2373 return (0);
2374 }
2375
2376 /* read the parameter values */
2377 if (!SDDS_ReadBinaryParameters(SDDS_dataset)) {
2378 SDDS_SetError("Unable to read page--parameter reading error (SDDS_ReadBinaryPageDetailed)");
2379 return (0);
2380 }
2381
2382 /* read the array values */
2383 if (!SDDS_ReadBinaryArrays(SDDS_dataset)) {
2384 SDDS_SetError("Unable to read page--array reading error (SDDS_ReadBinaryPageDetailed)");
2385 return (0);
2386 }
2387 if (SDDS_dataset->layout.data_mode.column_major) {
2388 SDDS_dataset->n_rows = n_rows;
2389 if (sparse_statistics == 0) {
2390 if (!SDDS_ReadBinaryColumns(SDDS_dataset, sparse_interval, sparse_offset)) {
2391 SDDS_SetError("Unable to read page--column reading error (SDDS_ReadBinaryPageDetailed)");
2392 return (0);
2393 }
2394 return (SDDS_dataset->page_number);
2395 } else {
2396 /* allocate space for full columns if needed */
2397 if (SDDS_dataset->n_rows_allocated < n_rows) {
2398 if (!SDDS_LengthenTable(SDDS_dataset, n_rows - SDDS_dataset->n_rows_allocated)) {
2399 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadBinaryPageDetailed)");
2400 return (0);
2401 }
2402 }
2403 if (!SDDS_ReadBinaryColumns(SDDS_dataset, 1, 0)) {
2404 SDDS_SetError("Unable to read page--column reading error (SDDS_ReadBinaryPageDetailed)");
2405 return (0);
2406 }
2407 statData = (void**)malloc(SDDS_dataset->layout.n_columns * sizeof(void*));
2408 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2409 statData[i] = NULL;
2410 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type))
2411 statData[i] = (double*)calloc(sparse_interval, sizeof(double));
2412 }
2413 n_rows -= sparse_offset;
2414 for (j = k = 0; j < n_rows; j++) {
2415 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2416 switch (SDDS_dataset->layout.column_definition[i].type) {
2417 case SDDS_FLOAT:
2418 if (statData[i])
2419 ((double*)statData[i])[j % sparse_interval] = (double)(((float*)SDDS_dataset->data[i])[j + sparse_offset]);
2420 break;
2421 case SDDS_DOUBLE:
2422 if (statData[i])
2423 ((double*)statData[i])[j % sparse_interval] = ((double*)SDDS_dataset->data[i])[j + sparse_offset];
2424 break;
2425 case SDDS_LONGDOUBLE:
2426 if (statData[i])
2427 ((double*)statData[i])[j % sparse_interval] = (double)(((long double*)SDDS_dataset->data[i])[j + sparse_offset]);
2428 break;
2429 case SDDS_STRING:
2430 if (((char ***)SDDS_dataset->data)[i][k])
2431 free(((char ***)SDDS_dataset->data)[i][k]);
2432 ((char ***)SDDS_dataset->data)[i][k] = ((char ***)SDDS_dataset->data)[i][j + sparse_offset];
2433 ((char ***)SDDS_dataset->data)[i][j + sparse_offset] = NULL;
2434 break;
2435 case SDDS_SHORT:
2436 ((short*)SDDS_dataset->data[i])[k] = ((short*)SDDS_dataset->data[i])[j + sparse_offset];
2437 break;
2438 case SDDS_USHORT:
2439 ((unsigned short*)SDDS_dataset->data[i])[k] = ((unsigned short*)SDDS_dataset->data[i])[j + sparse_offset];
2440 break;
2441 case SDDS_LONG:
2442 ((int32_t*)SDDS_dataset->data[i])[k] = ((int32_t*)SDDS_dataset->data[i])[j + sparse_offset];
2443 break;
2444 case SDDS_ULONG:
2445 ((uint32_t*)SDDS_dataset->data[i])[k] = ((uint32_t*)SDDS_dataset->data[i])[j + sparse_offset];
2446 break;
2447 case SDDS_LONG64:
2448 ((int64_t*)SDDS_dataset->data[i])[k] = ((int64_t*)SDDS_dataset->data[i])[j + sparse_offset];
2449 break;
2450 case SDDS_ULONG64:
2451 ((uint64_t*)SDDS_dataset->data[i])[k] = ((uint64_t*)SDDS_dataset->data[i])[j + sparse_offset];
2452 break;
2453 case SDDS_CHARACTER:
2454 ((char*)SDDS_dataset->data[i])[k] = ((char*)SDDS_dataset->data[i])[j + sparse_offset];
2455 break;
2456 default:
2457 break;
2458 }
2459 if (statData[i]) {
2460 if (sparse_statistics == 1)
2461 compute_average(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2462 else if (sparse_statistics == 2)
2463 compute_median(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2464 else if (sparse_statistics == 3)
2465 statResult = min_in_array((double*)statData[i], (j % sparse_interval) + 1);
2466 else if (sparse_statistics == 4)
2467 statResult = max_in_array((double*)statData[i], (j % sparse_interval) + 1);
2468 switch (SDDS_dataset->layout.column_definition[i].type) {
2469 case SDDS_FLOAT:
2470 ((float*)SDDS_dataset->data[i])[k] = statResult;
2471 break;
2472 case SDDS_DOUBLE:
2473 ((double*)SDDS_dataset->data[i])[k] = statResult;
2474 break;
2475 case SDDS_LONGDOUBLE:
2476 ((long double*)SDDS_dataset->data[i])[k] = statResult;
2477 break;
2478 }
2479 }
2480 }
2481 if (j % sparse_interval == sparse_interval - 1)
2482 k++;
2483 }
2484 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2485 if (SDDS_dataset->layout.column_definition[i].type == SDDS_STRING) {
2486 int64_t r;
2487 for (r = k; r < SDDS_dataset->n_rows; r++) {
2488 if (((char ***)SDDS_dataset->data)[i][r]) {
2489 free(((char ***)SDDS_dataset->data)[i][r]);
2490 ((char ***)SDDS_dataset->data)[i][r] = NULL;
2491 }
2492 }
2493 }
2494 if (statData[i])
2495 free(statData[i]);
2496 }
2497 free(statData);
2498 SDDS_dataset->n_rows = k;
2499 return (SDDS_dataset->page_number);
2500 }
2501 }
2502 if ((sparse_interval <= 1) && (sparse_offset == 0)) {
2503 for (j = 0; j < n_rows; j++) {
2504 if (!SDDS_ReadBinaryRow(SDDS_dataset, j, 0)) {
2505 SDDS_dataset->n_rows = j;
2506 if (SDDS_dataset->autoRecover) {
2507#if defined(DEBUG)
2508 fprintf(stderr, "Doing auto-read recovery\n");
2509#endif
2510 SDDS_dataset->autoRecovered = 1;
2512 return (SDDS_dataset->page_number);
2513 }
2514 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2515 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2516 return (0);
2517 }
2518 }
2519 SDDS_dataset->n_rows = j;
2520 return (SDDS_dataset->page_number);
2521 } else {
2522 for (j = 0; j < sparse_offset; j++) {
2523 if (!SDDS_ReadBinaryRow(SDDS_dataset, 0, 1)) {
2524 SDDS_dataset->n_rows = 0;
2525 if (SDDS_dataset->autoRecover) {
2526 SDDS_dataset->autoRecovered = 1;
2528 return (SDDS_dataset->page_number);
2529 }
2530 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2531 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2532 return (0);
2533 }
2534 }
2535 n_rows -= sparse_offset;
2536 if (sparse_statistics != 0) {
2537 // Allocate buffer space for statistical sparsing
2538 statData = (void**)malloc(SDDS_dataset->layout.n_columns * sizeof(void*));
2539 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2540 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2541 // Not ideal for SDDS_LONGDOUBLE but we may never run across this error
2542 statData[i] = (double*)calloc(sparse_interval, sizeof(double));
2543 }
2544 }
2545 for (j = k = 0; j < n_rows; j++) {
2546 if (!SDDS_ReadBinaryRow(SDDS_dataset, k, 0)) {
2547 SDDS_dataset->n_rows = k;
2548 if (SDDS_dataset->autoRecover) {
2549 SDDS_dataset->autoRecovered = 1;
2551 return (SDDS_dataset->page_number);
2552 }
2553 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2554 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2555 return (0);
2556 }
2557 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2558 switch (SDDS_dataset->layout.column_definition[i].type) {
2559 case SDDS_FLOAT:
2560 ((double*)statData[i])[j % sparse_interval] = (double)(((float*)SDDS_dataset->data[i])[k]);
2561 break;
2562 case SDDS_DOUBLE:
2563 ((double*)statData[i])[j % sparse_interval] = ((double*)SDDS_dataset->data[i])[k];
2564 break;
2565 case SDDS_LONGDOUBLE:
2566 ((double*)statData[i])[j % sparse_interval] = (double)(((long double*)SDDS_dataset->data[i])[k]);
2567 break;
2568 }
2569 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2570 if (sparse_statistics == 1) {
2571 // Sparse and get average statistics
2572 compute_average(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2573 } else if (sparse_statistics == 2) {
2574 // Sparse and get median statistics
2575 compute_median(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2576 } else if (sparse_statistics == 3) {
2577 // Sparse and get minimum statistics
2578 statResult = min_in_array((double*)statData[i], (j % sparse_interval) + 1);
2579 } else if (sparse_statistics == 4) {
2580 // Sparse and get maximum statistics
2581 statResult = max_in_array((double*)statData[i], (j % sparse_interval) + 1);
2582 }
2583 }
2584 switch (SDDS_dataset->layout.column_definition[i].type) {
2585 case SDDS_FLOAT:
2586 ((float*)SDDS_dataset->data[i])[k] = statResult;
2587 break;
2588 case SDDS_DOUBLE:
2589 ((double*)SDDS_dataset->data[i])[k] = statResult;
2590 break;
2591 case SDDS_LONGDOUBLE:
2592 ((long double*)SDDS_dataset->data[i])[k] = statResult;
2593 break;
2594 }
2595 }
2596 if (j % sparse_interval == sparse_interval - 1) {
2597 k++;
2598 }
2599 }
2600 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2601 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2602 free(statData[i]);
2603 }
2604 }
2605 free(statData);
2606 } else {
2607 for (j = k = 0; j < n_rows; j++) {
2608 if (!SDDS_ReadBinaryRow(SDDS_dataset, k, mod = j % sparse_interval)) {
2609 SDDS_dataset->n_rows = k;
2610 if (SDDS_dataset->autoRecover) {
2611 SDDS_dataset->autoRecovered = 1;
2613 return (SDDS_dataset->page_number);
2614 }
2615 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2616 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2617 return (0);
2618 }
2619 k += mod ? 0 : 1;
2620 }
2621 }
2622 SDDS_dataset->n_rows = k;
2623 return (SDDS_dataset->page_number);
2624 }
2625}
int32_t SDDS_ReadBinaryColumns(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset)
Reads the binary columns from an SDDS dataset.
int32_t SDDS_ReadBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
Reads a binary row from the specified SDDS dataset.
void SDDS_SetReadRecoveryMode(SDDS_DATASET *SDDS_dataset, int32_t mode)
Sets the read recovery mode for an SDDS dataset.
int32_t SDDS_ReadNonNativePageDetailed(SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows)
Reads a detailed non-native endian page from an SDDS dataset.
int32_t SDDS_ReadBinaryArrays(SDDS_DATASET *SDDS_dataset)
Reads binary arrays from an SDDS dataset.
int32_t SDDS_ReadBinaryParameters(SDDS_DATASET *SDDS_dataset)
Reads binary parameters from the specified 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()
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:705
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
Definition SDDS_utils.c:354
#define SDDS_FLOATING_TYPE(type)
Checks if the given type identifier corresponds to a floating-point type.
Definition SDDStypes.h:124
double max_in_array(double *array, long n)
Finds the maximum value in an array of doubles.
Definition findMinMax.c:318
double min_in_array(double *array, long n)
Finds the minimum value in an array of doubles.
Definition findMinMax.c:336
long compute_average(double *value, double *data, int64_t n)
Computes the average of an array of doubles.
Definition median.c:152
long compute_median(double *value, double *x, long n)
Computes the median of an array of doubles.
Definition median.c:29

◆ SDDS_ReadBinaryPageLastRows()

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.

This function reads the last last_rows rows from the binary page of the specified SDDS dataset. It is useful for retrieving recent data entries without processing the entire dataset.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
last_rowsThe number of rows to read from the end of the dataset.
Returns
  • Returns the page number on successful read.
  • Returns -1 if the end-of-file is reached.
  • Returns 0 on error.

The function internally calls SDDS_ReadBinaryPageDetailed with sparse_interval set to 1, sparse_offset set to 0, and last_rows as specified. This configuration ensures that only the last last_rows rows are read from the dataset.

Note
  • This function is particularly useful for applications that need to display or process the most recent data entries.
  • Ensure that last_rows does not exceed the total number of rows in the dataset to avoid errors.
  • The function assumes that the dataset has been properly initialized and that the file pointers are correctly set up.

Definition at line 2171 of file SDDS_binary.c.

2171 {
2172 return SDDS_ReadBinaryPageDetailed(SDDS_dataset, 1, 0, last_rows, 0);
2173}

◆ SDDS_ReadBinaryParameters()

int32_t SDDS_ReadBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Reads binary parameters from the specified SDDS dataset.

This function iterates through all the parameters defined in the SDDS dataset layout and reads their values from the underlying file. It handles different data types, including strings, and manages memory allocation for string parameters. Depending on the dataset's compression settings (uncompressed, LZMA, or GZIP), it uses the appropriate reading functions to retrieve the parameter values.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successfully reading all binary parameters, or 0 if an error occurred.
Return values
1All parameters were successfully read and stored.
0An error occurred during the read operation, such as I/O errors, data type mismatches, or memory allocation failures.
Note
Parameters with the 'fixed_value' attribute are handled by scanning the fixed value string instead of reading from the file. String parameters are dynamically allocated and should be freed by the caller when no longer needed.

Definition at line 3072 of file SDDS_binary.c.

3072 {
3073 int32_t i;
3074 SDDS_LAYOUT *layout;
3075 /* char *predefined_format; */
3076 char buffer[SDDS_MAXLINE];
3077#if defined(zLib)
3078 gzFile gzfp = NULL;
3079#endif
3080 FILE *fp = NULL;
3081 struct lzmafile *lzmafp = NULL;
3082 SDDS_FILEBUFFER *fBuffer;
3083
3084 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryParameters"))
3085 return (0);
3086 layout = &SDDS_dataset->layout;
3087 if (!layout->n_parameters)
3088 return (1);
3089#if defined(zLib)
3090 if (SDDS_dataset->layout.gzipFile) {
3091 gzfp = layout->gzfp;
3092 } else {
3093#endif
3094 if (SDDS_dataset->layout.lzmaFile) {
3095 lzmafp = layout->lzmafp;
3096 } else {
3097 fp = layout->fp;
3098 }
3099#if defined(zLib)
3100 }
3101#endif
3102 fBuffer = &SDDS_dataset->fBuffer;
3103 for (i = 0; i < layout->n_parameters; i++) {
3104 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
3105 continue;
3106 if (layout->parameter_definition[i].fixed_value) {
3107 strcpy(buffer, layout->parameter_definition[i].fixed_value);
3108 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
3109 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadBinaryParameters)");
3110 return (0);
3111 }
3112 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
3113 if (*(char **)SDDS_dataset->parameter[i])
3114 free(*(char **)SDDS_dataset->parameter[i]);
3115#if defined(zLib)
3116 if (SDDS_dataset->layout.gzipFile) {
3117 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
3118 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
3119 return (0);
3120 }
3121 } else {
3122#endif
3123 if (SDDS_dataset->layout.lzmaFile) {
3124 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3125 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
3126 return (0);
3127 }
3128 } else {
3129 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3130 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
3131 return (0);
3132 }
3133 }
3134#if defined(zLib)
3135 }
3136#endif
3137 } else {
3138#if defined(zLib)
3139 if (SDDS_dataset->layout.gzipFile) {
3140 if (!SDDS_GZipBufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3141 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3142 return (0);
3143 }
3144 } else {
3145#endif
3146 if (SDDS_dataset->layout.lzmaFile) {
3147 if (!SDDS_LZMABufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3148 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3149 return (0);
3150 }
3151 } else {
3152 if (!SDDS_BufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3153 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3154 return (0);
3155 }
3156 }
3157#if defined(zLib)
3158 }
3159#endif
3160 }
3161 }
3162 return (1);
3163}
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_ReadBinaryRow()

int32_t SDDS_ReadBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
int32_t skip )

Reads a binary row from the specified SDDS dataset.

This function reads a single row of data from the given SDDS dataset. Depending on the dataset's configuration, it handles uncompressed, LZMA-compressed, or GZIP-compressed files. For each column in the dataset, the function reads the appropriate data type. If a column is of type string, it reads the string using the corresponding string reading function. If the 'skip' parameter is set, the function skips reading the data without storing it.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]rowThe row number to read. Must be within the allocated range of rows in the dataset.
[in]skipIf non-zero, the function skips reading the data for each column without storing it.
Returns
int32_t Returns 1 on successful reading of the row, or 0 if an error occurred.
Return values
1The row was successfully read and stored (or skipped).
0An error occurred during reading, such as I/O errors or memory allocation failures.
Note
This function may modify the dataset's data structures by allocating memory for string columns. Ensure that the dataset is properly initialized and that memory is managed appropriately.

Definition at line 2836 of file SDDS_binary.c.

2836 {
2837 int64_t i, type, size;
2838 SDDS_LAYOUT *layout;
2839#if defined(zLib)
2840 gzFile gzfp;
2841#endif
2842 FILE *fp;
2843 struct lzmafile *lzmafp;
2844 SDDS_FILEBUFFER *fBuffer;
2845
2846 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryRow"))
2847 return (0);
2848 layout = &SDDS_dataset->layout;
2849 fBuffer = &SDDS_dataset->fBuffer;
2850
2851#if defined(zLib)
2852 if (SDDS_dataset->layout.gzipFile) {
2853 gzfp = layout->gzfp;
2854 for (i = 0; i < layout->n_columns; i++) {
2855 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2856 continue;
2857 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2858 if (!skip) {
2859 if (((char ***)SDDS_dataset->data)[i][row])
2860 free((((char ***)SDDS_dataset->data)[i][row]));
2861 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
2862 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2863 return (0);
2864 }
2865 } else {
2866 if (!SDDS_ReadGZipBinaryString(gzfp, fBuffer, 1)) {
2867 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2868 return 0;
2869 }
2870 }
2871 } else {
2872 size = SDDS_type_size[type - 1];
2873 if (!SDDS_GZipBufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2874 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2875 return (0);
2876 }
2877 }
2878 }
2879 } else {
2880#endif
2881 if (SDDS_dataset->layout.lzmaFile) {
2882 lzmafp = layout->lzmafp;
2883 for (i = 0; i < layout->n_columns; i++) {
2884 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2885 continue;
2886 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2887 if (!skip) {
2888 if (((char ***)SDDS_dataset->data)[i][row])
2889 free((((char ***)SDDS_dataset->data)[i][row]));
2890 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
2891 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2892 return (0);
2893 }
2894 } else {
2895 if (!SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 1)) {
2896 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2897 return 0;
2898 }
2899 }
2900 } else {
2901 size = SDDS_type_size[type - 1];
2902 if (!SDDS_LZMABufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2903 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2904 return (0);
2905 }
2906 }
2907 }
2908 } else {
2909 fp = layout->fp;
2910 for (i = 0; i < layout->n_columns; i++) {
2911 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2912 continue;
2913 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2914 if (!skip) {
2915 if (((char ***)SDDS_dataset->data)[i][row])
2916 free((((char ***)SDDS_dataset->data)[i][row]));
2917 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
2918 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2919 return (0);
2920 }
2921 } else {
2922 if (!SDDS_ReadBinaryString(fp, fBuffer, 1)) {
2923 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2924 return 0;
2925 }
2926 }
2927 } else {
2928 size = SDDS_type_size[type - 1];
2929 if (!SDDS_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2930 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2931 return (0);
2932 }
2933 }
2934 }
2935 }
2936#if defined(zLib)
2937 }
2938#endif
2939 return (1);
2940}

◆ SDDS_ReadBinaryString()

char * SDDS_ReadBinaryString ( FILE * fp,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Reads a binary string from a file with buffering.

This function reads a binary string from the specified file by first reading the length of the string and then reading the string content based on the length. If the 'skip' parameter is set, the string data is skipped over instead of being stored. The function allocates memory for the string, which should be freed by the caller when no longer needed.

Parameters
[in]fpThe file pointer to read from. Must be an open file in binary read mode.
[in,out]fBufferPointer to the file buffer used for buffered reading operations.
[in]skipIf non-zero, the string data is skipped without being stored.
Returns
char* Returns a pointer to the read null-terminated string on success, or NULL if an error occurred.
Return values
NULLAn error occurred during reading or memory allocation.
Non-NULLPointer to the read string.

Definition at line 2741 of file SDDS_binary.c.

2741 {
2742 int32_t length;
2743 char *string;
2744
2745 if (!SDDS_BufferedRead(&length, sizeof(length), fp, fBuffer, SDDS_LONG, 0) || length < 0)
2746 return (0);
2747 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
2748 return (NULL);
2749 if (length && !SDDS_BufferedRead(skip ? NULL : string, sizeof(*string) * length, fp, fBuffer, SDDS_STRING, 0))
2750 return (NULL);
2751 string[length] = 0;
2752 return (string);
2753}

◆ SDDS_ReadLZMABinaryString()

char * SDDS_ReadLZMABinaryString ( struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Reads a binary string from an LZMA-compressed file with buffering.

This function reads a binary string from the specified LZMA-compressed file by first reading the length of the string and then reading the string content based on the length. If the 'skip' parameter is set, the string data is skipped over instead of being stored. The function allocates memory for the string, which should be freed by the caller when no longer needed.

Parameters
[in]lzmafpThe LZMA file pointer to read from. Must be an open LZMA-compressed file in read mode.
[in,out]fBufferPointer to the file buffer used for buffered reading operations.
[in]skipIf non-zero, the string data is skipped without being stored.
Returns
char* Returns a pointer to the read null-terminated string on success, or NULL if an error occurred.
Return values
NULLAn error occurred during reading or memory allocation.
Non-NULLPointer to the read string.

Definition at line 2771 of file SDDS_binary.c.

2771 {
2772 int32_t length;
2773 char *string;
2774
2775 if (!SDDS_LZMABufferedRead(&length, sizeof(length), lzmafp, fBuffer, SDDS_LONG, 0) || length < 0)
2776 return (0);
2777 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
2778 return (NULL);
2779 if (length && !SDDS_LZMABufferedRead(skip ? NULL : string, sizeof(*string) * length, lzmafp, fBuffer, SDDS_STRING, 0))
2780 return (NULL);
2781 string[length] = 0;
2782 return (string);
2783}

◆ SDDS_ReadNewBinaryRows()

int32_t SDDS_ReadNewBinaryRows ( SDDS_DATASET * SDDS_dataset)

Reads new binary rows from the SDDS dataset.

This function updates the SDDS dataset by reading any new rows that have been added to the underlying file since the last read operation. It verifies that the dataset is in a compatible binary format and ensures that byte order and compression settings are supported. If the number of rows in the file exceeds the currently allocated rows in memory, the function expands the dataset's internal storage to accommodate the new rows.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns the number of new rows successfully read on success, or -1 if an error occurred.
Return values
>0The number of new rows read and added to the dataset.
-1An error occurred during the read operation, such as unsupported file format, I/O errors, or memory allocation failures.
Note
This function does not support MPI parallel I/O, ASCII files, column-major order binary files, non-native byte orders, or compressed files (gzip or lzma). Attempts to use these features will result in an error.

Definition at line 2962 of file SDDS_binary.c.

2962 {
2963 int64_t row, offset, newRows = 0;
2964 int32_t rowsPresent32;
2965 int64_t rowsPresent;
2966
2967#if SDDS_MPI_IO
2968 if (SDDS_dataset->parallel_io) {
2969 SDDS_SetError("Error: MPI mode not supported yet in SDDS_ReadNewBinaryRows");
2970 return -1;
2971 }
2972#endif
2973 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
2974 SDDS_SetError("Error: ASCII files not supported in SDDS_ReadNewBinaryRows");
2975 return -1;
2976 }
2977 if (SDDS_dataset->layout.data_mode.column_major) {
2978 SDDS_SetError("Error: column-major order binary files not supported in SDDS_ReadNewBinaryRows");
2979 return -1;
2980 }
2981 if (SDDS_dataset->swapByteOrder) {
2982 SDDS_SetError("Error: Non-native endian not supported yet in SDDS_ReadNewBinaryRows");
2983 return -1;
2984 }
2985#if defined(zLib)
2986 if (SDDS_dataset->layout.gzipFile) {
2987 SDDS_SetError("Error: gzip compressed files not supported yet in SDDS_ReadNewBinaryRows");
2988 return -1;
2989 } else {
2990#endif
2991 if (SDDS_dataset->layout.lzmaFile) {
2992 SDDS_SetError("Error: lzma compressed files not supported yet in SDDS_ReadNewBinaryRows");
2993 return -1;
2994 }
2995#if defined(zLib)
2996 }
2997#endif
2998
2999 // Read how many rows we have now
3000 offset = ftell(SDDS_dataset->layout.fp);
3001 fseek(SDDS_dataset->layout.fp, SDDS_dataset->rowcount_offset, 0);
3002 if (SDDS_dataset->layout.data_mode.mode == SDDS_BINARY) {
3003 if (fread(&rowsPresent32, sizeof(rowsPresent32), 1, SDDS_dataset->layout.fp) == 0) {
3004 SDDS_SetError("Error: row count not present or not correct length");
3005 return -1;
3006 }
3007 if (SDDS_dataset->swapByteOrder) {
3008 SDDS_SwapLong(&rowsPresent32);
3009 }
3010 if (rowsPresent32 == INT32_MIN) {
3011 if (fread(&rowsPresent, sizeof(rowsPresent), 1, SDDS_dataset->layout.fp) == 0) {
3012 SDDS_SetError("Error: row count not present or not correct length");
3013 return -1;
3014 }
3015 if (SDDS_dataset->swapByteOrder) {
3016 SDDS_SwapLong64(&rowsPresent);
3017 }
3018 } else {
3019 rowsPresent = rowsPresent32;
3020 }
3021 } else {
3022 char buffer[30];
3023 if (!fgets(buffer, 30, SDDS_dataset->layout.fp) || strlen(buffer) != 21 || sscanf(buffer, "%" SCNd64, &rowsPresent) != 1) {
3024 SDDS_SetError("Error: row count not present or not correct length");
3025 return -1;
3026 }
3027 }
3028 fseek(SDDS_dataset->layout.fp, offset, 0);
3029
3030 // If the row count listed in the file is greather than the allocated rows, then lengthen the table in memory
3031 if (rowsPresent > SDDS_dataset->n_rows_allocated) {
3032 if (!SDDS_LengthenTable(SDDS_dataset, rowsPresent + 3)) {
3033 return -1;
3034 }
3035 }
3036
3037 for (row = SDDS_dataset->n_rows; row < rowsPresent; row++) {
3038 if (!SDDS_ReadBinaryRow(SDDS_dataset, row, 0)) {
3039 if (SDDS_dataset->autoRecover) {
3040 row--;
3041 SDDS_dataset->autoRecovered = 1;
3043 break;
3044 }
3045 SDDS_SetError("Unable to read page--error reading data row");
3046 return -1;
3047 }
3048 }
3049 newRows = row + 1 - SDDS_dataset->n_rows;
3050 SDDS_dataset->n_rows = row + 1;
3051 return newRows;
3052}
void SDDS_SwapLong64(int64_t *data)
Swaps the endianness of a 64-bit integer.

◆ SDDS_ReadNonNativeBinaryArrays()

int32_t SDDS_ReadNonNativeBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Reads non-native endian binary arrays from an SDDS dataset.

This function iterates through all array definitions in the specified SDDS dataset and reads their binary data from the underlying file. It handles various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. For string arrays, it reads each string individually, ensuring proper memory allocation and byte order conversion. The function supports different compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. After reading, it swaps the endianness of the array data to match the system's native byte order.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successful reading and byte-swapping of all arrays, or 0 if an error occurred.
Return values
1All non-native endian arrays were successfully read and byte-swapped.
0An error occurred during the read or byte-swapping process, such as I/O failures, memory allocation issues, or corrupted array definitions.
Note
This function modifies the dataset's array data in place. It should be called after successfully opening and preparing the dataset for reading. Ensure that the dataset structure is properly initialized to prevent undefined behavior.

Definition at line 4708 of file SDDS_binary.c.

4708 {
4709 int32_t i, j;
4710 SDDS_LAYOUT *layout;
4711 /* char *predefined_format; */
4712 /* static char buffer[SDDS_MAXLINE]; */
4713#if defined(zLib)
4714 gzFile gzfp = NULL;
4715#endif
4716 FILE *fp = NULL;
4717 struct lzmafile *lzmafp = NULL;
4718 SDDS_ARRAY *array;
4719 SDDS_FILEBUFFER *fBuffer;
4720
4721 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryArrays"))
4722 return (0);
4723 layout = &SDDS_dataset->layout;
4724 if (!layout->n_arrays)
4725 return (1);
4726#if defined(zLib)
4727 if (SDDS_dataset->layout.gzipFile) {
4728 gzfp = layout->gzfp;
4729 } else {
4730#endif
4731 if (SDDS_dataset->layout.lzmaFile) {
4732 lzmafp = layout->lzmafp;
4733 } else {
4734 fp = layout->fp;
4735 }
4736#if defined(zLib)
4737 }
4738#endif
4739 fBuffer = &SDDS_dataset->fBuffer;
4740 if (!SDDS_dataset->array) {
4741 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_ReadNonNativeBinaryArrays)");
4742 return (0);
4743 }
4744 for (i = 0; i < layout->n_arrays; i++) {
4745 array = SDDS_dataset->array + i;
4746 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
4747 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_ReadNonNativeBinaryArrays)");
4748 return (0);
4749 }
4750 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
4751 SDDS_SetError("Unable to read array--definition copy failed (SDDS_ReadNonNativeBinaryArrays)");
4752 return (0);
4753 }
4754 /*if (array->dimension) free(array->dimension); */
4755 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
4756 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadNonNativeBinaryArrays)");
4757 return (0);
4758 }
4759#if defined(zLib)
4760 if (SDDS_dataset->layout.gzipFile) {
4761 if (!SDDS_GZipBufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, gzfp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4762 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4763 return (0);
4764 }
4765 } else {
4766#endif
4767 if (SDDS_dataset->layout.lzmaFile) {
4768 if (!SDDS_LZMABufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, lzmafp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4769 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4770 return (0);
4771 }
4772 } else {
4773 if (!SDDS_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, fp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4774 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4775 return (0);
4776 }
4777 }
4778#if defined(zLib)
4779 }
4780#endif
4781 array->elements = 1;
4782 for (j = 0; j < array->definition->dimensions; j++) {
4783 SDDS_SwapLong(&(array->dimension[j]));
4784 array->elements *= array->dimension[j];
4785 }
4786 if (array->data)
4787 free(array->data);
4788 array->data = array->pointer = NULL;
4789 if (array->elements == 0)
4790 continue;
4791 if (array->elements < 0) {
4792 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_ReadNonNativeBinaryArrays)");
4793 return (0);
4794 }
4795 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
4796 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadNonNativeBinaryArrays)");
4797 return (0);
4798 }
4799 if (array->definition->type == SDDS_STRING) {
4800#if defined(zLib)
4801 if (SDDS_dataset->layout.gzipFile) {
4802 for (j = 0; j < array->elements; j++) {
4803 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4804 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4805 return (0);
4806 }
4807 }
4808 } else {
4809#endif
4810 if (SDDS_dataset->layout.lzmaFile) {
4811 for (j = 0; j < array->elements; j++) {
4812 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4813 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4814 return (0);
4815 }
4816 }
4817 } else {
4818 for (j = 0; j < array->elements; j++) {
4819 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4820 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4821 return (0);
4822 }
4823 }
4824 }
4825#if defined(zLib)
4826 }
4827#endif
4828 } else {
4829#if defined(zLib)
4830 if (SDDS_dataset->layout.gzipFile) {
4831 if (!SDDS_GZipBufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, gzfp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4832 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4833 return (0);
4834 }
4835 } else {
4836#endif
4837 if (SDDS_dataset->layout.lzmaFile) {
4838 if (!SDDS_LZMABufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, lzmafp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4839 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4840 return (0);
4841 }
4842 } else {
4843 if (!SDDS_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, fp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4844 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4845 return (0);
4846 }
4847 }
4848#if defined(zLib)
4849 }
4850#endif
4851 }
4852 }
4853 SDDS_SwapEndsArrayData(SDDS_dataset);
4854 return (1);
4855}
char * SDDS_ReadNonNativeLZMABinaryString(struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Reads a non-native endian binary string from an LZMA-compressed file.
int32_t SDDS_SwapEndsArrayData(SDDS_DATASET *SDDSin)
Swaps the endianness of the array data in an SDDS dataset.
char * SDDS_ReadNonNativeBinaryString(FILE *fp, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Reads a non-native endian binary string from a file.

◆ SDDS_ReadNonNativeBinaryColumns()

int32_t SDDS_ReadNonNativeBinaryColumns ( SDDS_DATASET * SDDS_dataset)

Reads the non-native endian binary columns from an SDDS dataset.

This function is similar to SDDS_ReadBinaryColumns but specifically handles columns with non-native endianness. It iterates through all column definitions within the specified SDDS dataset and reads their binary data from the underlying file, ensuring that the byte order is correctly swapped to match the system's native endianness. The function supports various compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successful reading and byte-swapping of all columns, or 0 if an error occurred.
Return values
1All non-native endian columns were successfully read and byte-swapped.
0An error occurred during the read or byte-swapping operation, such as I/O failures, memory allocation issues, or corrupted column definitions.
Note
This function assumes that the dataset's byte order has been declared and that the underlying file's byte order differs from the system's native byte order. Proper initialization and configuration of the SDDS_dataset structure are required before calling this function.

Definition at line 3590 of file SDDS_binary.c.

3590 {
3591 int64_t i, row;
3592 SDDS_LAYOUT *layout;
3593 /* char *predefined_format; */
3594 /* static char buffer[SDDS_MAXLINE]; */
3595#if defined(zLib)
3596 gzFile gzfp = NULL;
3597#endif
3598 FILE *fp = NULL;
3599 struct lzmafile *lzmafp = NULL;
3600 SDDS_FILEBUFFER *fBuffer;
3601
3602 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryColumns"))
3603 return (0);
3604 layout = &SDDS_dataset->layout;
3605 if (!layout->n_columns || !SDDS_dataset->n_rows)
3606 return (1);
3607#if defined(zLib)
3608 if (SDDS_dataset->layout.gzipFile) {
3609 gzfp = layout->gzfp;
3610 } else {
3611#endif
3612 if (SDDS_dataset->layout.lzmaFile) {
3613 lzmafp = layout->lzmafp;
3614 } else {
3615 fp = layout->fp;
3616 }
3617#if defined(zLib)
3618 }
3619#endif
3620 fBuffer = &SDDS_dataset->fBuffer;
3621
3622 for (i = 0; i < layout->n_columns; i++) {
3623 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
3624 continue;
3625 if (layout->column_definition[i].type == SDDS_STRING) {
3626#if defined(zLib)
3627 if (SDDS_dataset->layout.gzipFile) {
3628 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3629 if (((char ***)SDDS_dataset->data)[i][row])
3630 free((((char ***)SDDS_dataset->data)[i][row]));
3631 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
3632 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumns)");
3633 return (0);
3634 }
3635 }
3636 } else {
3637#endif
3638 if (SDDS_dataset->layout.lzmaFile) {
3639 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3640 if (((char ***)SDDS_dataset->data)[i][row])
3641 free((((char ***)SDDS_dataset->data)[i][row]));
3642 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
3643 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumms)");
3644 return (0);
3645 }
3646 }
3647 } else {
3648 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3649 if (((char ***)SDDS_dataset->data)[i][row])
3650 free((((char ***)SDDS_dataset->data)[i][row]));
3651 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
3652 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumms)");
3653 return (0);
3654 }
3655 }
3656 }
3657#if defined(zLib)
3658 }
3659#endif
3660 } else {
3661#if defined(zLib)
3662 if (SDDS_dataset->layout.gzipFile) {
3663 if (!SDDS_GZipBufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, gzfp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3664 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3665 return (0);
3666 }
3667 } else {
3668#endif
3669 if (SDDS_dataset->layout.lzmaFile) {
3670 if (!SDDS_LZMABufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, lzmafp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3671 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3672 return (0);
3673 }
3674 } else {
3675 if (!SDDS_BufferedRead(SDDS_dataset->data[i], SDDS_type_size[layout->column_definition[i].type - 1] * SDDS_dataset->n_rows, fp, fBuffer, layout->column_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
3676 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3677 return (0);
3678 }
3679 }
3680#if defined(zLib)
3681 }
3682#endif
3683 }
3684 }
3685 return (1);
3686}

◆ SDDS_ReadNonNativeBinaryPage()

int32_t SDDS_ReadNonNativeBinaryPage ( SDDS_DATASET * SDDS_dataset,
int64_t sparse_interval,
int64_t sparse_offset )

Reads a non-native endian binary page from an SDDS dataset.

This function reads a binary page from the specified SDDS dataset, handling data with non-native endianness. It performs necessary byte order conversions to ensure correct data interpretation on the host system. The function supports sparse reading based on the provided interval and offset.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]sparse_intervalInterval between rows to be read for sparsity.
[in]sparse_offsetOffset to start reading rows for sparsity.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function is a wrapper for SDDS_ReadNonNativeBinaryPageDetailed with specific parameters.

Definition at line 4312 of file SDDS_binary.c.

4312 {
4313 return SDDS_ReadNonNativeBinaryPageDetailed(SDDS_dataset, sparse_interval, sparse_offset, 0);
4314}
int32_t SDDS_ReadNonNativeBinaryPageDetailed(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset, int64_t last_rows)
Reads a detailed non-native endian binary page from an SDDS dataset.

◆ SDDS_ReadNonNativeBinaryPageDetailed()

int32_t SDDS_ReadNonNativeBinaryPageDetailed ( SDDS_DATASET * SDDS_dataset,
int64_t sparse_interval,
int64_t sparse_offset,
int64_t last_rows )

Reads a detailed non-native endian binary page from an SDDS dataset.

This function reads a binary page from the specified SDDS dataset, handling data with non-native endianness. It supports both sparse reading and reading of the last few rows based on the provided parameters. The function performs necessary byte order conversions to ensure correct data interpretation on the host system.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]sparse_intervalInterval between rows to be read for sparsity.
[in]sparse_offsetOffset to start reading rows for sparsity.
[in]last_rowsNumber of last rows to read from the dataset.
Returns
int32_t Returns the page number on success, or 0 on failure.
Return values
>0Page number successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function handles various compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. It manages memory allocation for parameters, arrays, and columns, ensuring that data is correctly stored and byte-swapped as necessary. The function also updates the dataset's row count and handles auto-recovery in case of errors.

Definition at line 4361 of file SDDS_binary.c.

4361 {
4362 int32_t n_rows32 = 0;
4363 int64_t n_rows, j, k, alloc_rows, rows_to_store, mod;
4364 /* int32_t page_number, i; */
4365#if defined(zLib)
4366 gzFile gzfp = NULL;
4367#endif
4368 FILE *fp = NULL;
4369 struct lzmafile *lzmafp = NULL;
4370 SDDS_FILEBUFFER *fBuffer;
4371
4372 /* static char s[SDDS_MAXLINE]; */
4373 n_rows = 0;
4374 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
4375#if defined(zLib)
4376 if (SDDS_dataset->layout.gzipFile) {
4377 gzfp = SDDS_dataset->layout.gzfp;
4378 } else {
4379#endif
4380 if (SDDS_dataset->layout.lzmaFile) {
4381 lzmafp = SDDS_dataset->layout.lzmafp;
4382 } else {
4383 fp = SDDS_dataset->layout.fp;
4384 }
4385#if defined(zLib)
4386 }
4387#endif
4388 fBuffer = &SDDS_dataset->fBuffer;
4389 if (!fBuffer->buffer) {
4390 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
4391 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * bufferSize))) {
4392 SDDS_SetError("Unable to do buffered read--allocation failure");
4393 return 0;
4394 }
4395 fBuffer->bufferSize = bufferSize;
4396 fBuffer->bytesLeft = 0;
4397 }
4398 SDDS_dataset->rowcount_offset = -1;
4399#if defined(zLib)
4400 if (SDDS_dataset->layout.gzipFile) {
4401 if (!SDDS_GZipBufferedRead(&n_rows32, sizeof(n_rows32), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4402 if (gzeof(gzfp))
4403 return (SDDS_dataset->page_number = -1);
4404 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4405 return (0);
4406 }
4407 SDDS_SwapLong(&n_rows32);
4408 if (n_rows32 == INT32_MIN) {
4409 if (!SDDS_GZipBufferedRead(&n_rows, sizeof(n_rows), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4410 if (gzeof(gzfp))
4411 return (SDDS_dataset->page_number = -1);
4412 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4413 return (0);
4414 }
4415 SDDS_SwapLong64(&n_rows);
4416 } else {
4417 n_rows = n_rows32;
4418 }
4419 } else {
4420#endif
4421 /* This value will only be valid if read buffering is turned off, which is done for
4422 * certain append operations! Should really modify SDDS_BufferedRead and SDDS_BufferedWrite
4423 * to provide ftell capability.
4424 */
4425 if (SDDS_dataset->layout.lzmaFile) {
4426 if (!SDDS_LZMABufferedRead(&n_rows32, sizeof(n_rows32), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4427 if (lzma_eof(lzmafp))
4428 return (SDDS_dataset->page_number = -1);
4429 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4430 return (0);
4431 }
4432 SDDS_SwapLong(&n_rows32);
4433 if (n_rows32 == INT32_MIN) {
4434 if (!SDDS_LZMABufferedRead(&n_rows, sizeof(n_rows), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4435 if (lzma_eof(lzmafp))
4436 return (SDDS_dataset->page_number = -1);
4437 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4438 return (0);
4439 }
4440 SDDS_SwapLong64(&n_rows);
4441 } else {
4442 n_rows = n_rows32;
4443 }
4444 } else {
4445 SDDS_dataset->rowcount_offset = ftell(fp);
4446 if (!SDDS_BufferedRead(&n_rows32, sizeof(n_rows32), fp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4447 if (feof(fp))
4448 return (SDDS_dataset->page_number = -1);
4449 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4450 return (0);
4451 }
4452 SDDS_SwapLong(&n_rows32);
4453 if (n_rows32 == INT32_MIN) {
4454 if (!SDDS_BufferedRead(&n_rows, sizeof(n_rows), fp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4455 if (feof(fp))
4456 return (SDDS_dataset->page_number = -1);
4457 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4458 return (0);
4459 }
4460 SDDS_SwapLong64(&n_rows);
4461 } else {
4462 n_rows = n_rows32;
4463 }
4464 }
4465#if defined(zLib)
4466 }
4467#endif
4468 if (n_rows < 0) {
4469 SDDS_SetError("Unable to read page--negative number of rows (SDDS_ReadNonNativeBinaryPage)");
4470 return (0);
4471 }
4472 if (last_rows < 0)
4473 last_rows = 0;
4474 /* Fix this limitation later */
4475 if (SDDS_dataset->layout.data_mode.column_major) {
4476 sparse_interval = 1;
4477 sparse_offset = 0;
4478 last_rows = 0;
4479 }
4480 if (last_rows) {
4481 sparse_interval = 1;
4482 sparse_offset = n_rows - last_rows;
4483 rows_to_store = last_rows + 2;
4484 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
4485 }
4486 if (sparse_interval <= 0)
4487 sparse_interval = 1;
4488 if (sparse_offset < 0)
4489 sparse_offset = 0;
4490
4491 rows_to_store = (n_rows - sparse_offset) / sparse_interval + 2;
4492 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
4493 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, alloc_rows)) {
4494 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadNonNativeBinaryPage)");
4495 return (0);
4496 }
4497
4498 /* read the parameter values */
4499 if (!SDDS_ReadNonNativeBinaryParameters(SDDS_dataset)) {
4500 SDDS_SetError("Unable to read page--parameter reading error (SDDS_ReadNonNativeBinaryPage)");
4501 return (0);
4502 }
4503
4504 /* read the array values */
4505 if (!SDDS_ReadNonNativeBinaryArrays(SDDS_dataset)) {
4506 SDDS_SetError("Unable to read page--array reading error (SDDS_ReadNonNativeBinaryPage)");
4507 return (0);
4508 }
4509 if (SDDS_dataset->layout.data_mode.column_major) {
4510 SDDS_dataset->n_rows = n_rows;
4511 if (!SDDS_ReadNonNativeBinaryColumns(SDDS_dataset)) {
4512 SDDS_SetError("Unable to read page--column reading error (SDDS_ReadNonNativeBinaryPage)");
4513 return (0);
4514 }
4515 SDDS_SwapEndsColumnData(SDDS_dataset);
4516 return (SDDS_dataset->page_number);
4517 }
4518 if ((sparse_interval <= 1) && (sparse_offset == 0)) {
4519 for (j = 0; j < n_rows; j++) {
4520 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, j, 0)) {
4521 SDDS_dataset->n_rows = j - 1;
4522 if (SDDS_dataset->autoRecover) {
4524 SDDS_SwapEndsColumnData(SDDS_dataset);
4525 return (SDDS_dataset->page_number);
4526 }
4527 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4528 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4529 return (0);
4530 }
4531 }
4532 SDDS_dataset->n_rows = j;
4533 SDDS_SwapEndsColumnData(SDDS_dataset);
4534 return (SDDS_dataset->page_number);
4535 } else {
4536 for (j = 0; j < sparse_offset; j++) {
4537 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, 0, 1)) {
4538 SDDS_dataset->n_rows = 0;
4539 if (SDDS_dataset->autoRecover) {
4541 SDDS_SwapEndsColumnData(SDDS_dataset);
4542 return (SDDS_dataset->page_number);
4543 }
4544 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4545 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4546 return (0);
4547 }
4548 }
4549 n_rows -= sparse_offset;
4550 for (j = k = 0; j < n_rows; j++) {
4551 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, k, mod = j % sparse_interval)) {
4552 SDDS_dataset->n_rows = k - 1;
4553 if (SDDS_dataset->autoRecover) {
4555 SDDS_SwapEndsColumnData(SDDS_dataset);
4556 return (SDDS_dataset->page_number);
4557 }
4558 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4559 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4560 return (0);
4561 }
4562 k += mod ? 0 : 1;
4563 }
4564 SDDS_dataset->n_rows = k;
4565 SDDS_SwapEndsColumnData(SDDS_dataset);
4566 return (SDDS_dataset->page_number);
4567 }
4568}
int32_t SDDS_SwapEndsColumnData(SDDS_DATASET *SDDSin)
Swaps the endianness of the column data in an SDDS dataset.
int32_t SDDS_ReadNonNativeBinaryColumns(SDDS_DATASET *SDDS_dataset)
Reads the non-native endian binary columns from an SDDS dataset.
int32_t SDDS_ReadNonNativeBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
Reads a non-native endian binary row from an SDDS dataset.
int32_t SDDS_ReadNonNativeBinaryParameters(SDDS_DATASET *SDDS_dataset)
Reads non-native endian binary parameters from an SDDS dataset.
int32_t SDDS_ReadNonNativeBinaryArrays(SDDS_DATASET *SDDS_dataset)
Reads non-native endian binary arrays from an SDDS dataset.

◆ SDDS_ReadNonNativeBinaryPageLastRows()

int32_t SDDS_ReadNonNativeBinaryPageLastRows ( SDDS_DATASET * SDDS_dataset,
int64_t last_rows )

Reads the last few rows from a non-native endian binary page in an SDDS dataset.

This function reads the specified number of last rows from a binary page in the given SDDS dataset, handling data with non-native endianness. It performs necessary byte order conversions to ensure correct data interpretation on the host system.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]last_rowsNumber of last rows to read from the dataset.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function is a wrapper for SDDS_ReadNonNativeBinaryPageDetailed with specific parameters to read the last few rows. It should be used when only the most recent rows are needed.

Definition at line 4334 of file SDDS_binary.c.

4334 {
4335 return SDDS_ReadNonNativeBinaryPageDetailed(SDDS_dataset, 1, 0, last_rows);
4336}

◆ SDDS_ReadNonNativeBinaryParameters()

int32_t SDDS_ReadNonNativeBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Reads non-native endian binary parameters from an SDDS dataset.

This function iterates through all parameter definitions in the specified SDDS dataset and reads their binary data from the underlying file. It handles various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. For string parameters, it reads each string individually, ensuring proper memory allocation and byte order conversion. Parameters with fixed values are processed by scanning the fixed value strings into the appropriate data types. The function supports different compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns 1 on successful reading and byte-swapping of all parameters, or 0 if an error occurred.
Return values
1All non-native endian parameters were successfully read and byte-swapped.
0An error occurred during the read or byte-swapping process, such as I/O failures, memory allocation issues, or corrupted parameter definitions.
Note
This function modifies the dataset's parameter data in place. It should be called after successfully opening and preparing the dataset for reading. Ensure that the dataset structure is properly initialized to prevent undefined behavior.

Definition at line 4592 of file SDDS_binary.c.

4592 {
4593 int32_t i;
4594 SDDS_LAYOUT *layout;
4595 /* char *predefined_format; */
4596 char buffer[SDDS_MAXLINE];
4597#if defined(zLib)
4598 gzFile gzfp = NULL;
4599#endif
4600 FILE *fp = NULL;
4601 struct lzmafile *lzmafp = NULL;
4602 SDDS_FILEBUFFER *fBuffer;
4603
4604 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryParameters"))
4605 return (0);
4606 layout = &SDDS_dataset->layout;
4607 if (!layout->n_parameters)
4608 return (1);
4609#if defined(zLib)
4610 if (SDDS_dataset->layout.gzipFile) {
4611 gzfp = layout->gzfp;
4612 } else {
4613#endif
4614 if (SDDS_dataset->layout.lzmaFile) {
4615 lzmafp = layout->lzmafp;
4616 } else {
4617 fp = layout->fp;
4618 }
4619#if defined(zLib)
4620 }
4621#endif
4622 fBuffer = &SDDS_dataset->fBuffer;
4623 for (i = 0; i < layout->n_parameters; i++) {
4624 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4625 continue;
4626 if (layout->parameter_definition[i].fixed_value) {
4627 strcpy(buffer, layout->parameter_definition[i].fixed_value);
4628 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
4629 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadNonNativeBinaryParameters)");
4630 return (0);
4631 }
4632 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
4633 if (*(char **)SDDS_dataset->parameter[i])
4634 free(*(char **)SDDS_dataset->parameter[i]);
4635#if defined(zLib)
4636 if (SDDS_dataset->layout.gzipFile) {
4637 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4638 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4639 return (0);
4640 }
4641 } else {
4642#endif
4643 if (SDDS_dataset->layout.lzmaFile) {
4644 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4645 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4646 return (0);
4647 }
4648 } else {
4649 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4650 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4651 return (0);
4652 }
4653 }
4654#if defined(zLib)
4655 }
4656#endif
4657 } else {
4658#if defined(zLib)
4659 if (SDDS_dataset->layout.gzipFile) {
4660 if (!SDDS_GZipBufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
4661 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4662 return (0);
4663 }
4664 } else {
4665#endif
4666 if (SDDS_dataset->layout.lzmaFile) {
4667 if (!SDDS_LZMABufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
4668 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4669 return (0);
4670 }
4671 } else {
4672 if (!SDDS_BufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer, layout->parameter_definition[i].type, SDDS_dataset->layout.byteOrderDeclared)) {
4673 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4674 return (0);
4675 }
4676 }
4677#if defined(zLib)
4678 }
4679#endif
4680 }
4681 }
4682 SDDS_SwapEndsParameterData(SDDS_dataset);
4683 return (1);
4684}
int32_t SDDS_SwapEndsParameterData(SDDS_DATASET *SDDSin)
Swaps the endianness of the parameter data in an SDDS dataset.

◆ SDDS_ReadNonNativeBinaryRow()

int32_t SDDS_ReadNonNativeBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
int32_t skip )

Reads a non-native endian binary row from an SDDS dataset.

This function reads a single row of data from the specified SDDS dataset, handling data with non-native endianness. It iterates through all column definitions and reads each column's data for the given row. For string columns, it ensures proper memory allocation and byte order conversion. For other data types, it reads the binary data and performs necessary byte swapping. The function supports different compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]rowThe index of the row to read.
[in]skipIf non-zero, the function will skip reading the row data, useful for sparse reading.
Returns
int32_t Returns 1 on successful reading of the row, or 0 if an error occurred.
Return values
1The row was successfully read and byte-swapped.
0An error occurred during the read or byte-swapping process, such as I/O failures or corrupted data.
Note
This function modifies the dataset's data in place. It should be called after successfully opening and preparing the dataset for reading. Ensure that the dataset structure is properly initialized to prevent undefined behavior.

Definition at line 4878 of file SDDS_binary.c.

4878 {
4879 int64_t i, type, size;
4880 SDDS_LAYOUT *layout;
4881#if defined(zLib)
4882 gzFile gzfp;
4883#endif
4884 FILE *fp;
4885 struct lzmafile *lzmafp;
4886 SDDS_FILEBUFFER *fBuffer;
4887
4888 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryRow"))
4889 return (0);
4890 layout = &SDDS_dataset->layout;
4891 fBuffer = &SDDS_dataset->fBuffer;
4892
4893#if defined(zLib)
4894 if (SDDS_dataset->layout.gzipFile) {
4895 gzfp = layout->gzfp;
4896 for (i = 0; i < layout->n_columns; i++) {
4897 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4898 continue;
4899 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4900 if (!skip) {
4901 if (((char ***)SDDS_dataset->data)[i][row])
4902 free((((char ***)SDDS_dataset->data)[i][row]));
4903 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4904 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4905 return (0);
4906 }
4907 } else {
4908 if (!SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 1)) {
4909 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4910 return 0;
4911 }
4912 }
4913 } else {
4914 size = SDDS_type_size[type - 1];
4915 if (!SDDS_GZipBufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4916 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4917 return (0);
4918 }
4919 }
4920 }
4921 } else {
4922#endif
4923 if (SDDS_dataset->layout.lzmaFile) {
4924 lzmafp = layout->lzmafp;
4925 for (i = 0; i < layout->n_columns; i++) {
4926 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4927 continue;
4928 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4929 if (!skip) {
4930 if (((char ***)SDDS_dataset->data)[i][row])
4931 free((((char ***)SDDS_dataset->data)[i][row]));
4932 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4933 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4934 return (0);
4935 }
4936 } else {
4937 if (!SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 1)) {
4938 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4939 return 0;
4940 }
4941 }
4942 } else {
4943 size = SDDS_type_size[type - 1];
4944 if (!SDDS_LZMABufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4945 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4946 return (0);
4947 }
4948 }
4949 }
4950 } else {
4951 fp = layout->fp;
4952 for (i = 0; i < layout->n_columns; i++) {
4953 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4954 continue;
4955 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4956 if (!skip) {
4957 if (((char ***)SDDS_dataset->data)[i][row])
4958 free((((char ***)SDDS_dataset->data)[i][row]));
4959 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4960 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4961 return (0);
4962 }
4963 } else {
4964 if (!SDDS_ReadNonNativeBinaryString(fp, fBuffer, 1)) {
4965 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4966 return 0;
4967 }
4968 }
4969 } else {
4970 size = SDDS_type_size[type - 1];
4971 if (!SDDS_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4972 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4973 return (0);
4974 }
4975 }
4976 }
4977 }
4978#if defined(zLib)
4979 }
4980#endif
4981 return (1);
4982}

◆ SDDS_ReadNonNativeBinaryString()

char * SDDS_ReadNonNativeBinaryString ( FILE * fp,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Reads a non-native endian binary string from a file.

This function reads a binary string from the specified file pointer, handling non-native endianness. It first reads the length of the string, swaps its byte order if necessary, allocates memory for the string, reads the string data, and null-terminates it.

Parameters
[in]fpPointer to the FILE from which to read the string.
[in,out]fBufferPointer to the SDDS_FILEBUFFER structure used for buffered reading.
[in]skipIf non-zero, the function will skip reading the string data, useful for sparse reading.
Returns
char* Returns a pointer to the read string on success, or NULL if an error occurred.
Return values
Non-NULLPointer to the newly allocated string.
NULLAn error occurred during reading or memory allocation.
Note
The caller is responsible for freeing the returned string to prevent memory leaks.

Definition at line 5001 of file SDDS_binary.c.

5001 {
5002 int32_t length;
5003 char *string;
5004
5005 if (!SDDS_BufferedRead(&length, sizeof(length), fp, fBuffer, SDDS_LONG, 0))
5006 return (0);
5007 SDDS_SwapLong(&length);
5008 if (length < 0)
5009 return (0);
5010 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
5011 return (NULL);
5012 if (length && !SDDS_BufferedRead(skip ? NULL : string, sizeof(*string) * length, fp, fBuffer, SDDS_STRING, 0))
5013 return (NULL);
5014 string[length] = 0;
5015 return (string);
5016}

◆ SDDS_ReadNonNativeLZMABinaryString()

char * SDDS_ReadNonNativeLZMABinaryString ( struct lzmafile * lzmafp,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Reads a non-native endian binary string from an LZMA-compressed file.

This function reads a binary string from the specified LZMA-compressed file pointer, handling non-native endianness. It first reads the length of the string, swaps its byte order if necessary, allocates memory for the string, reads the string data, and null-terminates it.

Parameters
[in]lzmafpPointer to the LZMAFILE from which to read the string.
[in,out]fBufferPointer to the SDDS_FILEBUFFER structure used for buffered reading.
[in]skipIf non-zero, the function will skip reading the string data, useful for sparse reading.
Returns
char* Returns a pointer to the read string on success, or NULL if an error occurred.
Return values
Non-NULLPointer to the newly allocated string.
NULLAn error occurred during reading or memory allocation.
Note
The caller is responsible for freeing the returned string to prevent memory leaks.

Definition at line 5035 of file SDDS_binary.c.

5035 {
5036 int32_t length;
5037 char *string;
5038
5039 if (!SDDS_LZMABufferedRead(&length, sizeof(length), lzmafp, fBuffer, SDDS_LONG, 0))
5040 return (0);
5041 SDDS_SwapLong(&length);
5042 if (length < 0)
5043 return (0);
5044 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
5045 return (NULL);
5046 if (length && !SDDS_LZMABufferedRead(skip ? NULL : string, sizeof(*string) * length, lzmafp, fBuffer, SDDS_STRING, 0))
5047 return (NULL);
5048 string[length] = 0;
5049 return (string);
5050}

◆ SDDS_ReadNonNativePage()

int32_t SDDS_ReadNonNativePage ( SDDS_DATASET * SDDS_dataset)

Reads a non-native endian page from an SDDS dataset.

This function reads a page of data from the specified SDDS dataset, handling data with non-native endianness. It supports both ASCII and binary data modes, performing necessary byte order conversions to ensure correct data interpretation on the host system.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function is a wrapper for SDDS_ReadNonNativePageDetailed with default parameters. It should be used when no specific mode, sparse interval, or offset is required.

Definition at line 4133 of file SDDS_binary.c.

4133 {
4134 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, 0, 1, 0, 0);
4135}

◆ SDDS_ReadNonNativePageDetailed()

int32_t SDDS_ReadNonNativePageDetailed ( SDDS_DATASET * SDDS_dataset,
uint32_t mode,
int64_t sparse_interval,
int64_t sparse_offset,
int64_t last_rows )

Reads a detailed non-native endian page from an SDDS dataset.

This function reads a page of data from the specified SDDS dataset, handling data with non-native endianness. It supports both ASCII and binary data modes, performing necessary byte order conversions to ensure correct data interpretation on the host system. Additionally, it allows for sparse reading and reading of the last few rows based on the provided parameters.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]modeMode flag to support future expansion.
[in]sparse_intervalInterval between rows to be read for sparsity.
[in]sparse_offsetOffset to start reading rows for sparsity.
[in]last_rowsNumber of last rows to read from the dataset.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function handles various compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. It manages memory allocation for parameters, arrays, and columns, ensuring that data is correctly stored and byte-swapped as necessary.

Definition at line 4182 of file SDDS_binary.c.

4184{
4185 int32_t retval;
4186 /* SDDS_LAYOUT layout_copy; */
4187
4188 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativePageDetailed"))
4189 return (0);
4190 if (SDDS_dataset->layout.disconnected) {
4191 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadNonNativePageDetailed)");
4192 return 0;
4193 }
4194#if defined(zLib)
4195 if (SDDS_dataset->layout.gzipFile) {
4196 if (!SDDS_dataset->layout.gzfp) {
4197 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4198 return (0);
4199 }
4200 } else {
4201#endif
4202 if (SDDS_dataset->layout.lzmaFile) {
4203 if (!SDDS_dataset->layout.lzmafp) {
4204 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4205 return (0);
4206 }
4207 } else {
4208 if (!SDDS_dataset->layout.fp) {
4209 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4210 return (0);
4211 }
4212 }
4213#if defined(zLib)
4214 }
4215#endif
4216 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
4217 if ((retval = SDDS_ReadAsciiPage(SDDS_dataset, sparse_interval, sparse_offset, 0)) < 1) {
4218 return (retval);
4219 }
4220 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
4221 if ((retval = SDDS_ReadNonNativeBinaryPage(SDDS_dataset, sparse_interval, sparse_offset)) < 1) {
4222 return (retval);
4223 }
4224 } else {
4225 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadNonNativePageDetailed)");
4226 return (0);
4227 }
4228 return (retval);
4229}
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_ReadNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset, int64_t sparse_interval, int64_t sparse_offset)
Reads a non-native endian binary page from an SDDS dataset.

◆ SDDS_ReadNonNativePageLastRows()

int32_t SDDS_ReadNonNativePageLastRows ( SDDS_DATASET * SDDS_dataset,
int64_t last_rows )

Reads the last few rows from a non-native endian page in an SDDS dataset.

This function reads the specified number of last rows from the non-native endian page of the given SDDS dataset. It handles data with non-native endianness, performing necessary byte order conversions to ensure correct data interpretation on the host system.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]last_rowsNumber of last rows to read from the dataset.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function is a wrapper for SDDS_ReadNonNativePageDetailed with specific parameters to read the last few rows. It should be used when only the most recent rows are needed.

Definition at line 4249 of file SDDS_binary.c.

4249 {
4250 int32_t retval;
4251 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativePageLastRows"))
4252 return (0);
4253 if (SDDS_dataset->layout.disconnected) {
4254 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadNonNativePageLastRows)");
4255 return 0;
4256 }
4257#if defined(zLib)
4258 if (SDDS_dataset->layout.gzipFile) {
4259 if (!SDDS_dataset->layout.gzfp) {
4260 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4261 return (0);
4262 }
4263 } else {
4264#endif
4265 if (SDDS_dataset->layout.lzmaFile) {
4266 if (!SDDS_dataset->layout.lzmafp) {
4267 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4268 return (0);
4269 }
4270 } else {
4271 if (!SDDS_dataset->layout.fp) {
4272 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4273 return (0);
4274 }
4275 }
4276#if defined(zLib)
4277 }
4278#endif
4279 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
4280 if ((retval = SDDS_ReadAsciiPageLastRows(SDDS_dataset, last_rows)) < 1) {
4281 return (retval);
4282 }
4283 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
4284 if ((retval = SDDS_ReadNonNativeBinaryPageLastRows(SDDS_dataset, last_rows)) < 1) {
4285 return (retval);
4286 }
4287 } else {
4288 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadNonNativePageLastRows)");
4289 return (0);
4290 }
4291 return (retval);
4292}
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_ReadNonNativeBinaryPageLastRows(SDDS_DATASET *SDDS_dataset, int64_t last_rows)
Reads the last few rows from a non-native endian binary page in an SDDS dataset.

◆ SDDS_ReadNonNativePageSparse()

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

Reads a sparse non-native endian page from an SDDS dataset.

This function reads a sparse page of data from the specified SDDS dataset, handling data with non-native endianness. Sparse reading allows for selective row retrieval based on the provided interval and offset.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to read from.
[in]modeMode flag to support future expansion.
[in]sparse_intervalInterval between rows to be read for sparsity.
[in]sparse_offsetOffset to start reading rows for sparsity.
Returns
int32_t Returns the number of rows read on success, or 0 on failure.
Return values
>0Number of rows successfully read.
0An error occurred during the read operation, such as I/O failures, data corruption, or unsupported data modes.
Note
This function is a wrapper for SDDS_ReadNonNativePageDetailed with specific parameters to enable sparse reading. It should be used when selective row retrieval is desired.

Definition at line 4155 of file SDDS_binary.c.

4155 {
4156 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, mode, sparse_interval, sparse_offset, 0);
4157}

◆ SDDS_ReadRecoveryPossible()

int32_t SDDS_ReadRecoveryPossible ( SDDS_DATASET * SDDS_dataset)

Checks if any data in an SDDS page was recovered after an error was detected.

This function inspects the SDDS dataset to determine if any data recovery was possible following an error during data reading. It resets the recovery flag after checking.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset.
Returns
  • Returns 1 if recovery was possible.
  • Returns 0 if no recovery was performed or if recovery was not possible.

The function performs the following steps:

  • Retrieves the current state of the readRecoveryPossible flag from the dataset.
  • Resets the readRecoveryPossible flag to 0.
  • Returns the original state of the readRecoveryPossible flag.
Note
  • This function is typically used after attempting to recover from a read error to verify if any partial data was successfully recovered.
  • The recovery flag is automatically managed by other functions within the SDDS library.

Definition at line 2075 of file SDDS_binary.c.

2075 {
2076 int32_t returnValue;
2077
2078 returnValue = SDDS_dataset->readRecoveryPossible;
2079 SDDS_dataset->readRecoveryPossible = 0;
2080 return returnValue;
2081}

◆ SDDS_SetBufferedRead()

int32_t SDDS_SetBufferedRead ( int32_t dummy)

Obsolete routine retained for backward compatibility.

This function no longer performs any operations. Use SDDS_SetDefaultIOBufferSize(0) to disable buffering instead.

Parameters
dummyUnused parameter kept for API compatibility.
Returns
Always returns 0.

Definition at line 65 of file SDDS_binary.c.

65 {
66 return 0;
67}

◆ SDDS_SetDefaultIOBufferSize()

int32_t SDDS_SetDefaultIOBufferSize ( int32_t newValue)

Sets the default I/O buffer size used for file operations.

This function updates the global defaultIOBufferSize variable, which determines the size of the I/O buffer used for file read/write operations. The initial default is SDDS_FILEBUFFER_SIZE, which is 262144 bytes.

Parameters
newValueThe new default I/O buffer size in bytes. If newValue is negative, the function returns the current buffer size without changing it. If newValue is between 0 and 128 (inclusive), it is treated as 0, effectively disabling buffering.
Returns
The previous default I/O buffer size if newValue is greater than or equal to 0; otherwise, returns the current default buffer size without changing it.

Definition at line 82 of file SDDS_binary.c.

82 {
83 int32_t previous;
84 if (newValue < 0)
85 return SDDS_GetLockedDefaultIOBufferSize();
86 if (newValue < 128) /* arbitrary limit */
87 newValue = 0;
88 mdb_thread_lock(&defaultIOBufferSizeLock);
89 previous = defaultIOBufferSize;
90 defaultIOBufferSize = newValue;
91 mdb_thread_unlock(&defaultIOBufferSizeLock);
92 return previous;
93}

◆ SDDS_SetReadRecoveryMode()

void SDDS_SetReadRecoveryMode ( SDDS_DATASET * SDDS_dataset,
int32_t mode )

Sets the read recovery mode for an SDDS dataset.

This function configures whether read recovery is possible for the specified SDDS dataset. Enabling recovery allows the dataset to attempt to recover partial data in case of read errors.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset.
modeInteger flag indicating the recovery mode:
  • 0 to disable read recovery.
  • 1 to enable read recovery.

The function updates the readRecoveryPossible flag within the dataset structure based on the provided mode parameter. This flag is later checked by other functions to determine whether to attempt data recovery after encountering read errors.

Note
  • Enabling read recovery does not guarantee that all data can be recovered after an error.
  • It is recommended to enable recovery only if partial data recovery is acceptable in your application.

Definition at line 2103 of file SDDS_binary.c.

2103 {
2104 SDDS_dataset->readRecoveryPossible = mode;
2105}

◆ SDDS_SwapDouble()

void SDDS_SwapDouble ( double * data)

Swaps the endianness of a double.

This function swaps the byte order of a 64-bit double-precision floating-point number pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the double whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned double.

Definition at line 4083 of file SDDS_binary.c.

4083 {
4084 double copy;
4085 short i, j;
4086 copy = *data;
4087 for (i = 0, j = 7; i < 8; i++, j--)
4088 *(((char *)data) + i) = *(((char *)&copy) + j);
4089}

◆ SDDS_SwapEndsArrayData()

int32_t SDDS_SwapEndsArrayData ( SDDS_DATASET * SDDSin)

Swaps the endianness of the array data in an SDDS dataset.

This function iterates through all arrays defined in the specified SDDS dataset and swaps the byte order of each element to match the system's native endianness. It supports various data types including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. The function ensures that binary data is correctly interpreted on systems with different byte orders.

Parameters
[in,out]SDDSinPointer to the SDDS_DATASET structure representing the dataset whose array data endianness is to be swapped.
Returns
int32_t Always returns 1.
Return values
1The endianness of all applicable array data elements was successfully swapped.
Note
This function modifies the dataset's array data in place. It should be called only when the dataset's byte order is known to differ from the system's native byte order.

Definition at line 3872 of file SDDS_binary.c.

3872 {
3873 int32_t i, j;
3874 SDDS_LAYOUT *layout;
3875 short *sData;
3876 unsigned short *suData;
3877 int32_t *lData;
3878 uint32_t *luData;
3879 int64_t *lData64;
3880 uint64_t *luData64;
3881 float *fData;
3882 double *dData;
3883 long double *ldData;
3884
3885 layout = &SDDSin->layout;
3886
3887 for (i = 0; i < layout->n_arrays; i++) {
3888 switch (layout->array_definition[i].type) {
3889 case SDDS_SHORT:
3890 sData = SDDSin->array[i].data;
3891 for (j = 0; j < SDDSin->array[i].elements; j++)
3892 SDDS_SwapShort(sData + j);
3893 break;
3894 case SDDS_USHORT:
3895 suData = SDDSin->array[i].data;
3896 for (j = 0; j < SDDSin->array[i].elements; j++)
3897 SDDS_SwapUShort(suData + j);
3898 break;
3899 case SDDS_LONG:
3900 lData = SDDSin->array[i].data;
3901 for (j = 0; j < SDDSin->array[i].elements; j++)
3902 SDDS_SwapLong(lData + j);
3903 break;
3904 case SDDS_ULONG:
3905 luData = SDDSin->array[i].data;
3906 for (j = 0; j < SDDSin->array[i].elements; j++)
3907 SDDS_SwapULong(luData + j);
3908 break;
3909 case SDDS_LONG64:
3910 lData64 = SDDSin->array[i].data;
3911 for (j = 0; j < SDDSin->array[i].elements; j++)
3912 SDDS_SwapLong64(lData64 + j);
3913 break;
3914 case SDDS_ULONG64:
3915 luData64 = SDDSin->array[i].data;
3916 for (j = 0; j < SDDSin->array[i].elements; j++)
3917 SDDS_SwapULong64(luData64 + j);
3918 break;
3919 case SDDS_LONGDOUBLE:
3920 ldData = SDDSin->array[i].data;
3921 for (j = 0; j < SDDSin->array[i].elements; j++)
3922 SDDS_SwapLongDouble(ldData + j);
3923 break;
3924 case SDDS_DOUBLE:
3925 dData = SDDSin->array[i].data;
3926 for (j = 0; j < SDDSin->array[i].elements; j++)
3927 SDDS_SwapDouble(dData + j);
3928 break;
3929 case SDDS_FLOAT:
3930 fData = SDDSin->array[i].data;
3931 for (j = 0; j < SDDSin->array[i].elements; j++)
3932 SDDS_SwapFloat(fData + j);
3933 break;
3934 default:
3935 break;
3936 }
3937 }
3938 return (1);
3939}
void SDDS_SwapLongDouble(long double *data)
Swaps the endianness of a long double.
void SDDS_SwapULong64(uint64_t *data)
Swaps the endianness of a 64-bit unsigned integer.
void SDDS_SwapULong(uint32_t *data)
Swaps the endianness of a 32-bit unsigned integer.
void SDDS_SwapUShort(unsigned short *data)
Swaps the endianness of an unsigned short integer.
void SDDS_SwapShort(short *data)
Swaps the endianness of a short integer.
void SDDS_SwapFloat(float *data)
Swaps the endianness of a float.

◆ SDDS_SwapEndsColumnData()

int32_t SDDS_SwapEndsColumnData ( SDDS_DATASET * SDDSin)

Swaps the endianness of the column data in an SDDS dataset.

This function iterates through all columns in the specified SDDS dataset and swaps the byte order of each data element to match the system's native endianness. It supports various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. The function ensures that binary data is correctly interpreted on systems with different byte orders.

Parameters
[in,out]SDDSinPointer to the SDDS_DATASET structure representing the dataset whose column data endianness is to be swapped.
Returns
int32_t Always returns 1.
Return values
1The endianness of all applicable column data elements was successfully swapped.
Note
This function modifies the dataset's column data in place. It should be called only when the dataset's byte order is known to differ from the system's native byte order. String data types are not affected by this function.

Definition at line 3707 of file SDDS_binary.c.

3707 {
3708 int32_t i, row;
3709 SDDS_LAYOUT *layout;
3710 short *sData;
3711 unsigned short *suData;
3712 int32_t *lData;
3713 uint32_t *luData;
3714 int64_t *lData64;
3715 uint64_t *luData64;
3716 float *fData;
3717 double *dData;
3718 long double *ldData;
3719
3720 layout = &SDDSin->layout;
3721 for (i = 0; i < layout->n_columns; i++) {
3722 switch (layout->column_definition[i].type) {
3723 case SDDS_SHORT:
3724 sData = SDDSin->data[i];
3725 for (row = 0; row < SDDSin->n_rows; row++)
3726 SDDS_SwapShort(sData + row);
3727 break;
3728 case SDDS_USHORT:
3729 suData = SDDSin->data[i];
3730 for (row = 0; row < SDDSin->n_rows; row++)
3731 SDDS_SwapUShort(suData + row);
3732 break;
3733 case SDDS_LONG:
3734 lData = SDDSin->data[i];
3735 for (row = 0; row < SDDSin->n_rows; row++)
3736 SDDS_SwapLong(lData + row);
3737 break;
3738 case SDDS_ULONG:
3739 luData = SDDSin->data[i];
3740 for (row = 0; row < SDDSin->n_rows; row++)
3741 SDDS_SwapULong(luData + row);
3742 break;
3743 case SDDS_LONG64:
3744 lData64 = SDDSin->data[i];
3745 for (row = 0; row < SDDSin->n_rows; row++)
3746 SDDS_SwapLong64(lData64 + row);
3747 break;
3748 case SDDS_ULONG64:
3749 luData64 = SDDSin->data[i];
3750 for (row = 0; row < SDDSin->n_rows; row++)
3751 SDDS_SwapULong64(luData64 + row);
3752 break;
3753 case SDDS_LONGDOUBLE:
3754 ldData = SDDSin->data[i];
3755 for (row = 0; row < SDDSin->n_rows; row++)
3756 SDDS_SwapLongDouble(ldData + row);
3757 break;
3758 case SDDS_DOUBLE:
3759 dData = SDDSin->data[i];
3760 for (row = 0; row < SDDSin->n_rows; row++)
3761 SDDS_SwapDouble(dData + row);
3762 break;
3763 case SDDS_FLOAT:
3764 fData = SDDSin->data[i];
3765 for (row = 0; row < SDDSin->n_rows; row++)
3766 SDDS_SwapFloat(fData + row);
3767 break;
3768 default:
3769 break;
3770 }
3771 }
3772 return (1);
3773}

◆ SDDS_SwapEndsParameterData()

int32_t SDDS_SwapEndsParameterData ( SDDS_DATASET * SDDSin)

Swaps the endianness of the parameter data in an SDDS dataset.

This function iterates through all parameters in the specified SDDS dataset and swaps the byte order of each data element to match the system's native endianness. It handles various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. Parameters with fixed values are skipped as their byte order is already consistent.

Parameters
[in,out]SDDSinPointer to the SDDS_DATASET structure representing the dataset whose parameter data endianness is to be swapped.
Returns
int32_t Always returns 1.
Return values
1The endianness of all applicable parameter data elements was successfully swapped.
Note
This function modifies the dataset's parameter data in place. It should be called only when the dataset's byte order is known to differ from the system's native byte order. String data types and parameters with fixed values are not affected by this function.

Definition at line 3793 of file SDDS_binary.c.

3793 {
3794 int32_t i;
3795 SDDS_LAYOUT *layout;
3796 short *sData;
3797 unsigned short *suData;
3798 int32_t *lData;
3799 uint32_t *luData;
3800 int64_t *lData64;
3801 uint64_t *luData64;
3802 float *fData;
3803 double *dData;
3804 long double *ldData;
3805
3806 layout = &SDDSin->layout;
3807 for (i = 0; i < layout->n_parameters; i++) {
3808 if (layout->parameter_definition[i].fixed_value) {
3809 continue;
3810 }
3811 switch (layout->parameter_definition[i].type) {
3812 case SDDS_SHORT:
3813 sData = SDDSin->parameter[i];
3814 SDDS_SwapShort(sData);
3815 break;
3816 case SDDS_USHORT:
3817 suData = SDDSin->parameter[i];
3818 SDDS_SwapUShort(suData);
3819 break;
3820 case SDDS_LONG:
3821 lData = SDDSin->parameter[i];
3822 SDDS_SwapLong(lData);
3823 break;
3824 case SDDS_ULONG:
3825 luData = SDDSin->parameter[i];
3826 SDDS_SwapULong(luData);
3827 break;
3828 case SDDS_LONG64:
3829 lData64 = SDDSin->parameter[i];
3830 SDDS_SwapLong64(lData64);
3831 break;
3832 case SDDS_ULONG64:
3833 luData64 = SDDSin->parameter[i];
3834 SDDS_SwapULong64(luData64);
3835 break;
3836 case SDDS_LONGDOUBLE:
3837 ldData = SDDSin->parameter[i];
3838 SDDS_SwapLongDouble(ldData);
3839 break;
3840 case SDDS_DOUBLE:
3841 dData = SDDSin->parameter[i];
3842 SDDS_SwapDouble(dData);
3843 break;
3844 case SDDS_FLOAT:
3845 fData = SDDSin->parameter[i];
3846 SDDS_SwapFloat(fData);
3847 break;
3848 default:
3849 break;
3850 }
3851 }
3852 return (1);
3853}

◆ SDDS_SwapFloat()

void SDDS_SwapFloat ( float * data)

Swaps the endianness of a float.

This function swaps the byte order of a 32-bit floating-point number pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the float whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned float.

Definition at line 4064 of file SDDS_binary.c.

4064 {
4065 float copy;
4066 short i, j;
4067 copy = *data;
4068 for (i = 0, j = 3; i < 4; i++, j--)
4069 *(((char *)data) + i) = *(((char *)&copy) + j);
4070}

◆ SDDS_SwapLong()

void SDDS_SwapLong ( int32_t * data)

Swaps the endianness of a 32-bit integer.

This function swaps the byte order of a 32-bit integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the 32-bit integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 32-bit integer.

Definition at line 3988 of file SDDS_binary.c.

3988 {
3989 int32_t copy;
3990 short i, j;
3991 copy = *data;
3992 for (i = 0, j = 3; i < 4; i++, j--)
3993 *(((char *)data) + i) = *(((char *)&copy) + j);
3994}

◆ SDDS_SwapLong64()

void SDDS_SwapLong64 ( int64_t * data)

Swaps the endianness of a 64-bit integer.

This function swaps the byte order of a 64-bit integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the 64-bit integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 64-bit integer.

Definition at line 4026 of file SDDS_binary.c.

4026 {
4027 int64_t copy;
4028 short i, j;
4029 copy = *data;
4030 for (i = 0, j = 7; i < 8; i++, j--)
4031 *(((char *)data) + i) = *(((char *)&copy) + j);
4032}

◆ SDDS_SwapLongDouble()

void SDDS_SwapLongDouble ( long double * data)

Swaps the endianness of a long double.

This function swaps the byte order of a long double floating-point number pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats. The function accounts for different sizes of long double based on the system's architecture.

Parameters
[in,out]dataPointer to the long double whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned long double. The size of long double may vary between different systems.

Definition at line 4103 of file SDDS_binary.c.

4103 {
4104 long double copy;
4105 short i, j;
4106 copy = *data;
4107 if (LDBL_DIG == 18) {
4108 for (i = 0, j = 11; i < 12; i++, j--)
4109 *(((char *)data) + i) = *(((char *)&copy) + j);
4110 } else {
4111 for (i = 0, j = 7; i < 8; i++, j--)
4112 *(((char *)data) + i) = *(((char *)&copy) + j);
4113 }
4114}

◆ SDDS_SwapShort()

void SDDS_SwapShort ( short * data)

Swaps the endianness of a short integer.

This function swaps the byte order of a 16-bit short integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the short integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 16-bit short integer.

Definition at line 3952 of file SDDS_binary.c.

3952 {
3953 unsigned char c1;
3954 c1 = *((char *)data);
3955 *((char *)data) = *(((char *)data) + 1);
3956 *(((char *)data) + 1) = c1;
3957}

◆ SDDS_SwapULong()

void SDDS_SwapULong ( uint32_t * data)

Swaps the endianness of a 32-bit unsigned integer.

This function swaps the byte order of a 32-bit unsigned integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the 32-bit unsigned integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 32-bit unsigned integer.

Definition at line 4007 of file SDDS_binary.c.

4007 {
4008 uint32_t copy;
4009 short i, j;
4010 copy = *data;
4011 for (i = 0, j = 3; i < 4; i++, j--)
4012 *(((char *)data) + i) = *(((char *)&copy) + j);
4013}

◆ SDDS_SwapULong64()

void SDDS_SwapULong64 ( uint64_t * data)

Swaps the endianness of a 64-bit unsigned integer.

This function swaps the byte order of a 64-bit unsigned integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the 64-bit unsigned integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 64-bit unsigned integer.

Definition at line 4045 of file SDDS_binary.c.

4045 {
4046 uint64_t copy;
4047 short i, j;
4048 copy = *data;
4049 for (i = 0, j = 7; i < 8; i++, j--)
4050 *(((char *)data) + i) = *(((char *)&copy) + j);
4051}

◆ SDDS_SwapUShort()

void SDDS_SwapUShort ( unsigned short * data)

Swaps the endianness of an unsigned short integer.

This function swaps the byte order of a 16-bit unsigned short integer pointed to by the provided data pointer. It effectively converts the data between little-endian and big-endian formats.

Parameters
[in,out]dataPointer to the unsigned short integer whose byte order is to be swapped.
Note
The function modifies the data in place. Ensure that the pointer is valid and points to a properly aligned 16-bit unsigned short integer.

Definition at line 3970 of file SDDS_binary.c.

3970 {
3971 unsigned char c1;
3972 c1 = *((char *)data);
3973 *((char *)data) = *(((char *)data) + 1);
3974 *(((char *)data) + 1) = c1;
3975}

◆ SDDS_UpdateBinaryPage()

int32_t SDDS_UpdateBinaryPage ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Updates the binary page of an SDDS dataset.

This function updates the binary page of the specified SDDS dataset based on the provided mode. It handles writing the dataset's binary data to the associated file, managing buffering, and handling different file formats such as gzip and LZMA if applicable.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to update.
modeBitmask indicating the update mode. It can be:
  • 0 for a standard update.
  • FLUSH_TABLE to flush the table after updating.
Returns
  • Returns 1 on successful update.
  • Returns 0 if an error occurs during the update process.

The function performs several checks before updating:

  • Checks the environment variable SDDS_OUTPUT_ENDIANESS to determine if a non-native binary update is required.
  • Validates the dataset structure.
  • Ensures that the dataset is not using gzip or LZMA compression, or is not in column-major data mode.
  • Handles writing the binary page, updating row counts, and managing buffer flushing.
Note
  • The function is not thread-safe and should be called in a synchronized context.
  • Requires that the dataset has been properly initialized and populated with data.

Definition at line 1098 of file SDDS_binary.c.

1098 {
1099 FILE *fp;
1100 int64_t i, rows, offset, code, fixed_rows;
1101 int32_t min32 = INT32_MIN, rows32;
1102 SDDS_FILEBUFFER *fBuffer;
1103 char *outputEndianess = NULL;
1104
1105 if ((outputEndianess = getenv("SDDS_OUTPUT_ENDIANESS"))) {
1106 if (((strncmp(outputEndianess, "big", 3) == 0) && (SDDS_IsBigEndianMachine() == 0)) || ((strncmp(outputEndianess, "little", 6) == 0) && (SDDS_IsBigEndianMachine() == 1)))
1107 return SDDS_UpdateNonNativeBinaryPage(SDDS_dataset, mode);
1108 }
1109
1110#ifdef DEBUG
1111 fprintf(stderr, "%" PRId64 " virtual rows present, first=%" PRId64 "\n", SDDS_CountRowsOfInterest(SDDS_dataset), SDDS_dataset->first_row_in_mem);
1112#endif
1113 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_UpdateBinaryPage"))
1114 return (0);
1115#if defined(zLib)
1116 if (SDDS_dataset->layout.gzipFile) {
1117 SDDS_SetError("Unable to perform page updates on a gzip file (SDDS_UpdateBinaryPage)");
1118 return 0;
1119 }
1120#endif
1121 if (SDDS_dataset->layout.lzmaFile) {
1122 SDDS_SetError("Unable to perform page updates on an .lzma or .xz file (SDDS_UpdateBinaryPage)");
1123 return 0;
1124 }
1125 if (SDDS_dataset->layout.data_mode.column_major) {
1126 SDDS_SetError("Unable to perform page updates on column major order file. (SDDS_UpdateBinaryPage)");
1127 return 0;
1128 }
1129 if (!SDDS_dataset->writing_page) {
1130#ifdef DEBUG
1131 fprintf(stderr, "Page not being written---calling SDDS_UpdateBinaryPage\n");
1132#endif
1133 if (!(code = SDDS_WriteBinaryPage(SDDS_dataset)))
1134 return 0;
1135 if (mode & FLUSH_TABLE) {
1136 SDDS_FreeTableStrings(SDDS_dataset);
1137 SDDS_dataset->first_row_in_mem = SDDS_CountRowsOfInterest(SDDS_dataset);
1138 SDDS_dataset->last_row_written = -1;
1139 SDDS_dataset->n_rows = 0;
1140 }
1141 return code;
1142 }
1143
1144 if (!(fp = SDDS_dataset->layout.fp)) {
1145 SDDS_SetError("Unable to update page--file pointer is NULL (SDDS_UpdateBinaryPage)");
1146 return (0);
1147 }
1148 fBuffer = &SDDS_dataset->fBuffer;
1149 if (!SDDS_FlushBuffer(fp, fBuffer)) {
1150 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateBinaryPage)");
1151 return 0;
1152 }
1153 offset = ftell(fp);
1154
1155 rows = SDDS_CountRowsOfInterest(SDDS_dataset) + SDDS_dataset->first_row_in_mem;
1156#ifdef DEBUG
1157 fprintf(stderr, "%" PRId64 " rows stored in table, %" PRId64 " already written\n", rows, SDDS_dataset->n_rows_written);
1158#endif
1159 if (rows == SDDS_dataset->n_rows_written)
1160 return (1);
1161 if (rows < SDDS_dataset->n_rows_written) {
1162 SDDS_SetError("Unable to update page--new number of rows less than previous number (SDDS_UpdateBinaryPage)");
1163 return (0);
1164 }
1165 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))) {
1166 if (SDDS_fseek(fp, SDDS_dataset->rowcount_offset, 0) == -1) {
1167 SDDS_SetError("Unable to update page--failure doing fseek (SDDS_UpdateBinaryPage)");
1168 return (0);
1169 }
1170 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
1171 if ((rows - SDDS_dataset->n_rows_written) + 1 > SDDS_dataset->layout.data_mode.fixed_row_increment) {
1172 SDDS_dataset->layout.data_mode.fixed_row_increment = (rows - SDDS_dataset->n_rows_written) + 1;
1173 }
1174 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
1175#if defined(DEBUG)
1176 fprintf(stderr, "Setting %" PRId64 " fixed rows\n", fixed_rows);
1177#endif
1178 if ((fixed_rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
1179 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateBinaryPage)");
1180 return (0);
1181 }
1182 if (fixed_rows > INT32_MAX) {
1183 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
1184 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1185 return (0);
1186 }
1187 if (fwrite(&fixed_rows, sizeof(fixed_rows), 1, fp) != 1) {
1188 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1189 return (0);
1190 }
1191 } else {
1192 rows32 = (int32_t)fixed_rows;
1193 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
1194 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1195 return (0);
1196 }
1197 }
1198 } else {
1199#if defined(DEBUG)
1200 fprintf(stderr, "Setting %" PRId64 " rows\n", rows);
1201#endif
1202 if ((rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
1203 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateBinaryPage)");
1204 return (0);
1205 }
1206 if (rows > INT32_MAX) {
1207 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
1208 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1209 return (0);
1210 }
1211 if (fwrite(&rows, sizeof(rows), 1, fp) != 1) {
1212 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1213 return (0);
1214 }
1215 } else {
1216 rows32 = (int32_t)rows;
1217 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
1218 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
1219 return (0);
1220 }
1221 }
1222 }
1223 if (SDDS_fseek(fp, offset, 0) == -1) {
1224 SDDS_SetError("Unable to update page--failure doing fseek to end of page (SDDS_UpdateBinaryPage)");
1225 return (0);
1226 }
1227 }
1228 for (i = SDDS_dataset->last_row_written + 1; i < SDDS_dataset->n_rows; i++)
1229 if (SDDS_dataset->row_flag[i] && !SDDS_WriteBinaryRow(SDDS_dataset, i)) {
1230 SDDS_SetError("Unable to update page--failure writing row (SDDS_UpdateBinaryPage)");
1231 return (0);
1232 }
1233#ifdef DEBUG
1234 fprintf(stderr, "Flushing buffer\n");
1235#endif
1236 if (!SDDS_FlushBuffer(fp, fBuffer)) {
1237 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateBinaryPage)");
1238 return 0;
1239 }
1240 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
1241 SDDS_dataset->n_rows_written = rows;
1242 if (mode & FLUSH_TABLE) {
1243 SDDS_FreeTableStrings(SDDS_dataset);
1244 SDDS_dataset->first_row_in_mem = rows;
1245 SDDS_dataset->last_row_written = -1;
1246 SDDS_dataset->n_rows = 0;
1247 }
1248 return (1);
1249}
int32_t SDDS_UpdateNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset, uint32_t mode)
Updates a non-native endian binary page in an SDDS dataset.
int32_t SDDS_WriteBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row)
Writes a single binary row of an SDDS dataset to the associated file.
int32_t SDDS_FlushBuffer(FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_WriteBinaryPage(SDDS_DATASET *SDDS_dataset)
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)
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.

◆ SDDS_UpdateNonNativeBinaryPage()

int32_t SDDS_UpdateNonNativeBinaryPage ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Updates a non-native endian binary page in an SDDS dataset.

This function updates an existing binary page in the specified SDDS dataset, handling byte order reversal to convert between little-endian and big-endian formats. It supports updating rows based on the provided mode flags, such as flushing the table. The function ensures that the buffer is flushed before performing the update and writes any new rows that have been flagged for writing. It also handles fixed row counts and manages byte order conversions as necessary.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to update.
[in]modeBitmask indicating the update mode (e.g., FLUSH_TABLE).
Returns
int32_t Returns 1 on successful update of the binary page, or 0 if an error occurred.
Return values
1The binary page was successfully updated and byte-swapped.
0An error occurred during the update operation, such as I/O failures, invalid row counts, or corrupted dataset definitions.
Note
This function modifies the dataset's internal structures during the update process. Ensure that the dataset is properly initialized and opened for writing before invoking this function. After updating, the dataset's state is updated to reflect the changes made to the page.

Definition at line 5844 of file SDDS_binary.c.

5844 {
5845 FILE *fp;
5846 int32_t code, min32 = INT32_MIN, rows32;
5847 int64_t i, rows, offset, fixed_rows;
5848 SDDS_FILEBUFFER *fBuffer;
5849
5850 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_UpdateNonNativeBinaryPage"))
5851 return (0);
5852#if defined(zLib)
5853 if (SDDS_dataset->layout.gzipFile) {
5854 SDDS_SetError("Unable to perform page updates on a gzip file (SDDS_UpdateNonNativeBinaryPage)");
5855 return 0;
5856 }
5857#endif
5858 if (SDDS_dataset->layout.lzmaFile) {
5859 SDDS_SetError("Unable to perform page updates on .lzma or .xz files (SDDS_UpdateNonNativeBinaryPage)");
5860 return 0;
5861 }
5862 if (SDDS_dataset->layout.data_mode.column_major) {
5863 SDDS_SetError("Unable to perform page updates on a column major order file (SDDS_UpdateNonNativeBinaryPage)");
5864 return 0;
5865 }
5866 if (!SDDS_dataset->writing_page) {
5867#ifdef DEBUG
5868 fprintf(stderr, "Page not being written---calling SDDS_UpdateNonNativeBinaryPage\n");
5869#endif
5870 if (!(code = SDDS_WriteNonNativeBinaryPage(SDDS_dataset))) {
5871 return 0;
5872 }
5873 if (mode & FLUSH_TABLE) {
5874 SDDS_FreeTableStrings(SDDS_dataset);
5875 SDDS_dataset->first_row_in_mem = SDDS_CountRowsOfInterest(SDDS_dataset);
5876 SDDS_dataset->last_row_written = -1;
5877 SDDS_dataset->n_rows = 0;
5878 }
5879 return code;
5880 }
5881
5882 if (!(fp = SDDS_dataset->layout.fp)) {
5883 SDDS_SetError("Unable to update page--file pointer is NULL (SDDS_UpdateNonNativeBinaryPage)");
5884 return (0);
5885 }
5886 fBuffer = &SDDS_dataset->fBuffer;
5887 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5888 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateNonNativeBinaryPage)");
5889 return 0;
5890 }
5891 offset = ftell(fp);
5892
5893 rows = SDDS_CountRowsOfInterest(SDDS_dataset) + SDDS_dataset->first_row_in_mem;
5894#ifdef DEBUG
5895 fprintf(stderr, "%" PRId64 " rows stored in table, %" PRId32 " already written\n", rows, SDDS_dataset->n_rows_written);
5896#endif
5897 if (rows == SDDS_dataset->n_rows_written) {
5898 return (1);
5899 }
5900 if (rows < SDDS_dataset->n_rows_written) {
5901 SDDS_SetError("Unable to update page--new number of rows less than previous number (SDDS_UpdateNonNativeBinaryPage)");
5902 return (0);
5903 }
5904 SDDS_SwapLong(&min32);
5905 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))) {
5906 if (SDDS_fseek(fp, SDDS_dataset->rowcount_offset, 0) == -1) {
5907 SDDS_SetError("Unable to update page--failure doing fseek (SDDS_UpdateNonNativeBinaryPage)");
5908 return (0);
5909 }
5910 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5911 if ((rows - SDDS_dataset->n_rows_written) + 1 > SDDS_dataset->layout.data_mode.fixed_row_increment) {
5912 SDDS_dataset->layout.data_mode.fixed_row_increment = (rows - SDDS_dataset->n_rows_written) + 1;
5913 }
5914 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5915#if defined(DEBUG)
5916 fprintf(stderr, "Setting %" PRId64 " fixed rows\n", fixed_rows);
5917#endif
5918 if ((fixed_rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
5919 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateNonNativeBinaryPage)");
5920 return (0);
5921 }
5922 if (fixed_rows > INT32_MAX) {
5923 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
5924 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
5925 return (0);
5926 }
5927 SDDS_SwapLong64(&fixed_rows);
5928 if (fwrite(&fixed_rows, sizeof(fixed_rows), 1, fp) != 1) {
5929 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5930 return (0);
5931 }
5932 SDDS_SwapLong64(&fixed_rows);
5933 } else {
5934 rows32 = (int32_t)fixed_rows;
5935 SDDS_SwapLong(&rows32);
5936 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
5937 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5938 return (0);
5939 }
5940 }
5941 } else {
5942#if defined(DEBUG)
5943 fprintf(stderr, "Setting %" PRId64 " rows\n", rows);
5944#endif
5945 if ((rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
5946 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateNonNativeBinaryPage)");
5947 return (0);
5948 }
5949 if (rows > INT32_MAX) {
5950 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
5951 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
5952 return (0);
5953 }
5954 SDDS_SwapLong64(&rows);
5955 if (fwrite(&rows, sizeof(rows), 1, fp) != 1) {
5956 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5957 return (0);
5958 }
5959 SDDS_SwapLong64(&rows);
5960 } else {
5961 rows32 = (int32_t)rows;
5962 SDDS_SwapLong(&rows32);
5963 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
5964 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5965 return (0);
5966 }
5967 }
5968 }
5969 if (SDDS_fseek(fp, offset, 0) == -1) {
5970 SDDS_SetError("Unable to update page--failure doing fseek to end of page (SDDS_UpdateNonNativeBinaryPage)");
5971 return (0);
5972 }
5973 }
5974 SDDS_SwapEndsColumnData(SDDS_dataset);
5975 for (i = SDDS_dataset->last_row_written + 1; i < SDDS_dataset->n_rows; i++) {
5976 if (SDDS_dataset->row_flag[i] && !SDDS_WriteNonNativeBinaryRow(SDDS_dataset, i)) {
5977 SDDS_SetError("Unable to update page--failure writing row (SDDS_UpdateNonNativeBinaryPage)");
5978 return (0);
5979 }
5980 }
5981 SDDS_SwapEndsColumnData(SDDS_dataset);
5982#ifdef DEBUG
5983 fprintf(stderr, "Flushing buffer\n");
5984#endif
5985 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5986 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateNonNativeBinaryPage)");
5987 return 0;
5988 }
5989 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
5990 SDDS_dataset->n_rows_written = rows;
5991 if (mode & FLUSH_TABLE) {
5992 SDDS_FreeTableStrings(SDDS_dataset);
5993 SDDS_dataset->first_row_in_mem = rows;
5994 SDDS_dataset->last_row_written = -1;
5995 SDDS_dataset->n_rows = 0;
5996 }
5997 return (1);
5998}
int32_t SDDS_WriteNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset)
Writes a non-native endian binary page to an SDDS dataset.
int32_t SDDS_WriteNonNativeBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row)
Writes a non-native endian binary row to an SDDS dataset.

◆ SDDS_WriteBinaryArrays()

int32_t SDDS_WriteBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Writes the binary arrays of the SDDS dataset to a file.

This function writes all arrays defined in the SDDS dataset to the associated binary file. It handles arrays with and without dimensions, and manages different compression formats such as gzip and LZMA if enabled.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure containing the dataset to write.
Returns
  • Returns 1 on successful write of all arrays.
  • Returns 0 if an error occurs during the writing process.

The function performs the following steps:

  • Validates the dataset structure.
  • Iterates over all arrays defined in the dataset layout.
  • For each array:
    • If the array has no dimensions, it writes zeroes for each defined dimension.
    • If the array has dimensions, it writes the dimension sizes using the appropriate compression method.
    • If the array type is SDDS_STRING, it writes each string element using the appropriate compression method.
    • Otherwise, it writes the array's data using buffered write functions.

The function handles different file formats:

  • For gzip files, it uses SDDS_GZipWriteBinaryString and SDDS_GZipBufferedWrite.
  • For LZMA files, it uses SDDS_LZMAWriteBinaryString and SDDS_LZMABufferedWrite.
  • For standard binary files, it uses SDDS_WriteBinaryString and SDDS_BufferedWrite.
Note
  • The function assumes that the dataset has been properly initialized and that all arrays are correctly allocated.
  • Compression support (zLib or LZMA) must be enabled during compilation for handling compressed files.

Definition at line 1554 of file SDDS_binary.c.

1554 {
1555 int32_t i, j, zero = 0;
1556 SDDS_LAYOUT *layout;
1557#if defined(zLib)
1558 gzFile gzfp;
1559#endif
1560 FILE *fp;
1561 struct lzmafile *lzmafp;
1562 SDDS_FILEBUFFER *fBuffer;
1563
1564 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryArrays"))
1565 return (0);
1566 layout = &SDDS_dataset->layout;
1567#if defined(zLib)
1568 if (SDDS_dataset->layout.gzipFile) {
1569 gzfp = layout->gzfp;
1570 fBuffer = &SDDS_dataset->fBuffer;
1571 for (i = 0; i < layout->n_arrays; i++) {
1572 if (!SDDS_dataset->array[i].dimension) {
1573 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1574 if (!SDDS_GZipBufferedWrite(&zero, sizeof(zero), gzfp, fBuffer)) {
1575 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1576 return 0;
1577 }
1578 continue;
1579 }
1580 if (!SDDS_GZipBufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, gzfp, fBuffer)) {
1581 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1582 return (0);
1583 }
1584 if (layout->array_definition[i].type == SDDS_STRING) {
1585 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1586 if (!SDDS_GZipWriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], gzfp, fBuffer)) {
1587 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1588 return (0);
1589 }
1590 }
1591 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, gzfp, fBuffer)) {
1592 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1593 return (0);
1594 }
1595 }
1596 } else {
1597#endif
1598 if (SDDS_dataset->layout.gzipFile) {
1599 lzmafp = layout->lzmafp;
1600 fBuffer = &SDDS_dataset->fBuffer;
1601 for (i = 0; i < layout->n_arrays; i++) {
1602 if (!SDDS_dataset->array[i].dimension) {
1603 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1604 if (!SDDS_LZMABufferedWrite(&zero, sizeof(zero), lzmafp, fBuffer)) {
1605 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1606 return 0;
1607 }
1608 continue;
1609 }
1610 if (!SDDS_LZMABufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, lzmafp, fBuffer)) {
1611 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1612 return (0);
1613 }
1614 if (layout->array_definition[i].type == SDDS_STRING) {
1615 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1616 if (!SDDS_LZMAWriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], lzmafp, fBuffer)) {
1617 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1618 return (0);
1619 }
1620 }
1621 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, lzmafp, fBuffer)) {
1622 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1623 return (0);
1624 }
1625 }
1626 } else {
1627 fp = layout->fp;
1628 fBuffer = &SDDS_dataset->fBuffer;
1629 for (i = 0; i < layout->n_arrays; i++) {
1630 if (!SDDS_dataset->array[i].dimension) {
1631 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1632 if (!SDDS_BufferedWrite(&zero, sizeof(zero), fp, fBuffer)) {
1633 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1634 return 0;
1635 }
1636 continue;
1637 }
1638 if (!SDDS_BufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, fp, fBuffer)) {
1639 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1640 return (0);
1641 }
1642 if (layout->array_definition[i].type == SDDS_STRING) {
1643 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1644 if (!SDDS_WriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], fp, fBuffer)) {
1645 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1646 return (0);
1647 }
1648 }
1649 } else if (!SDDS_BufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, fp, fBuffer)) {
1650 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1651 return (0);
1652 }
1653 }
1654 }
1655#if defined(zLib)
1656 }
1657#endif
1658 return (1);
1659}
int32_t SDDS_BufferedWrite(void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_LZMAWriteBinaryString(char *string, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
Writes a binary string to a file with LZMA compression.
int32_t SDDS_WriteBinaryString(char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
Writes a binary string to a file with buffering.

◆ SDDS_WriteBinaryColumns()

int32_t SDDS_WriteBinaryColumns ( SDDS_DATASET * SDDS_dataset)

Writes the binary columns of an SDDS dataset to the associated file.

This function iterates over each column defined in the SDDS dataset layout and writes its data to the binary file. It handles different data types, including strings and numeric types, and supports various compression formats such as gzip and LZMA if enabled.

Depending on the dataset's configuration, the function writes directly to a standard binary file, a gzip-compressed file, or an LZMA-compressed file. It also handles sparse data by only writing rows flagged for inclusion.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write.
Returns
  • Returns 1 on successful writing of all columns.
  • Returns 0 if an error occurs during the writing process.

The function performs the following steps:

  • Validates the dataset structure using SDDS_CheckDataset.
  • Determines the file format (standard, gzip, LZMA) and initializes the corresponding file pointer.
  • Iterates through each column in the dataset:
    • For string columns, writes each string entry individually using the appropriate write function.
    • For numeric columns, writes the entire column data in a buffered manner if all rows are flagged; otherwise, writes individual row entries.
  • Handles errors by setting appropriate error messages and aborting the write operation.
Note
  • The function assumes that the dataset has been properly initialized and populated with data.
  • Compression support (zLib for gzip, LZMA libraries) must be enabled during compilation for handling compressed files.
  • The function is not thread-safe and should be called in a synchronized context.

Definition at line 1694 of file SDDS_binary.c.

1694 {
1695 int64_t i, row, rows, type, size;
1696 SDDS_LAYOUT *layout;
1697#if defined(zLib)
1698 gzFile gzfp;
1699#endif
1700 FILE *fp;
1701 struct lzmafile *lzmafp;
1702 SDDS_FILEBUFFER *fBuffer;
1703
1704 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryColumns"))
1705 return (0);
1706 layout = &SDDS_dataset->layout;
1707 fBuffer = &SDDS_dataset->fBuffer;
1708 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1709#if defined(zLib)
1710 if (SDDS_dataset->layout.gzipFile) {
1711 gzfp = layout->gzfp;
1712 for (i = 0; i < layout->n_columns; i++) {
1713 type = layout->column_definition[i].type;
1714 size = SDDS_type_size[type - 1];
1715 if (type == SDDS_STRING) {
1716 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1717 if (SDDS_dataset->row_flag[row] && !SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1718 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1719 return (0);
1720 }
1721 }
1722 } else {
1723 if (rows == SDDS_dataset->n_rows) {
1724 if (!SDDS_GZipBufferedWrite(SDDS_dataset->data[i], size * rows, gzfp, fBuffer)) {
1725 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1726 return (0);
1727 }
1728 } else {
1729 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1730 if (SDDS_dataset->row_flag[row] && !SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
1731 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1732 return (0);
1733 }
1734 }
1735 }
1736 }
1737 }
1738 } else {
1739#endif
1740 if (SDDS_dataset->layout.lzmaFile) {
1741 lzmafp = layout->lzmafp;
1742 for (i = 0; i < layout->n_columns; i++) {
1743 type = layout->column_definition[i].type;
1744 size = SDDS_type_size[type - 1];
1745 if (layout->column_definition[i].type == SDDS_STRING) {
1746 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1747 if (SDDS_dataset->row_flag[row] && !SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
1748 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1749 return (0);
1750 }
1751 }
1752 } else {
1753 if (rows == SDDS_dataset->n_rows) {
1754 if (!SDDS_LZMABufferedWrite(SDDS_dataset->data[i], size * rows, lzmafp, fBuffer)) {
1755 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1756 return (0);
1757 }
1758 } else {
1759 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1760 if (SDDS_dataset->row_flag[row] && !SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
1761 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1762 return (0);
1763 }
1764 }
1765 }
1766 }
1767 }
1768 } else {
1769 fp = layout->fp;
1770 for (i = 0; i < layout->n_columns; i++) {
1771 type = layout->column_definition[i].type;
1772 size = SDDS_type_size[type - 1];
1773 if (layout->column_definition[i].type == SDDS_STRING) {
1774 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1775 if (SDDS_dataset->row_flag[row] && !SDDS_WriteBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
1776 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1777 return (0);
1778 }
1779 }
1780 } else {
1781 if (rows == SDDS_dataset->n_rows) {
1782 if (!SDDS_BufferedWrite(SDDS_dataset->data[i], size * rows, fp, fBuffer)) {
1783 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1784 return (0);
1785 }
1786 } else {
1787 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1788 if (SDDS_dataset->row_flag[row] && !SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
1789 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1790 return (0);
1791 }
1792 }
1793 }
1794 }
1795 }
1796 }
1797#if defined(zLib)
1798 }
1799#endif
1800 return (1);
1801}

◆ SDDS_WriteBinaryPage()

int32_t SDDS_WriteBinaryPage ( SDDS_DATASET * SDDS_dataset)

Writes a binary page of data to an SDDS dataset, handling compression and buffering.

This function writes a binary page (including parameters, arrays, and row data) to the SDDS dataset pointed to by SDDS_dataset. It handles different file types, including regular files, LZMA-compressed files, and GZIP-compressed files, and uses buffering to improve write performance.

The function performs the following steps:

  • Checks for output endianess and writes a non-native binary page if needed.
  • Determines the number of rows to write and calculates any fixed row counts.
  • Writes the number of rows to the file.
  • Writes parameters, arrays, and column data using the appropriate write functions.
  • Flushes the buffer to ensure all data is written.

It uses the appropriate buffered write functions (SDDS_BufferedWrite, SDDS_LZMABufferedWrite, or SDDS_GZipBufferedWrite) depending on the file type.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the SDDS dataset to write to.
Returns
Returns 1 on success; returns 0 on error.
Note
The function sets error messages using SDDS_SetError if any step fails.

Definition at line 767 of file SDDS_binary.c.

767 {
768#if defined(zLib)
769 gzFile gzfp;
770#endif
771 FILE *fp;
772 struct lzmafile *lzmafp;
773 int64_t i, rows, fixed_rows;
774 int32_t min32 = INT32_MIN, rows32;
775 /* static char buffer[SDDS_MAXLINE]; */
776 SDDS_FILEBUFFER *fBuffer;
777 char *outputEndianess = NULL;
778
779 if ((outputEndianess = getenv("SDDS_OUTPUT_ENDIANESS"))) {
780 if (((strncmp(outputEndianess, "big", 3) == 0) && (SDDS_IsBigEndianMachine() == 0)) || ((strncmp(outputEndianess, "little", 6) == 0) && (SDDS_IsBigEndianMachine() == 1)))
781 return SDDS_WriteNonNativeBinaryPage(SDDS_dataset);
782 }
783
784 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryPage"))
785 return (0);
786
787#if defined(zLib)
788 if (SDDS_dataset->layout.gzipFile) {
789 if (!(gzfp = SDDS_dataset->layout.gzfp)) {
790 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteBinaryPage)");
791 return (0);
792 }
793 fBuffer = &SDDS_dataset->fBuffer;
794
795 if (!fBuffer->buffer) {
796 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
797 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (bufferSize + 1)))) {
798 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteBinaryPage)");
799 return 0;
800 }
801 fBuffer->bufferSize = bufferSize;
802 fBuffer->bytesLeft = bufferSize;
803 }
804
805 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
806 SDDS_dataset->rowcount_offset = gztell(gzfp);
807 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
808 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
809 if (fixed_rows > INT32_MAX) {
810 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
811 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
812 return (0);
813 }
814 if (!SDDS_GZipBufferedWrite(&fixed_rows, sizeof(fixed_rows), gzfp, fBuffer)) {
815 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
816 return (0);
817 }
818 } else {
819 rows32 = (int32_t)fixed_rows;
820 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
821 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
822 return (0);
823 }
824 }
825 } else {
826 if (rows > INT32_MAX) {
827 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
828 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
829 return (0);
830 }
831 if (!SDDS_GZipBufferedWrite(&rows, sizeof(rows), gzfp, fBuffer)) {
832 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
833 return (0);
834 }
835 } else {
836 rows32 = (int32_t)rows;
837 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
838 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
839 return (0);
840 }
841 }
842 }
843 if (!SDDS_WriteBinaryParameters(SDDS_dataset)) {
844 SDDS_SetError("Unable to write page--parameter writing problem (SDDS_WriteBinaryPage)");
845 return 0;
846 }
847 if (!SDDS_WriteBinaryArrays(SDDS_dataset)) {
848 SDDS_SetError("Unable to write page--array writing problem (SDDS_WriteBinaryPage)");
849 return 0;
850 }
851 if (SDDS_dataset->layout.n_columns) {
852 if (SDDS_dataset->layout.data_mode.column_major) {
853 if (!SDDS_WriteBinaryColumns(SDDS_dataset)) {
854 SDDS_SetError("Unable to write page--column writing problem (SDDS_WriteBinaryPage)");
855 return 0;
856 }
857 } else {
858 for (i = 0; i < SDDS_dataset->n_rows; i++) {
859 if (SDDS_dataset->row_flag[i] && !SDDS_WriteBinaryRow(SDDS_dataset, i)) {
860 SDDS_SetError("Unable to write page--row writing problem (SDDS_WriteBinaryPage)");
861 return 0;
862 }
863 }
864 }
865 }
866 if (!SDDS_GZipFlushBuffer(gzfp, fBuffer)) {
867 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
868 return 0;
869 }
870 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
871 SDDS_dataset->n_rows_written = rows;
872 SDDS_dataset->writing_page = 1;
873 } else {
874#endif
875 if (SDDS_dataset->layout.lzmaFile) {
876 if (!(lzmafp = SDDS_dataset->layout.lzmafp)) {
877 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteBinaryPage)");
878 return (0);
879 }
880 fBuffer = &SDDS_dataset->fBuffer;
881
882 if (!fBuffer->buffer) {
883 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
884 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (bufferSize + 1)))) {
885 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteBinaryPage)");
886 return 0;
887 }
888 fBuffer->bufferSize = bufferSize;
889 fBuffer->bytesLeft = bufferSize;
890 }
891 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
892 SDDS_dataset->rowcount_offset = lzma_tell(lzmafp);
893 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
894 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
895 if (fixed_rows > INT32_MAX) {
896 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
897 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
898 return (0);
899 }
900 if (!SDDS_LZMABufferedWrite(&fixed_rows, sizeof(fixed_rows), lzmafp, fBuffer)) {
901 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
902 return (0);
903 }
904 } else {
905 rows32 = (int32_t)fixed_rows;
906 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
907 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
908 return (0);
909 }
910 }
911 } else {
912 if (rows > INT32_MAX) {
913 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
914 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
915 return (0);
916 }
917 if (!SDDS_LZMABufferedWrite(&rows, sizeof(rows), lzmafp, fBuffer)) {
918 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
919 return (0);
920 }
921 } else {
922 rows32 = (int32_t)rows;
923 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
924 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
925 return (0);
926 }
927 }
928 }
929 if (!SDDS_WriteBinaryParameters(SDDS_dataset)) {
930 SDDS_SetError("Unable to write page--parameter writing problem (SDDS_WriteBinaryPage)");
931 return 0;
932 }
933 if (!SDDS_WriteBinaryArrays(SDDS_dataset)) {
934 SDDS_SetError("Unable to write page--array writing problem (SDDS_WriteBinaryPage)");
935 return 0;
936 }
937 if (SDDS_dataset->layout.n_columns) {
938 if (SDDS_dataset->layout.data_mode.column_major) {
939 if (!SDDS_WriteBinaryColumns(SDDS_dataset)) {
940 SDDS_SetError("Unable to write page--column writing problem (SDDS_WriteBinaryPage)");
941 return 0;
942 }
943 } else {
944 for (i = 0; i < SDDS_dataset->n_rows; i++) {
945 if (SDDS_dataset->row_flag[i] && !SDDS_WriteBinaryRow(SDDS_dataset, i)) {
946 SDDS_SetError("Unable to write page--row writing problem (SDDS_WriteBinaryPage)");
947 return 0;
948 }
949 }
950 }
951 }
952 if (!SDDS_LZMAFlushBuffer(lzmafp, fBuffer)) {
953 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
954 return 0;
955 }
956 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
957 SDDS_dataset->n_rows_written = rows;
958 SDDS_dataset->writing_page = 1;
959 } else {
960 if (!(fp = SDDS_dataset->layout.fp)) {
961 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteBinaryPage)");
962 return (0);
963 }
964 fBuffer = &SDDS_dataset->fBuffer;
965
966 if (!fBuffer->buffer) {
967 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
968 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (bufferSize + 1)))) {
969 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteBinaryPage)");
970 return 0;
971 }
972 fBuffer->bufferSize = bufferSize;
973 fBuffer->bytesLeft = bufferSize;
974 }
975
976 /* Flush any existing data in the output buffer so we can determine the
977 * row count offset for the file. This is probably unnecessary.
978 */
979 if (!SDDS_FlushBuffer(fp, fBuffer)) {
980 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
981 return 0;
982 }
983
984 /* output the row count and determine its byte offset in the file */
985 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
986 SDDS_dataset->rowcount_offset = ftell(fp);
987 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
988 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
989#if defined(DEBUG)
990 fprintf(stderr, "setting %" PRId64 " fixed rows\n", fixed_rows);
991#endif
992 if (fixed_rows > INT32_MAX) {
993 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
994 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
995 return (0);
996 }
997 if (!SDDS_BufferedWrite(&fixed_rows, sizeof(fixed_rows), fp, fBuffer)) {
998 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
999 return (0);
1000 }
1001 } else {
1002 rows32 = (int32_t)fixed_rows;
1003 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
1004 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
1005 return (0);
1006 }
1007 }
1008 } else {
1009#if defined(DEBUG)
1010 fprintf(stderr, "setting %" PRId64 " rows\n", rows);
1011#endif
1012 if (rows > INT32_MAX) {
1013 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
1014 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
1015 return (0);
1016 }
1017 if (!SDDS_BufferedWrite(&rows, sizeof(rows), fp, fBuffer)) {
1018 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
1019 return (0);
1020 }
1021 } else {
1022 rows32 = (int32_t)rows;
1023 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
1024 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteBinaryPage)");
1025 return (0);
1026 }
1027 }
1028 }
1029
1030 /* write the data, using buffered I/O */
1031 if (!SDDS_WriteBinaryParameters(SDDS_dataset)) {
1032 SDDS_SetError("Unable to write page--parameter writing problem (SDDS_WriteBinaryPage)");
1033 return 0;
1034 }
1035 if (!SDDS_WriteBinaryArrays(SDDS_dataset)) {
1036 SDDS_SetError("Unable to write page--array writing problem (SDDS_WriteBinaryPage)");
1037 return 0;
1038 }
1039 if (SDDS_dataset->layout.n_columns) {
1040 if (SDDS_dataset->layout.data_mode.column_major) {
1041 if (!SDDS_WriteBinaryColumns(SDDS_dataset)) {
1042 SDDS_SetError("Unable to write page--column writing problem (SDDS_WriteBinaryPage)");
1043 return 0;
1044 }
1045 } else {
1046 for (i = 0; i < SDDS_dataset->n_rows; i++) {
1047 if (SDDS_dataset->row_flag[i] && !SDDS_WriteBinaryRow(SDDS_dataset, i)) {
1048 SDDS_SetError("Unable to write page--row writing problem (SDDS_WriteBinaryPage)");
1049 return 0;
1050 }
1051 }
1052 }
1053 }
1054 /* flush the page */
1055 if (!SDDS_FlushBuffer(fp, fBuffer)) {
1056 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
1057 return 0;
1058 }
1059 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
1060 SDDS_dataset->n_rows_written = rows;
1061 SDDS_dataset->writing_page = 1;
1062 }
1063#if defined(zLib)
1064 }
1065#endif
1066 return (1);
1067}
int32_t SDDS_WriteBinaryColumns(SDDS_DATASET *SDDS_dataset)
Writes the binary columns of an SDDS dataset to the associated file.
int32_t SDDS_WriteBinaryArrays(SDDS_DATASET *SDDS_dataset)
Writes the binary arrays of the SDDS dataset to a file.
int32_t SDDS_WriteBinaryParameters(SDDS_DATASET *SDDS_dataset)
Writes the binary parameters of the SDDS dataset.
int32_t SDDS_LZMAFlushBuffer(struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)

◆ SDDS_WriteBinaryParameters()

int32_t SDDS_WriteBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Writes the binary parameters of the SDDS dataset.

This function writes all non-fixed parameters of the SDDS dataset to the associated binary file. It handles different compression formats such as gzip and LZMA if enabled.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure containing the dataset to write.
Returns
  • Returns 1 on successful write of all parameters.
  • Returns 0 if an error occurs during the writing process.

The function performs the following steps:

  • Validates the dataset structure.
  • Iterates over all parameters defined in the dataset layout.
  • For each parameter:
    • If it is a fixed value, it is skipped.
    • If the parameter is of type SDDS_STRING, it writes the string using the appropriate compression method.
    • Otherwise, it writes the parameter's value using buffered write functions.

The function handles different file formats:

  • For gzip files, it uses SDDS_GZipWriteBinaryString and SDDS_GZipBufferedWrite.
  • For LZMA files, it uses SDDS_LZMAWriteBinaryString and SDDS_LZMABufferedWrite.
  • For standard binary files, it uses SDDS_WriteBinaryString and SDDS_BufferedWrite.
Note
  • The function assumes that the dataset has been properly initialized and that all parameters are correctly allocated.
  • Compression support (zLib or LZMA) must be enabled during compilation for handling compressed files.

Definition at line 1447 of file SDDS_binary.c.

1447 {
1448 int32_t i;
1449 SDDS_LAYOUT *layout;
1450 /* char *predefined_format; */
1451 /* static char buffer[SDDS_MAXLINE]; */
1452#if defined(zLib)
1453 gzFile gzfp;
1454#endif
1455 FILE *fp;
1456 struct lzmafile *lzmafp;
1457 SDDS_FILEBUFFER *fBuffer;
1458
1459 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryParameters"))
1460 return (0);
1461 layout = &SDDS_dataset->layout;
1462#if defined(zLib)
1463 if (SDDS_dataset->layout.gzipFile) {
1464 gzfp = layout->gzfp;
1465 fBuffer = &SDDS_dataset->fBuffer;
1466 for (i = 0; i < layout->n_parameters; i++) {
1467 if (layout->parameter_definition[i].fixed_value)
1468 continue;
1469 if (layout->parameter_definition[i].type == SDDS_STRING) {
1470 if (!SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->parameter[i]), gzfp, fBuffer)) {
1471 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1472 return (0);
1473 }
1474 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer)) {
1475 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1476 return (0);
1477 }
1478 }
1479 } else {
1480#endif
1481 if (SDDS_dataset->layout.lzmaFile) {
1482 lzmafp = layout->lzmafp;
1483 fBuffer = &SDDS_dataset->fBuffer;
1484 for (i = 0; i < layout->n_parameters; i++) {
1485 if (layout->parameter_definition[i].fixed_value)
1486 continue;
1487 if (layout->parameter_definition[i].type == SDDS_STRING) {
1488 if (!SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->parameter[i]), lzmafp, fBuffer)) {
1489 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1490 return (0);
1491 }
1492 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer)) {
1493 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1494 return (0);
1495 }
1496 }
1497 } else {
1498 fp = layout->fp;
1499 fBuffer = &SDDS_dataset->fBuffer;
1500 for (i = 0; i < layout->n_parameters; i++) {
1501 if (layout->parameter_definition[i].fixed_value)
1502 continue;
1503 if (layout->parameter_definition[i].type == SDDS_STRING) {
1504 if (!SDDS_WriteBinaryString(*((char **)SDDS_dataset->parameter[i]), fp, fBuffer)) {
1505 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1506 return (0);
1507 }
1508 } else if (!SDDS_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer)) {
1509 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1510 return (0);
1511 }
1512 }
1513 }
1514#if defined(zLib)
1515 }
1516#endif
1517 return (1);
1518}

◆ SDDS_WriteBinaryRow()

int32_t SDDS_WriteBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row )

Writes a single binary row of an SDDS dataset to the associated file.

This function writes the data of a specified row within the SDDS dataset to the binary file. It handles different data types, including strings and numeric types, and supports various compression formats such as gzip and LZMA if enabled.

Depending on the dataset's configuration, the function writes directly to a standard binary file, a gzip-compressed file, or an LZMA-compressed file.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset.
rowThe zero-based index of the row to write.
Returns
  • Returns 1 on successful writing of the row.
  • Returns 0 if an error occurs during the writing process.

The function performs the following steps:

  • Validates the dataset structure using SDDS_CheckDataset.
  • Determines the file format (standard, gzip, LZMA) and initializes the corresponding file pointer.
  • Iterates through each column in the dataset:
    • For string columns, writes the string entry of the specified row using the appropriate write function.
    • For numeric columns, writes the data of the specified row using buffered write functions.
  • Handles errors by setting appropriate error messages and aborting the write operation.
Note
  • The function assumes that the dataset has been properly initialized and that the specified row exists.
  • Compression support (zLib for gzip, LZMA libraries) must be enabled during compilation for handling compressed files.
  • The function is not thread-safe and should be called in a synchronized context.

Definition at line 1978 of file SDDS_binary.c.

1978 {
1979 int64_t i, type, size;
1980 SDDS_LAYOUT *layout;
1981#if defined(zLib)
1982 gzFile gzfp;
1983#endif
1984 FILE *fp;
1985 struct lzmafile *lzmafp;
1986 SDDS_FILEBUFFER *fBuffer;
1987
1988 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryRow"))
1989 return (0);
1990 layout = &SDDS_dataset->layout;
1991#if defined(zLib)
1992 if (SDDS_dataset->layout.gzipFile) {
1993 gzfp = layout->gzfp;
1994 fBuffer = &SDDS_dataset->fBuffer;
1995 for (i = 0; i < layout->n_columns; i++) {
1996 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
1997 if (!SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1998 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
1999 return (0);
2000 }
2001 } else {
2002 size = SDDS_type_size[type - 1];
2003 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
2004 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
2005 return (0);
2006 }
2007 }
2008 }
2009 } else {
2010#endif
2011 if (SDDS_dataset->layout.lzmaFile) {
2012 lzmafp = layout->lzmafp;
2013 fBuffer = &SDDS_dataset->fBuffer;
2014 for (i = 0; i < layout->n_columns; i++) {
2015 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2016 if (!SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
2017 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
2018 return (0);
2019 }
2020 } else {
2021 size = SDDS_type_size[type - 1];
2022 if (!SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
2023 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
2024 return (0);
2025 }
2026 }
2027 }
2028 } else {
2029 fp = layout->fp;
2030 fBuffer = &SDDS_dataset->fBuffer;
2031 for (i = 0; i < layout->n_columns; i++) {
2032 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2033 if (!SDDS_WriteBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
2034 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
2035 return (0);
2036 }
2037 } else {
2038 size = SDDS_type_size[type - 1];
2039 if (!SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
2040 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
2041 return (0);
2042 }
2043 }
2044 }
2045 }
2046#if defined(zLib)
2047 }
2048#endif
2049 return (1);
2050}

◆ SDDS_WriteBinaryString()

int32_t SDDS_WriteBinaryString ( char * string,
FILE * fp,
SDDS_FILEBUFFER * fBuffer )

Writes a binary string to a file with buffering.

This function writes a binary string to the specified file by first writing the length of the string followed by the string's content to ensure proper binary formatting. If the input string is NULL, an empty string is written instead. The writing operation utilizes a buffered approach to enhance performance.

Parameters
[in]stringThe null-terminated string to be written. If NULL, an empty string is written.
[in]fpThe file pointer to write to. Must be an open file in binary write mode.
[in,out]fBufferPointer to the file buffer used for buffered writing operations.
Returns
int32_t Returns 1 on success, 0 on failure.
Return values
1Operation was successful.
0An error occurred during writing.

Definition at line 2642 of file SDDS_binary.c.

2642 {
2643 int32_t length;
2644 static const char dummy_string[] = "";
2645 if (!string)
2646 string = (char *)dummy_string;
2647 length = strlen(string);
2648 if (!SDDS_BufferedWrite(&length, sizeof(length), fp, fBuffer)) {
2649 SDDS_SetError("Unable to write string--error writing length");
2650 return (0);
2651 }
2652 if (length && !SDDS_BufferedWrite(string, sizeof(*string) * length, fp, fBuffer)) {
2653 SDDS_SetError("Unable to write string--error writing contents");
2654 return (0);
2655 }
2656 return (1);
2657}

◆ SDDS_WriteNonNativeBinaryArrays()

int32_t SDDS_WriteNonNativeBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Writes non-native endian binary arrays to an SDDS dataset.

This function iterates through all array definitions in the specified SDDS dataset and writes their binary data to the underlying file. It handles various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. For string arrays, it writes each string individually, ensuring proper memory management and byte order conversion. The function supports different compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files. After writing, it swaps the endianness of the array data to match the system's native byte order.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write to.
Returns
int32_t Returns 1 on successful writing of all arrays, or 0 if an error occurred.
Return values
1All non-native endian arrays were successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures, memory allocation issues, or corrupted array definitions.
Note
This function modifies the dataset's array data during the write process. Ensure that the dataset is properly initialized and opened for writing before invoking this function. After writing, the dataset's state is updated to reflect the written arrays.

Definition at line 5477 of file SDDS_binary.c.

5477 {
5478 int32_t i, j, dimension, zero = 0;
5479 SDDS_LAYOUT *layout;
5480 FILE *fp;
5481 struct lzmafile *lzmafp;
5482 SDDS_FILEBUFFER *fBuffer;
5483#if defined(zLib)
5484 gzFile gzfp;
5485#endif
5486 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryArrays"))
5487 return (0);
5488 SDDS_SwapEndsArrayData(SDDS_dataset);
5489
5490 layout = &SDDS_dataset->layout;
5491 fBuffer = &SDDS_dataset->fBuffer;
5492#if defined(zLib)
5493 if (SDDS_dataset->layout.gzipFile) {
5494 gzfp = layout->gzfp;
5495 for (i = 0; i < layout->n_arrays; i++) {
5496 if (!SDDS_dataset->array[i].dimension) {
5497 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5498 if (!SDDS_GZipBufferedWrite(&zero, sizeof(zero), gzfp, fBuffer)) {
5499 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5500 SDDS_SwapEndsArrayData(SDDS_dataset);
5501 return 0;
5502 }
5503 continue;
5504 }
5505
5506 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5507 dimension = SDDS_dataset->array[i].dimension[j];
5508 SDDS_SwapLong(&dimension);
5509 if (!SDDS_GZipBufferedWrite(&dimension, sizeof(dimension), gzfp, fBuffer)) {
5510 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5511 SDDS_SwapEndsArrayData(SDDS_dataset);
5512 return (0);
5513 }
5514 }
5515 if (layout->array_definition[i].type == SDDS_STRING) {
5516 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5517 if (!SDDS_GZipWriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], gzfp, fBuffer)) {
5518 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5519 SDDS_SwapEndsArrayData(SDDS_dataset);
5520 return (0);
5521 }
5522 }
5523 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, gzfp, fBuffer)) {
5524 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5525 SDDS_SwapEndsArrayData(SDDS_dataset);
5526 return (0);
5527 }
5528 }
5529 } else {
5530#endif
5531 if (SDDS_dataset->layout.lzmaFile) {
5532 lzmafp = layout->lzmafp;
5533 for (i = 0; i < layout->n_arrays; i++) {
5534 if (!SDDS_dataset->array[i].dimension) {
5535 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5536 if (!SDDS_LZMABufferedWrite(&zero, sizeof(zero), lzmafp, fBuffer)) {
5537 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5538 SDDS_SwapEndsArrayData(SDDS_dataset);
5539 return 0;
5540 }
5541 continue;
5542 }
5543
5544 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5545 dimension = SDDS_dataset->array[i].dimension[j];
5546 SDDS_SwapLong(&dimension);
5547 if (!SDDS_LZMABufferedWrite(&dimension, sizeof(dimension), lzmafp, fBuffer)) {
5548 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5549 SDDS_SwapEndsArrayData(SDDS_dataset);
5550 return (0);
5551 }
5552 }
5553 if (layout->array_definition[i].type == SDDS_STRING) {
5554 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5555 if (!SDDS_LZMAWriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], lzmafp, fBuffer)) {
5556 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5557 SDDS_SwapEndsArrayData(SDDS_dataset);
5558 return (0);
5559 }
5560 }
5561 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, lzmafp, fBuffer)) {
5562 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5563 SDDS_SwapEndsArrayData(SDDS_dataset);
5564 return (0);
5565 }
5566 }
5567 } else {
5568 fp = layout->fp;
5569 for (i = 0; i < layout->n_arrays; i++) {
5570 if (!SDDS_dataset->array[i].dimension) {
5571 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5572 if (!SDDS_BufferedWrite(&zero, sizeof(zero), fp, fBuffer)) {
5573 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5574 SDDS_SwapEndsArrayData(SDDS_dataset);
5575 return 0;
5576 }
5577 continue;
5578 }
5579
5580 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5581 dimension = SDDS_dataset->array[i].dimension[j];
5582 SDDS_SwapLong(&dimension);
5583 if (!SDDS_BufferedWrite(&dimension, sizeof(dimension), fp, fBuffer)) {
5584 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5585 SDDS_SwapEndsArrayData(SDDS_dataset);
5586 return (0);
5587 }
5588 }
5589 if (layout->array_definition[i].type == SDDS_STRING) {
5590 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5591 if (!SDDS_WriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], fp, fBuffer)) {
5592 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5593 SDDS_SwapEndsArrayData(SDDS_dataset);
5594 return (0);
5595 }
5596 }
5597 } else if (!SDDS_BufferedWrite(SDDS_dataset->array[i].data, SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements, fp, fBuffer)) {
5598 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5599 SDDS_SwapEndsArrayData(SDDS_dataset);
5600 return (0);
5601 }
5602 }
5603 }
5604#if defined(zLib)
5605 }
5606#endif
5607 SDDS_SwapEndsArrayData(SDDS_dataset);
5608 return (1);
5609}
int32_t SDDS_WriteNonNativeBinaryString(char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
Writes a non-native endian binary string to a file.
int32_t SDDS_LZMAWriteNonNativeBinaryString(char *string, struct lzmafile *lzmafp, SDDS_FILEBUFFER *fBuffer)
Writes a non-native endian binary string to an LZMA-compressed file.

◆ SDDS_WriteNonNativeBinaryColumns()

int32_t SDDS_WriteNonNativeBinaryColumns ( SDDS_DATASET * SDDS_dataset)

Writes non-native endian binary columns of an SDDS dataset to the associated file.

This function iterates over each column defined in the SDDS dataset layout and writes its data to the binary file using a non-native byte order. It handles different data types, including strings and numeric types, and supports various compression formats such as gzip and LZMA if enabled.

Depending on the dataset's configuration, the function writes directly to a standard binary file, a gzip-compressed file, or an LZMA-compressed file. It also handles sparse data by only writing rows flagged for inclusion.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write.
Returns
  • Returns 1 on successful writing of all columns.
  • Returns 0 if an error occurs during the writing process.

The function performs the following steps:

  • Validates the dataset structure using SDDS_CheckDataset.
  • Determines the file format (standard, gzip, LZMA) and initializes the corresponding file pointer.
  • Iterates through each column in the dataset:
    • For string columns, writes each string entry individually using the appropriate non-native write function.
    • For numeric columns, writes the entire column data in a buffered manner if all rows are flagged; otherwise, writes individual row entries.
  • Handles errors by setting appropriate error messages and aborting the write operation.
Note
  • The function assumes that the dataset has been properly initialized and populated with data.
  • Compression support (zLib for gzip, LZMA libraries) must be enabled during compilation for handling compressed files.
  • The function is not thread-safe and should be called in a synchronized context.

Definition at line 1837 of file SDDS_binary.c.

1837 {
1838 int64_t i, row, rows, size, type;
1839 SDDS_LAYOUT *layout;
1840#if defined(zLib)
1841 gzFile gzfp;
1842#endif
1843 FILE *fp;
1844 struct lzmafile *lzmafp;
1845 SDDS_FILEBUFFER *fBuffer;
1846
1847 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryColumns"))
1848 return (0);
1849 layout = &SDDS_dataset->layout;
1850 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1851 fBuffer = &SDDS_dataset->fBuffer;
1852#if defined(zLib)
1853 if (SDDS_dataset->layout.gzipFile) {
1854 gzfp = layout->gzfp;
1855 for (i = 0; i < layout->n_columns; i++) {
1856 type = layout->column_definition[i].type;
1857 size = SDDS_type_size[type - 1];
1858 if (type == SDDS_STRING) {
1859 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1860 if (SDDS_dataset->row_flag[row] && !SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1861 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1862 return (0);
1863 }
1864 }
1865 } else {
1866 if (rows == SDDS_dataset->n_rows) {
1867 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i], size * rows, gzfp, fBuffer)) {
1868 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1869 return (0);
1870 }
1871 } else {
1872 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1873 if (SDDS_dataset->row_flag[row] && !SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
1874 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1875 return (0);
1876 }
1877 }
1878 }
1879 }
1880 }
1881 } else {
1882#endif
1883 if (SDDS_dataset->layout.lzmaFile) {
1884 lzmafp = layout->lzmafp;
1885 for (i = 0; i < layout->n_columns; i++) {
1886 type = layout->column_definition[i].type;
1887 size = SDDS_type_size[type - 1];
1888 if (type == SDDS_STRING) {
1889 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1890 if (SDDS_dataset->row_flag[row] && !SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
1891 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1892 return (0);
1893 }
1894 }
1895 } else {
1896 if (rows == SDDS_dataset->n_rows) {
1897 if (!SDDS_LZMABufferedWrite(SDDS_dataset->data[i], size * rows, lzmafp, fBuffer)) {
1898 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1899 return (0);
1900 }
1901 } else {
1902 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1903 if (SDDS_dataset->row_flag[row] && !SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
1904 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1905 return (0);
1906 }
1907 }
1908 }
1909 }
1910 }
1911 } else {
1912 fp = layout->fp;
1913 for (i = 0; i < layout->n_columns; i++) {
1914 type = layout->column_definition[i].type;
1915 size = SDDS_type_size[type - 1];
1916 if (type == SDDS_STRING) {
1917 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1918 if (SDDS_dataset->row_flag[row] && !SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
1919 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1920 return (0);
1921 }
1922 }
1923 } else {
1924 if (rows == SDDS_dataset->n_rows) {
1925 if (!SDDS_BufferedWrite(SDDS_dataset->data[i], size * rows, fp, fBuffer)) {
1926 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1927 return (0);
1928 }
1929 } else {
1930 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1931 if (SDDS_dataset->row_flag[row] && !SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
1932 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1933 return (0);
1934 }
1935 }
1936 }
1937 }
1938 }
1939 }
1940#if defined(zLib)
1941 }
1942#endif
1943 return (1);
1944}

◆ SDDS_WriteNonNativeBinaryPage()

int32_t SDDS_WriteNonNativeBinaryPage ( SDDS_DATASET * SDDS_dataset)

Writes a non-native endian binary page to an SDDS dataset.

This function writes a binary page to the specified SDDS dataset, handling byte order reversal to convert between little-endian and big-endian formats. It manages various compression formats, including uncompressed, GZIP-compressed, and LZMA-compressed files. The function performs the following operations:

  • Counts the number of rows to write.
  • Writes the row count with appropriate byte order handling.
  • Writes non-native endian parameters and arrays.
  • Writes column data in either column-major or row-major format based on the dataset's configuration.
  • Flushes the buffer to ensure all data is written to the file.
Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write to.
Returns
int32_t Returns 1 on successful writing of the binary page, or 0 if an error occurred.
Return values
1The binary page was successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures, memory allocation issues, or corrupted dataset definitions.
Note
This function modifies the dataset's internal structures during the write process. Ensure that the dataset is properly initialized and opened for writing before invoking this function. After writing, the dataset's state is updated to reflect the newly written page.

Definition at line 5112 of file SDDS_binary.c.

5116{
5117 FILE *fp;
5118 struct lzmafile *lzmafp = NULL;
5119 int64_t i, rows, fixed_rows;
5120 int32_t min32 = INT32_MIN, rows32;
5121 SDDS_FILEBUFFER *fBuffer;
5122#if defined(zLib)
5123 gzFile gzfp = NULL;
5124#endif
5125
5126 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryPage"))
5127 return (0);
5128 if (!(fp = SDDS_dataset->layout.fp)) {
5129 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5130 return (0);
5131 }
5132 fBuffer = &SDDS_dataset->fBuffer;
5133
5134 if (!fBuffer->buffer) {
5135 int32_t bufferSize = SDDS_GetLockedDefaultIOBufferSize();
5136 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * bufferSize))) {
5137 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteNonNativeBinaryPage)");
5138 return 0;
5139 }
5140 fBuffer->bufferSize = bufferSize;
5141 fBuffer->bytesLeft = bufferSize;
5142 }
5143 SDDS_SwapLong(&min32);
5144
5145 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
5146#if defined(zLib)
5147 if (SDDS_dataset->layout.gzipFile) {
5148 if (!(gzfp = SDDS_dataset->layout.gzfp)) {
5149 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5150 return (0);
5151 }
5152 SDDS_dataset->rowcount_offset = gztell(gzfp);
5153 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5154 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5155 if (fixed_rows > INT32_MAX) {
5156 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
5157 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5158 return (0);
5159 }
5160 SDDS_SwapLong64(&fixed_rows);
5161 if (!SDDS_GZipBufferedWrite(&fixed_rows, sizeof(fixed_rows), gzfp, fBuffer)) {
5162 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5163 return (0);
5164 }
5165 SDDS_SwapLong64(&fixed_rows);
5166 } else {
5167 rows32 = (int32_t)fixed_rows;
5168 SDDS_SwapLong(&rows32);
5169 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
5170 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5171 return (0);
5172 }
5173 }
5174 } else {
5175 if (rows > INT32_MAX) {
5176 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
5177 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5178 return (0);
5179 }
5180 SDDS_SwapLong64(&rows);
5181 if (!SDDS_GZipBufferedWrite(&rows, sizeof(rows), gzfp, fBuffer)) {
5182 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5183 return (0);
5184 }
5185 SDDS_SwapLong64(&rows);
5186 } else {
5187 rows32 = (int32_t)rows;
5188 SDDS_SwapLong(&rows32);
5189 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
5190 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5191 return (0);
5192 }
5193 }
5194 }
5195 } else {
5196#endif
5197 if (SDDS_dataset->layout.lzmaFile) {
5198 if (!(lzmafp = SDDS_dataset->layout.lzmafp)) {
5199 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5200 return (0);
5201 }
5202 SDDS_dataset->rowcount_offset = lzma_tell(lzmafp);
5203 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5204 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5205 if (fixed_rows > INT32_MAX) {
5206 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
5207 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5208 return (0);
5209 }
5210 SDDS_SwapLong64(&fixed_rows);
5211 if (!SDDS_LZMABufferedWrite(&fixed_rows, sizeof(fixed_rows), lzmafp, fBuffer)) {
5212 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5213 return (0);
5214 }
5215 SDDS_SwapLong64(&fixed_rows);
5216 } else {
5217 rows32 = (int32_t)fixed_rows;
5218 SDDS_SwapLong(&rows32);
5219 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
5220 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5221 return (0);
5222 }
5223 }
5224 } else {
5225 if (rows > INT32_MAX) {
5226 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
5227 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5228 return (0);
5229 }
5230 SDDS_SwapLong64(&rows);
5231 if (!SDDS_LZMABufferedWrite(&rows, sizeof(rows), lzmafp, fBuffer)) {
5232 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5233 return (0);
5234 }
5235 SDDS_SwapLong64(&rows);
5236 } else {
5237 rows32 = (int32_t)rows;
5238 SDDS_SwapLong(&rows32);
5239 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
5240 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5241 return (0);
5242 }
5243 }
5244 }
5245 } else {
5246 SDDS_dataset->rowcount_offset = ftell(fp);
5247 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5248 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5249 if (fixed_rows > INT32_MAX) {
5250 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
5251 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5252 return (0);
5253 }
5254 SDDS_SwapLong64(&fixed_rows);
5255 if (!SDDS_BufferedWrite(&fixed_rows, sizeof(fixed_rows), fp, fBuffer)) {
5256 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5257 return (0);
5258 }
5259 SDDS_SwapLong64(&fixed_rows);
5260 } else {
5261 rows32 = (int32_t)fixed_rows;
5262 SDDS_SwapLong(&rows32);
5263 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
5264 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5265 return (0);
5266 }
5267 }
5268 } else {
5269 if (rows > INT32_MAX) {
5270 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
5271 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5272 return (0);
5273 }
5274 SDDS_SwapLong64(&rows);
5275 if (!SDDS_BufferedWrite(&rows, sizeof(rows), fp, fBuffer)) {
5276 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5277 return (0);
5278 }
5279 SDDS_SwapLong64(&rows);
5280 } else {
5281 rows32 = (int32_t)rows;
5282 SDDS_SwapLong(&rows32);
5283 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
5284 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5285 return (0);
5286 }
5287 }
5288 }
5289 }
5290#if defined(zLib)
5291 }
5292#endif
5293 if (!SDDS_WriteNonNativeBinaryParameters(SDDS_dataset)) {
5294 SDDS_SetError("Unable to write page--parameter writing problem (SDDS_WriteNonNativeBinaryPage)");
5295 return 0;
5296 }
5297 if (!SDDS_WriteNonNativeBinaryArrays(SDDS_dataset)) {
5298 SDDS_SetError("Unable to write page--array writing problem (SDDS_WriteNonNativeBinaryPage)");
5299 return 0;
5300 }
5301 SDDS_SwapEndsColumnData(SDDS_dataset);
5302 if (SDDS_dataset->layout.n_columns) {
5303 if (SDDS_dataset->layout.data_mode.column_major) {
5304 if (!SDDS_WriteNonNativeBinaryColumns(SDDS_dataset)) {
5305 SDDS_SetError("Unable to write page--column writing problem (SDDS_WriteNonNativeBinaryPage)");
5306 return 0;
5307 }
5308 } else {
5309 for (i = 0; i < SDDS_dataset->n_rows; i++) {
5310 if (SDDS_dataset->row_flag[i]) {
5311 if (!SDDS_WriteNonNativeBinaryRow(SDDS_dataset, i)) {
5312 SDDS_SetError("Unable to write page--row writing problem (SDDS_WriteNonNativeBinaryPage)");
5313 return 0;
5314 }
5315 }
5316 }
5317 }
5318 }
5319 SDDS_SwapEndsColumnData(SDDS_dataset);
5320#if defined(zLib)
5321 if (SDDS_dataset->layout.gzipFile) {
5322 if (!SDDS_GZipFlushBuffer(gzfp, fBuffer)) {
5323 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5324 return 0;
5325 }
5326 } else {
5327#endif
5328 if (SDDS_dataset->layout.lzmaFile) {
5329 if (!SDDS_LZMAFlushBuffer(lzmafp, fBuffer)) {
5330 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5331 return 0;
5332 }
5333 } else {
5334 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5335 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5336 return 0;
5337 }
5338 }
5339#if defined(zLib)
5340 }
5341#endif
5342 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
5343 SDDS_dataset->n_rows_written = rows;
5344 SDDS_dataset->writing_page = 1;
5345 return (1);
5346}
int32_t SDDS_WriteNonNativeBinaryArrays(SDDS_DATASET *SDDS_dataset)
Writes non-native endian binary arrays to an SDDS dataset.
int32_t SDDS_WriteNonNativeBinaryColumns(SDDS_DATASET *SDDS_dataset)
Writes non-native endian binary columns of an SDDS dataset to the associated file.
int32_t SDDS_WriteNonNativeBinaryParameters(SDDS_DATASET *SDDS_dataset)
Writes non-native endian binary parameters to an SDDS dataset.

◆ SDDS_WriteNonNativeBinaryParameters()

int32_t SDDS_WriteNonNativeBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Writes non-native endian binary parameters to an SDDS dataset.

This function iterates through all parameter definitions in the specified SDDS dataset and writes their binary data to the underlying file. It handles various data types, including short, unsigned short, long, unsigned long, long long, unsigned long long, float, double, and long double. For string parameters, it writes each string individually, ensuring proper memory management and byte order conversion. Parameters with fixed values are skipped during the write process. The function supports different compression formats, including uncompressed, LZMA-compressed, and GZIP-compressed files.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write to.
Returns
int32_t Returns 1 on successful writing of all parameters, or 0 if an error occurred.
Return values
1All non-native endian parameters were successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures, memory allocation issues, or corrupted parameter definitions.
Note
This function modifies the dataset's parameter data during the write process. Ensure that the dataset is properly initialized and opened for writing before invoking this function. After writing, the dataset's state is updated to reflect the written parameters.

Definition at line 5369 of file SDDS_binary.c.

5369 {
5370 int32_t i;
5371 SDDS_LAYOUT *layout;
5372 FILE *fp;
5373 struct lzmafile *lzmafp;
5374 SDDS_FILEBUFFER *fBuffer;
5375#if defined(zLib)
5376 gzFile gzfp;
5377#endif
5378
5379 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryParameters"))
5380 return (0);
5381
5382 SDDS_SwapEndsParameterData(SDDS_dataset);
5383
5384 layout = &SDDS_dataset->layout;
5385 fBuffer = &SDDS_dataset->fBuffer;
5386#if defined(zLib)
5387 if (SDDS_dataset->layout.gzipFile) {
5388 if (!(gzfp = layout->gzfp)) {
5389 SDDS_SetError("Unable to write parameters--file pointer is NULL (SDDS_WriteNonNativeBinaryParameters)");
5390 return (0);
5391 }
5392 for (i = 0; i < layout->n_parameters; i++) {
5393 if (layout->parameter_definition[i].fixed_value)
5394 continue;
5395 if (layout->parameter_definition[i].type == SDDS_STRING) {
5396 if (!SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), gzfp, fBuffer)) {
5397 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5398 SDDS_SwapEndsParameterData(SDDS_dataset);
5399 return (0);
5400 }
5401 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer)) {
5402 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5403 SDDS_SwapEndsParameterData(SDDS_dataset);
5404 return (0);
5405 }
5406 }
5407 } else {
5408#endif
5409 if (SDDS_dataset->layout.lzmaFile) {
5410 if (!(lzmafp = layout->lzmafp)) {
5411 SDDS_SetError("Unable to write parameters--file pointer is NULL (SDDS_WriteNonNativeBinaryParameters)");
5412 return (0);
5413 }
5414 for (i = 0; i < layout->n_parameters; i++) {
5415 if (layout->parameter_definition[i].fixed_value)
5416 continue;
5417 if (layout->parameter_definition[i].type == SDDS_STRING) {
5418 if (!SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), lzmafp, fBuffer)) {
5419 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5420 SDDS_SwapEndsParameterData(SDDS_dataset);
5421 return (0);
5422 }
5423 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer)) {
5424 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5425 SDDS_SwapEndsParameterData(SDDS_dataset);
5426 return (0);
5427 }
5428 }
5429 } else {
5430 fp = layout->fp;
5431 for (i = 0; i < layout->n_parameters; i++) {
5432 if (layout->parameter_definition[i].fixed_value)
5433 continue;
5434 if (layout->parameter_definition[i].type == SDDS_STRING) {
5435 if (!SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), fp, fBuffer)) {
5436 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5437 SDDS_SwapEndsParameterData(SDDS_dataset);
5438 return (0);
5439 }
5440 } else if (!SDDS_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer)) {
5441 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5442 SDDS_SwapEndsParameterData(SDDS_dataset);
5443 return (0);
5444 }
5445 }
5446 }
5447#if defined(zLib)
5448 }
5449#endif
5450
5451 SDDS_SwapEndsParameterData(SDDS_dataset);
5452 return (1);
5453}

◆ SDDS_WriteNonNativeBinaryRow()

int32_t SDDS_WriteNonNativeBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row )

Writes a non-native endian binary row to an SDDS dataset.

This function writes a single row of data to the specified SDDS dataset, handling byte order reversal to convert between little-endian and big-endian formats. It supports various compression formats, including uncompressed, GZIP-compressed, and LZMA-compressed files. The function iterates through all column definitions, writing each column's data appropriately based on its type. For string columns, it ensures proper memory management and byte order conversion by utilizing specialized string writing functions. For non-string data types, it writes the binary data directly with the correct byte ordering.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure representing the dataset to write to.
[in]rowThe index of the row to write to the dataset.
Returns
int32_t Returns 1 on successful writing of the binary row, or 0 if an error occurred.
Return values
1The binary row was successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures or corrupted data.
Note
This function modifies the dataset's internal data structures during the write process. Ensure that the dataset is properly initialized and opened for writing before invoking this function. After writing, the dataset's state is updated to reflect the newly written row.

Definition at line 5632 of file SDDS_binary.c.

5632 {
5633 int64_t i, type, size;
5634 SDDS_LAYOUT *layout;
5635 FILE *fp;
5636 struct lzmafile *lzmafp;
5637 SDDS_FILEBUFFER *fBuffer;
5638#if defined(zLib)
5639 gzFile gzfp;
5640#endif
5641
5642 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryRow"))
5643 return (0);
5644 layout = &SDDS_dataset->layout;
5645 fBuffer = &SDDS_dataset->fBuffer;
5646#if defined(zLib)
5647 if (SDDS_dataset->layout.gzipFile) {
5648 gzfp = layout->gzfp;
5649 for (i = 0; i < layout->n_columns; i++) {
5650 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5651 if (!SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
5652 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5653 return (0);
5654 }
5655 } else {
5656 size = SDDS_type_size[type - 1];
5657 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
5658 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5659 return (0);
5660 }
5661 }
5662 }
5663 } else {
5664#endif
5665 if (SDDS_dataset->layout.lzmaFile) {
5666 lzmafp = layout->lzmafp;
5667 for (i = 0; i < layout->n_columns; i++) {
5668 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5669 if (!SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
5670 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5671 return (0);
5672 }
5673 } else {
5674 size = SDDS_type_size[type - 1];
5675 if (!SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
5676 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5677 return (0);
5678 }
5679 }
5680 }
5681 } else {
5682 fp = layout->fp;
5683 for (i = 0; i < layout->n_columns; i++) {
5684 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5685 if (!SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
5686 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5687 return (0);
5688 }
5689 } else {
5690 size = SDDS_type_size[type - 1];
5691 if (!SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
5692 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5693 return (0);
5694 }
5695 }
5696 }
5697 }
5698#if defined(zLib)
5699 }
5700#endif
5701 return (1);
5702}

◆ SDDS_WriteNonNativeBinaryString()

int32_t SDDS_WriteNonNativeBinaryString ( char * string,
FILE * fp,
SDDS_FILEBUFFER * fBuffer )

Writes a non-native endian binary string to a file.

This function writes a binary string to the specified file pointer, handling non-native endianness. It first writes the length of the string as a 32-bit integer with byte order swapped. If the string is not to be skipped, it then writes the string data itself followed by a null terminator. If the input string is NULL, an empty string is written instead.

Parameters
[in]stringThe string to write. If NULL, an empty string is written.
[in]fpPointer to the FILE where the string will be written.
[in]fBufferPointer to the SDDS_FILEBUFFER structure used for buffered writing.
Returns
int32_t Returns 1 on successful writing of the string, or 0 if an error occurred.
Return values
1The string was successfully written and byte-swapped.
0An error occurred during the write operation, such as I/O failures or memory allocation issues.
Note
The caller is responsible for ensuring that the file pointer fp is valid and open for writing. This function does not perform memory allocation for the string; it assumes that the string is already allocated and managed appropriately.

Definition at line 5724 of file SDDS_binary.c.

5724 {
5725 int32_t length;
5726 static const char dummy_string[] = "";
5727 if (!string)
5728 string = (char *)dummy_string;
5729 length = strlen(string);
5730 SDDS_SwapLong(&length);
5731 if (!SDDS_BufferedWrite(&length, sizeof(length), fp, fBuffer)) {
5732 SDDS_SetError("Unable to write string--error writing length");
5733 return (0);
5734 }
5735 SDDS_SwapLong(&length);
5736 if (length && !SDDS_BufferedWrite(string, sizeof(*string) * length, fp, fBuffer)) {
5737 SDDS_SetError("Unable to write string--error writing contents");
5738 return (0);
5739 }
5740 return (1);
5741}