SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
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 <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.
 
int32_t SDDS_SetBufferedRead (int32_t dummy)
 
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 5892 of file SDDS_binary.c.

5892 {
5893 int exponent;
5894 uint64_t mantissa;
5895 unsigned char d[8] = {0};
5896 double result;
5897
5898 if (byteOrder == SDDS_BIGENDIAN_SEEN) {
5899 /* conversion is done in little endian */
5900 char xx;
5901 int i;
5902 for (i = 0; i < 6; i++) {
5903 xx = x[0 + i];
5904 x[0 + i] = x[11 - i];
5905 x[11 - i] = xx;
5906 }
5907 }
5908
5909 exponent = (((x[9] << 8) | x[8]) & 0x7FFF);
5910 mantissa =
5911 ((uint64_t)x[7] << 56) | ((uint64_t)x[6] << 48) | ((uint64_t)x[5] << 40) | ((uint64_t)x[4] << 32) |
5912 ((uint64_t)x[3] << 24) | ((uint64_t)x[2] << 16) | ((uint64_t)x[1] << 8) | (uint64_t)x[0];
5913
5914 d[7] = x[9] & 0x80; /* Set sign. */
5915
5916 if ((exponent == 0x7FFF) || (exponent == 0)) {
5917 /* Infinite, NaN or denormal */
5918 if (exponent == 0x7FFF) {
5919 /* Infinite or NaN */
5920 d[7] |= 0x7F;
5921 d[6] = 0xF0;
5922 } else {
5923 /* Otherwise it's denormal. It cannot be represented as double. Translate as singed zero. */
5924 memcpy(&result, d, 8);
5925 return result;
5926 }
5927 } else {
5928 /* Normal number. */
5929 exponent = exponent - 0x3FFF + 0x03FF; /*< exponent for double precision. */
5930
5931 if (exponent <= -52) /*< Too small to represent. Translate as (signed) zero. */
5932 {
5933 memcpy(&result, d, 8);
5934 return result;
5935 } else if (exponent < 0) {
5936 /* Denormal, exponent bits are already zero here. */
5937 } else if (exponent >= 0x7FF) /*< Too large to represent. Translate as infinite. */
5938 {
5939 d[7] |= 0x7F;
5940 d[6] = 0xF0;
5941 memset(d, 0x00, 6);
5942 memcpy(&result, d, 8);
5943 return result;
5944 } else {
5945 /* Representable number */
5946 d[7] |= (exponent & 0x7F0) >> 4;
5947 d[6] |= (exponent & 0xF) << 4;
5948 }
5949 }
5950 /* Translate mantissa. */
5951
5952 mantissa >>= 11;
5953
5954 if (exponent < 0) {
5955 /* Denormal, further shifting is required here. */
5956 mantissa >>= (-exponent + 1);
5957 }
5958
5959 d[0] = mantissa & 0xFF;
5960 d[1] = (mantissa >> 8) & 0xFF;
5961 d[2] = (mantissa >> 16) & 0xFF;
5962 d[3] = (mantissa >> 24) & 0xFF;
5963 d[4] = (mantissa >> 32) & 0xFF;
5964 d[5] = (mantissa >> 40) & 0xFF;
5965 d[6] |= (mantissa >> 48) & 0x0F;
5966
5967 memcpy(&result, d, 8);
5968
5969 if (byteOrder == SDDS_BIGENDIAN_SEEN) {
5970 /* convert back to big endian */
5971 SDDS_SwapDouble(&result);
5972 }
5973
5974 return result;
5975}
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 96 of file SDDS_binary.c.

96 {
97 int float80tofloat64 = 0;
98 if ((LDBL_DIG != 18) && (type == SDDS_LONGDOUBLE)) {
99 if (getenv("SDDS_LONGDOUBLE_64BITS") == NULL) {
100 targetSize *= 2;
101 float80tofloat64 = 1;
102 }
103 }
104 if (!fBuffer->bufferSize) {
105 /* just read into users buffer or seek if no buffer given */
106 if (!target)
107 return !fseek(fp, (long)targetSize, SEEK_CUR);
108 else {
109 if (float80tofloat64) {
110 unsigned char x[16];
111 double d;
112 int64_t shift = 0;
113 while (shift < targetSize) {
114 if (fread(&x, (size_t)1, 16, fp) != 16)
115 return 0;
116 d = makeFloat64FromFloat80(x, byteOrder);
117 memcpy((char *)target + shift, &d, 8);
118 shift += 16;
119 }
120 return 1;
121 } else {
122 return fread(target, (size_t)1, (size_t)targetSize, fp) == targetSize;
123 }
124 }
125 }
126 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
127 /* sufficient data is already in the buffer */
128 if (target) {
129 if (float80tofloat64) {
130 unsigned char x[16];
131 double d;
132 int64_t shift = 0;
133 while (shift < targetSize) {
134 memcpy(x, (char *)fBuffer->data + shift, 16);
135 d = makeFloat64FromFloat80(x, byteOrder);
136 memcpy((char *)target + shift, &d, 8);
137 shift += 16;
138 }
139 } else {
140 memcpy((char *)target, (char *)fBuffer->data, targetSize);
141 }
142 }
143 fBuffer->data += targetSize;
144 return 1;
145 } else {
146 /* need to read additional data into buffer */
147 int64_t bytesNeeded, offset;
148 fBuffer->bytesLeft += targetSize; /* adds back amount subtracted above */
149
150 /* first, use the data that is already available. this cleans out the buffer */
151 if ((offset = fBuffer->bytesLeft)) {
152 /* some data is available in the buffer */
153 if (target) {
154 if (float80tofloat64) {
155 unsigned char x[16];
156 double d;
157 int64_t shift = 0;
158 while (shift < offset) {
159 memcpy(x, (char *)fBuffer->data + shift, 16);
160 d = makeFloat64FromFloat80(x, byteOrder);
161 memcpy((char *)target + shift, &d, 8);
162 shift += 16;
163 }
164 } else {
165 memcpy((char *)target, (char *)fBuffer->data, offset);
166 }
167 }
168 bytesNeeded = targetSize - offset;
169 fBuffer->bytesLeft = 0;
170 } else {
171 bytesNeeded = targetSize;
172 }
173 fBuffer->data = fBuffer->buffer;
174
175 if (fBuffer->bufferSize < bytesNeeded) {
176 /* just read what is needed directly into user's memory or seek */
177 if (!target)
178 return !fseek(fp, (long)bytesNeeded, SEEK_CUR);
179 else {
180 if (float80tofloat64) {
181 unsigned char x[16];
182 double d;
183 int64_t shift = 0;
184 while (shift < bytesNeeded) {
185 if (fread(&x, (size_t)1, 16, fp) != 16)
186 return 0;
187 d = makeFloat64FromFloat80(x, byteOrder);
188 memcpy((char *)target + offset + shift, &d, 8);
189 shift += 16;
190 }
191 return 1;
192 } else {
193 return fread((char *)target + offset, (size_t)1, (size_t)bytesNeeded, fp) == bytesNeeded;
194 }
195 }
196 }
197
198 /* fill the buffer */
199 if ((fBuffer->bytesLeft = fread(fBuffer->data, (size_t)1, (size_t)fBuffer->bufferSize, fp)) < bytesNeeded)
200 return 0;
201 if (target) {
202 if (float80tofloat64) {
203 unsigned char x[16];
204 double d;
205 int64_t shift = 0;
206 while (shift < bytesNeeded) {
207 memcpy(x, (char *)fBuffer->data + shift, 16);
208 d = makeFloat64FromFloat80(x, byteOrder);
209 memcpy((char *)target + offset + shift, &d, 8);
210 shift += 16;
211 }
212 } else {
213 memcpy((char *)target + offset, (char *)fBuffer->data, bytesNeeded);
214 }
215 }
216 fBuffer->data += bytesNeeded;
217 fBuffer->bytesLeft -= bytesNeeded;
218 return 1;
219 }
220}
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 484 of file SDDS_binary.c.

484 {
485 if (!fBuffer->bufferSize) {
486 return fwrite(target, (size_t)1, (size_t)targetSize, fp) == targetSize;
487 }
488 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
489 memcpy((char *)fBuffer->data, (char *)target, targetSize);
490 fBuffer->data += targetSize;
491#ifdef DEBUG
492 fprintf(stderr, "SDDS_BufferedWrite of %" PRId64 " bytes done in-memory, %" PRId64 " bytes left\n", targetSize, fBuffer->bytesLeft);
493#endif
494 return 1;
495 } else {
496 int64_t lastLeft;
497 /* add back what was subtracted in test above.
498 * lastLeft is the number of bytes left in the buffer before doing anything
499 * and also the number of bytes from the users data that get copied into the buffer.
500 */
501 lastLeft = (fBuffer->bytesLeft += targetSize);
502 /* copy part of the data into the buffer and write the buffer out */
503 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
504 if (fwrite(fBuffer->buffer, (size_t)1, (size_t)fBuffer->bufferSize, fp) != fBuffer->bufferSize)
505 return 0;
506 if (fflush(fp)) {
507 SDDS_SetError("Problem flushing file (SDDS_BufferedWrite)");
508 SDDS_SetError(strerror(errno));
509 return 0;
510 }
511 /* reset the data pointer and the bytesLeft value.
512 * also, determine if the remaining data is too large for the buffer.
513 * if so, just write it out.
514 */
515 fBuffer->data = fBuffer->buffer;
516 if ((targetSize -= lastLeft) > (fBuffer->bytesLeft = fBuffer->bufferSize)) {
517 return fwrite((char *)target + lastLeft, (size_t)1, (size_t)targetSize, fp) == targetSize;
518 }
519 /* copy remaining data into the buffer.
520 * could do this with a recursive call, but this is more efficient.
521 */
522 memcpy((char *)fBuffer->data, (char *)target + lastLeft, targetSize);
523 fBuffer->data += targetSize;
524 fBuffer->bytesLeft -= targetSize;
525 return 1;
526 }
527}
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379

◆ 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 632 of file SDDS_binary.c.

632 {
633 int64_t writeBytes;
634 if (!fp) {
635 SDDS_SetError("Unable to flush buffer: file pointer is NULL. (SDDS_FlushBuffer)");
636 return 0;
637 }
638 if (!fBuffer->bufferSize) {
639 if (fflush(fp)) {
640 SDDS_SetError("Problem flushing file (SDDS_FlushBuffer.1)");
641 SDDS_SetError(strerror(errno));
642 return 0;
643 }
644 return 1;
645 }
646 if (!fBuffer) {
647 SDDS_SetError("Unable to flush buffer: buffer pointer is NULL. (SDDS_FlushBuffer)");
648 return 0;
649 }
650 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
651 if (writeBytes < 0) {
652 SDDS_SetError("Unable to flush buffer: negative byte count (SDDS_FlushBuffer).");
653 return 0;
654 }
655#ifdef DEBUG
656 fprintf(stderr, "Writing %" PRId64 " bytes to disk\n", writeBytes);
657#endif
658 if (fwrite(fBuffer->buffer, 1, writeBytes, fp) != writeBytes) {
659 SDDS_SetError("Unable to flush buffer: write operation failed (SDDS_FlushBuffer).");
660 return 0;
661 }
662 fBuffer->bytesLeft = fBuffer->bufferSize;
663 fBuffer->data = fBuffer->buffer;
664 }
665 if (fflush(fp)) {
666 SDDS_SetError("Problem flushing file (SDDS_FlushBuffer.2)");
667 SDDS_SetError(strerror(errno));
668 return 0;
669 }
670 return 1;
671}

◆ 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 1258 of file SDDS_binary.c.

1258 {
1259 int32_t try;
1260#if defined(vxWorks)
1261 struct timespec rqtp;
1262 rqtp.tv_sec = 1;
1263 rqtp.tv_nsec = 0;
1264#endif
1265 for (try = 0; try < FSEEK_TRIES; try++) {
1266 if (fseek(fp, offset, dir) == -1) {
1267#if defined(vxWorks)
1268 nanosleep(&rqtp, NULL);
1269#else
1270 sleep(1);
1271#endif
1272 } else
1273 break;
1274 }
1275 if (try == 0)
1276 return 0;
1277 if (try == FSEEK_TRIES) {
1278 fputs("warning: fseek problems--unable to recover\n", stderr);
1279 return -1;
1280 }
1281 fputs("warning: fseek problems--recovered\n", stderr);
1282 return 0;
1283}

◆ 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 243 of file SDDS_binary.c.

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

◆ 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 550 of file SDDS_binary.c.

550 {
551 if (!fBuffer->bufferSize) {
552 SDDS_SetError("You must presently have a nonzero file buffer to use lzma (reading/writing .xz files)");
553 return 0;
554 }
555 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
556 memcpy((char *)fBuffer->data, (char *)target, targetSize);
557 fBuffer->data += targetSize;
558 return 1;
559 } else {
560 int64_t lastLeft;
561 lastLeft = (fBuffer->bytesLeft += targetSize);
562 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
563 if (lzma_write(lzmafp, fBuffer->buffer, (size_t)fBuffer->bufferSize) != fBuffer->bufferSize)
564 return 0;
565 fBuffer->bytesLeft = fBuffer->bufferSize;
566 fBuffer->data = fBuffer->buffer;
567 return SDDS_LZMABufferedWrite((char *)target + lastLeft, targetSize - lastLeft, lzmafp, fBuffer);
568 }
569}
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 687 of file SDDS_binary.c.

687 {
688 int32_t writeBytes;
689 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
690 if (lzma_write(lzmafp, fBuffer->buffer, writeBytes) != writeBytes)
691 return 0;
692 fBuffer->bytesLeft = fBuffer->bufferSize;
693 fBuffer->data = fBuffer->buffer;
694 }
695 return 1;
696}

◆ 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 1312 of file SDDS_binary.c.

1312 {
1313 int32_t try;
1314#if defined(vxWorks)
1315 struct timespec rqtp;
1316 rqtp.tv_sec = 1;
1317 rqtp.tv_nsec = 0;
1318#endif
1319 for (try = 0; try < FSEEK_TRIES; try++) {
1320 if (lzma_seek(lzmafp, offset, dir) == -1) {
1321#if defined(vxWorks)
1322 nanosleep(&rqtp, NULL);
1323#else
1324 sleep(1);
1325#endif
1326 } else
1327 break;
1328 }
1329 if (try == 0)
1330 return 0;
1331 if (try == FSEEK_TRIES) {
1332 fputs("warning: lzma_seek problems--unable to recover\n", stderr);
1333 return -1;
1334 }
1335 fputs("warning: lzma_seek problems--recovered\n", stderr);
1336 return 0;
1337}

◆ 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 2549 of file SDDS_binary.c.

2549 {
2550 int32_t length;
2551 static char *dummy_string = "";
2552 if (!string)
2553 string = dummy_string;
2554 length = strlen(string);
2555 if (!SDDS_LZMABufferedWrite(&length, sizeof(length), lzmafp, fBuffer)) {
2556 SDDS_SetError("Unable to write string--error writing length");
2557 return (0);
2558 }
2559 if (length && !SDDS_LZMABufferedWrite(string, sizeof(*string) * length, lzmafp, fBuffer)) {
2560 SDDS_SetError("Unable to write string--error writing contents");
2561 return (0);
2562 }
2563 return (1);
2564}

◆ 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 5636 of file SDDS_binary.c.

5636 {
5637 int32_t length;
5638 static char *dummy_string = "";
5639 if (!string)
5640 string = dummy_string;
5641 length = strlen(string);
5642 SDDS_SwapLong(&length);
5643 if (!SDDS_LZMABufferedWrite(&length, sizeof(length), lzmafp, fBuffer)) {
5644 SDDS_SetError("Unable to write string--error writing length");
5645 return (0);
5646 }
5647 SDDS_SwapLong(&length);
5648 if (length && !SDDS_LZMABufferedWrite(string, sizeof(*string) * length, lzmafp, fBuffer)) {
5649 SDDS_SetError("Unable to write string--error writing contents");
5650 return (0);
5651 }
5652 return (1);
5653}
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 3059 of file SDDS_binary.c.

3059 {
3060 int32_t i, j;
3061 SDDS_LAYOUT *layout;
3062 /* char *predefined_format; */
3063 /* static char buffer[SDDS_MAXLINE]; */
3064#if defined(zLib)
3065 gzFile gzfp = NULL;
3066#endif
3067 FILE *fp = NULL;
3068 struct lzmafile *lzmafp = NULL;
3069 SDDS_ARRAY *array;
3070 SDDS_FILEBUFFER *fBuffer;
3071
3072 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryArrays"))
3073 return (0);
3074 layout = &SDDS_dataset->layout;
3075 if (!layout->n_arrays)
3076 return (1);
3077#if defined(zLib)
3078 if (SDDS_dataset->layout.gzipFile) {
3079 gzfp = layout->gzfp;
3080 } else {
3081#endif
3082 if (SDDS_dataset->layout.lzmaFile) {
3083 lzmafp = layout->lzmafp;
3084 } else {
3085 fp = layout->fp;
3086 }
3087#if defined(zLib)
3088 }
3089#endif
3090 fBuffer = &SDDS_dataset->fBuffer;
3091 if (!SDDS_dataset->array) {
3092 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_ReadBinaryArrays)");
3093 return (0);
3094 }
3095 for (i = 0; i < layout->n_arrays; i++) {
3096 array = SDDS_dataset->array + i;
3097 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
3098 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_ReadBinaryArrays)");
3099 return (0);
3100 }
3101 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
3102 SDDS_SetError("Unable to read array--definition copy failed (SDDS_ReadBinaryArrays)");
3103 return (0);
3104 }
3105 /*if (array->dimension) free(array->dimension); */
3106 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
3107 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadBinaryArrays)");
3108 return (0);
3109 }
3110#if defined(zLib)
3111 if (SDDS_dataset->layout.gzipFile) {
3112 if (!SDDS_GZipBufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, gzfp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3113 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3114 return (0);
3115 }
3116 } else {
3117#endif
3118 if (SDDS_dataset->layout.lzmaFile) {
3119 if (!SDDS_LZMABufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, lzmafp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3120 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3121 return (0);
3122 }
3123 } else {
3124 if (!SDDS_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, fp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
3125 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadBinaryArrays)");
3126 return (0);
3127 }
3128 }
3129#if defined(zLib)
3130 }
3131#endif
3132 array->elements = 1;
3133 for (j = 0; j < array->definition->dimensions; j++)
3134 array->elements *= array->dimension[j];
3135 if (array->data)
3136 free(array->data);
3137 array->data = array->pointer = NULL;
3138 if (array->elements == 0)
3139 continue;
3140 if (array->elements < 0) {
3141 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_ReadBinaryArrays)");
3142 return (0);
3143 }
3144 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
3145 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadBinaryArrays)");
3146 return (0);
3147 }
3148 if (array->definition->type == SDDS_STRING) {
3149#if defined(zLib)
3150 if (SDDS_dataset->layout.gzipFile) {
3151 for (j = 0; j < array->elements; j++) {
3152 if (!(((char **)(array->data))[j] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
3153 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3154 return (0);
3155 }
3156 }
3157 } else {
3158#endif
3159 if (SDDS_dataset->layout.lzmaFile) {
3160 for (j = 0; j < array->elements; j++) {
3161 if (!(((char **)(array->data))[j] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3162 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3163 return (0);
3164 }
3165 }
3166 } else {
3167 for (j = 0; j < array->elements; j++) {
3168 if (!(((char **)(array->data))[j] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3169 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadBinaryArrays)");
3170 return (0);
3171 }
3172 }
3173 }
3174#if defined(zLib)
3175 }
3176#endif
3177 } else {
3178#if defined(zLib)
3179 if (SDDS_dataset->layout.gzipFile) {
3180 if (!SDDS_GZipBufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, gzfp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3181 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3182 return (0);
3183 }
3184 } else {
3185#endif
3186 if (SDDS_dataset->layout.lzmaFile) {
3187 if (!SDDS_LZMABufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, lzmafp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3188 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3189 return (0);
3190 }
3191 } else {
3192 if (!SDDS_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, fp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
3193 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadBinaryArrays)");
3194 return (0);
3195 }
3196 }
3197#if defined(zLib)
3198 }
3199#endif
3200 }
3201 }
3202 return (1);
3203}
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)
Definition SDDS_binary.c:96
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:552
ARRAY_DEFINITION * SDDS_CopyArrayDefinition(ARRAY_DEFINITION **target, ARRAY_DEFINITION *source)
Creates a copy of an array definition.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#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 3224 of file SDDS_binary.c.

3224 {
3225 int64_t i, j, k, row;
3226 SDDS_LAYOUT *layout;
3227 /* char *predefined_format; */
3228 /* static char buffer[SDDS_MAXLINE]; */
3229#if defined(zLib)
3230 gzFile gzfp = NULL;
3231#endif
3232 FILE *fp = NULL;
3233 struct lzmafile *lzmafp = NULL;
3234 SDDS_FILEBUFFER *fBuffer;
3235
3236 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryColumns"))
3237 return (0);
3238 layout = &SDDS_dataset->layout;
3239 if (!layout->n_columns || !SDDS_dataset->n_rows)
3240 return (1);
3241#if defined(zLib)
3242 if (SDDS_dataset->layout.gzipFile) {
3243 gzfp = layout->gzfp;
3244 } else {
3245#endif
3246 if (SDDS_dataset->layout.lzmaFile) {
3247 lzmafp = layout->lzmafp;
3248 } else {
3249 fp = layout->fp;
3250 }
3251#if defined(zLib)
3252 }
3253#endif
3254 fBuffer = &SDDS_dataset->fBuffer;
3255
3256 for (i = 0; i < layout->n_columns; i++) {
3257 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
3258 continue;
3259 if (layout->column_definition[i].type == SDDS_STRING) {
3260#if defined(zLib)
3261 if (SDDS_dataset->layout.gzipFile) {
3262 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3263 if (((char ***)SDDS_dataset->data)[i][row])
3264 free((((char ***)SDDS_dataset->data)[i][row]));
3265 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
3266 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumns)");
3267 return (0);
3268 }
3269 }
3270 } else {
3271#endif
3272 if (SDDS_dataset->layout.lzmaFile) {
3273 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3274 if (((char ***)SDDS_dataset->data)[i][row])
3275 free((((char ***)SDDS_dataset->data)[i][row]));
3276 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3277 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumms)");
3278 return (0);
3279 }
3280 }
3281 } else {
3282 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3283 if (((char ***)SDDS_dataset->data)[i][row])
3284 free((((char ***)SDDS_dataset->data)[i][row]));
3285 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3286 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadBinaryColumms)");
3287 return (0);
3288 }
3289 }
3290 }
3291#if defined(zLib)
3292 }
3293#endif
3294 } else {
3295#if defined(zLib)
3296 if (SDDS_dataset->layout.gzipFile) {
3297 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)) {
3298 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3299 return (0);
3300 }
3301 } else {
3302#endif
3303 if (SDDS_dataset->layout.lzmaFile) {
3304 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)) {
3305 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3306 return (0);
3307 }
3308 } else {
3309 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)) {
3310 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadBinaryColumns)");
3311 return (0);
3312 }
3313 }
3314#if defined(zLib)
3315 }
3316#endif
3317 }
3318 }
3319
3320 if (sparse_interval == 1 && sparse_offset == 0) {
3321 return(1);
3322 }
3323
3324 j = SDDS_dataset->n_rows;
3325 for (i = 0; i < layout->n_columns; i++) {
3326 j = k = 0;
3327 switch (layout->column_definition[i].type) {
3328 case SDDS_SHORT:
3329 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3330 if (k % sparse_interval == 0) {
3331 ((short*)SDDS_dataset->data[i])[j] = ((short*)SDDS_dataset->data[i])[row];
3332 j++;
3333 }
3334 k++;
3335 }
3336 break;
3337 case SDDS_USHORT:
3338 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3339 if (k % sparse_interval == 0) {
3340 ((unsigned short*)SDDS_dataset->data[i])[j] = ((unsigned short*)SDDS_dataset->data[i])[row];
3341 j++;
3342 }
3343 k++;
3344 }
3345 break;
3346 case SDDS_LONG:
3347 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3348 if (k % sparse_interval == 0) {
3349 ((int32_t*)SDDS_dataset->data[i])[j] = ((int32_t*)SDDS_dataset->data[i])[row];
3350 j++;
3351 }
3352 k++;
3353 }
3354 break;
3355 case SDDS_ULONG:
3356 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3357 if (k % sparse_interval == 0) {
3358 ((uint32_t*)SDDS_dataset->data[i])[j] = ((uint32_t*)SDDS_dataset->data[i])[row];
3359 j++;
3360 }
3361 k++;
3362 }
3363 break;
3364 case SDDS_LONG64:
3365 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3366 if (k % sparse_interval == 0) {
3367 ((int64_t*)SDDS_dataset->data[i])[j] = ((int64_t*)SDDS_dataset->data[i])[row];
3368 j++;
3369 }
3370 k++;
3371 }
3372 break;
3373 case SDDS_ULONG64:
3374 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3375 if (k % sparse_interval == 0) {
3376 ((uint64_t*)SDDS_dataset->data[i])[j] = ((uint64_t*)SDDS_dataset->data[i])[row];
3377 j++;
3378 }
3379 k++;
3380 }
3381 break;
3382 case SDDS_FLOAT:
3383 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3384 if (k % sparse_interval == 0) {
3385 ((float*)SDDS_dataset->data[i])[j] = ((float*)SDDS_dataset->data[i])[row];
3386 j++;
3387 }
3388 k++;
3389 }
3390 break;
3391 case SDDS_DOUBLE:
3392 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3393 if (k % sparse_interval == 0) {
3394 ((double*)SDDS_dataset->data[i])[j] = ((double*)SDDS_dataset->data[i])[row];
3395 j++;
3396 }
3397 k++;
3398 }
3399 break;
3400 case SDDS_LONGDOUBLE:
3401 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3402 if (k % sparse_interval == 0) {
3403 ((long double*)SDDS_dataset->data[i])[j] = ((long double*)SDDS_dataset->data[i])[row];
3404 j++;
3405 }
3406 k++;
3407 }
3408 break;
3409 case SDDS_STRING:
3410 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3411 if (k % sparse_interval == 0) {
3412 ((char**)SDDS_dataset->data[i])[j] = ((char**)SDDS_dataset->data[i])[row];
3413 j++;
3414 }
3415 k++;
3416 }
3417 for (k=j; k<SDDS_dataset->n_rows; k++) {
3418 if (((char ***)SDDS_dataset->data)[i][k]) {
3419 free((((char ***)SDDS_dataset->data)[i][k]));
3420 ((char ***)SDDS_dataset->data)[i][k] = NULL;
3421 }
3422 }
3423
3424 break;
3425 case SDDS_CHARACTER:
3426 for (row = sparse_offset; row < SDDS_dataset->n_rows; row++) {
3427 if (k % sparse_interval == 0) {
3428 ((char*)SDDS_dataset->data[i])[j] = ((char*)SDDS_dataset->data[i])[row];
3429 j++;
3430 }
3431 k++;
3432 }
3433 break;
3434 default:
3435 break;
3436 }
3437 }
3438
3439 SDDS_dataset->n_rows = j;
3440
3441 return (1);
3442}
#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 2120 of file SDDS_binary.c.

2120 {
2121 return SDDS_ReadBinaryPageDetailed(SDDS_dataset, sparse_interval, sparse_offset, 0, sparse_statistics);
2122}
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 2202 of file SDDS_binary.c.

2202 {
2203 int32_t n_rows32;
2204 int64_t n_rows, i, j, k, alloc_rows, rows_to_store, mod;
2205
2206 /* int32_t page_number, i; */
2207#if defined(zLib)
2208 gzFile gzfp = NULL;
2209#endif
2210 FILE *fp = NULL;
2211 struct lzmafile *lzmafp = NULL;
2212 SDDS_FILEBUFFER *fBuffer;
2213 void **statData=NULL;
2214 double statResult;
2215
2216 if (SDDS_dataset->autoRecovered)
2217 return -1;
2218 if (SDDS_dataset->swapByteOrder) {
2219 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, 0, sparse_interval, sparse_offset, last_rows);
2220 }
2221
2222 /* static char s[SDDS_MAXLINE]; */
2223 n_rows = 0;
2224 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
2225#if defined(zLib)
2226 if (SDDS_dataset->layout.gzipFile) {
2227 gzfp = SDDS_dataset->layout.gzfp;
2228 } else {
2229#endif
2230 if (SDDS_dataset->layout.lzmaFile) {
2231 lzmafp = SDDS_dataset->layout.lzmafp;
2232 } else {
2233 fp = SDDS_dataset->layout.fp;
2234 }
2235#if defined(zLib)
2236 }
2237#endif
2238 fBuffer = &SDDS_dataset->fBuffer;
2239 if (!fBuffer->buffer) {
2240 if (defaultIOBufferSize == 0 && (SDDS_dataset->layout.popenUsed || !SDDS_dataset->layout.filename) && (sparse_interval > 1 || sparse_offset > 0 || last_rows > 0)) {
2241 SDDS_SetError("The IO buffer size is 0 for data being read from a pipe with sparsing. This is not supported.");
2242 return 0;
2243 }
2244 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (defaultIOBufferSize + 1)))) {
2245 SDDS_SetError("Unable to do buffered read--allocation failure");
2246 return 0;
2247 }
2248 fBuffer->bufferSize = defaultIOBufferSize;
2249 fBuffer->bytesLeft = 0;
2250 }
2251 SDDS_dataset->rowcount_offset = -1;
2252#if defined(zLib)
2253 if (SDDS_dataset->layout.gzipFile) {
2254 if (!SDDS_GZipBufferedRead(&n_rows32, sizeof(n_rows32), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2255 if (gzeof(gzfp))
2256 return (SDDS_dataset->page_number = -1);
2257 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2258 return (0);
2259 }
2260 if (n_rows32 == INT32_MIN) {
2261 if (!SDDS_GZipBufferedRead(&n_rows, sizeof(n_rows), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2262 if (gzeof(gzfp))
2263 return (SDDS_dataset->page_number = -1);
2264 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2265 return (0);
2266 }
2267 } else {
2268 n_rows = n_rows32;
2269 }
2270 } else {
2271#endif
2272 /* This value will only be valid if read buffering is turned off, which is done for
2273 * certain append operations! Should really modify SDDS_BufferedRead and SDDS_BufferedWrite
2274 * to provide ftell capability.
2275 */
2276 if (SDDS_dataset->layout.lzmaFile) {
2277 if (!SDDS_LZMABufferedRead(&n_rows32, sizeof(n_rows32), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2278 if (lzma_eof(lzmafp))
2279 return (SDDS_dataset->page_number = -1);
2280 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2281 return (0);
2282 }
2283 if (n_rows32 == INT32_MIN) {
2284 if (!SDDS_LZMABufferedRead(&n_rows, sizeof(n_rows), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2285 if (lzma_eof(lzmafp))
2286 return (SDDS_dataset->page_number = -1);
2287 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2288 return (0);
2289 }
2290 } else {
2291 n_rows = n_rows32;
2292 }
2293 } else {
2294 SDDS_dataset->rowcount_offset = ftell(fp);
2295 if (!SDDS_BufferedRead(&n_rows32, sizeof(n_rows32), fp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
2296 if (feof(fp))
2297 return (SDDS_dataset->page_number = -1);
2298 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2299 return (0);
2300 }
2301 if (n_rows32 == INT32_MIN) {
2302 if (!SDDS_BufferedRead(&n_rows, sizeof(n_rows), fp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
2303 if (feof(fp))
2304 return (SDDS_dataset->page_number = -1);
2305 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadBinaryPageDetailed)");
2306 return (0);
2307 }
2308 } else {
2309 n_rows = n_rows32;
2310 }
2311 }
2312#if defined(zLib)
2313 }
2314#endif
2315
2316#if defined(DEBUG)
2317 fprintf(stderr, "Expect %" PRId64 " rows of data\n", n_rows);
2318#endif
2319 if (n_rows < 0) {
2320 SDDS_SetError("Unable to read page--negative number of rows (SDDS_ReadBinaryPageDetailed)");
2321 return (0);
2322 }
2323 if (SDDS_dataset->layout.byteOrderDeclared == 0) {
2324 if (n_rows > 10000000) {
2325 SDDS_SetError("Unable to read page--endian byte order not declared and suspected to be non-native. (SDDS_ReadBinaryPageDetailed)");
2326 return (0);
2327 }
2328 }
2329 if (n_rows > SDDS_GetRowLimit()) {
2330 /* the number of rows is "unreasonably" large---treat like end-of-file */
2331 return (SDDS_dataset->page_number = -1);
2332 }
2333 if (last_rows < 0)
2334 last_rows = 0;
2335 /* Fix this limitation later */
2336 if (SDDS_dataset->layout.data_mode.column_major && sparse_statistics != 0) {
2337 SDDS_SetError("sparse_statistics is not yet supported for column-major layout. Use sddsconvert -majorOrder=row to convert first.\n");
2338 return (0);
2339 }
2340
2341 if (last_rows) {
2342 sparse_interval = 1;
2343 sparse_offset = n_rows - last_rows;
2344 }
2345 if (sparse_interval <= 0)
2346 sparse_interval = 1;
2347 if (sparse_offset < 0)
2348 sparse_offset = 0;
2349
2350 rows_to_store = (n_rows - sparse_offset) / sparse_interval + 2;
2351 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
2352
2353 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, alloc_rows)) {
2354 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadBinaryPageDetailed)");
2355 return (0);
2356 }
2357
2358 /* read the parameter values */
2359 if (!SDDS_ReadBinaryParameters(SDDS_dataset)) {
2360 SDDS_SetError("Unable to read page--parameter reading error (SDDS_ReadBinaryPageDetailed)");
2361 return (0);
2362 }
2363
2364 /* read the array values */
2365 if (!SDDS_ReadBinaryArrays(SDDS_dataset)) {
2366 SDDS_SetError("Unable to read page--array reading error (SDDS_ReadBinaryPageDetailed)");
2367 return (0);
2368 }
2369 if (SDDS_dataset->layout.data_mode.column_major) {
2370 SDDS_dataset->n_rows = n_rows;
2371 if (!SDDS_ReadBinaryColumns(SDDS_dataset, sparse_interval, sparse_offset)) {
2372 SDDS_SetError("Unable to read page--column reading error (SDDS_ReadBinaryPageDetailed)");
2373 return (0);
2374 }
2375 return (SDDS_dataset->page_number);
2376 }
2377 if ((sparse_interval <= 1) && (sparse_offset == 0)) {
2378 for (j = 0; j < n_rows; j++) {
2379 if (!SDDS_ReadBinaryRow(SDDS_dataset, j, 0)) {
2380 SDDS_dataset->n_rows = j;
2381 if (SDDS_dataset->autoRecover) {
2382#if defined(DEBUG)
2383 fprintf(stderr, "Doing auto-read recovery\n");
2384#endif
2385 SDDS_dataset->autoRecovered = 1;
2387 return (SDDS_dataset->page_number);
2388 }
2389 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2390 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2391 return (0);
2392 }
2393 }
2394 SDDS_dataset->n_rows = j;
2395 return (SDDS_dataset->page_number);
2396 } else {
2397 for (j = 0; j < sparse_offset; j++) {
2398 if (!SDDS_ReadBinaryRow(SDDS_dataset, 0, 1)) {
2399 SDDS_dataset->n_rows = 0;
2400 if (SDDS_dataset->autoRecover) {
2401 SDDS_dataset->autoRecovered = 1;
2403 return (SDDS_dataset->page_number);
2404 }
2405 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2406 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2407 return (0);
2408 }
2409 }
2410 n_rows -= sparse_offset;
2411 if (sparse_statistics != 0) {
2412 // Allocate buffer space for statistical sparsing
2413 statData = (void**)malloc(SDDS_dataset->layout.n_columns * sizeof(void*));
2414 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2415 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2416 // Not ideal for SDDS_LONGDOUBLE but we may never run across this error
2417 statData[i] = (double*)calloc(sparse_interval, sizeof(double));
2418 }
2419 }
2420 for (j = k = 0; j < n_rows; j++) {
2421 if (!SDDS_ReadBinaryRow(SDDS_dataset, k, 0)) {
2422 SDDS_dataset->n_rows = k;
2423 if (SDDS_dataset->autoRecover) {
2424 SDDS_dataset->autoRecovered = 1;
2426 return (SDDS_dataset->page_number);
2427 }
2428 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2429 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2430 return (0);
2431 }
2432 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2433 switch (SDDS_dataset->layout.column_definition[i].type) {
2434 case SDDS_FLOAT:
2435 ((double*)statData[i])[j % sparse_interval] = (double)(((float*)SDDS_dataset->data[i])[k]);
2436 break;
2437 case SDDS_DOUBLE:
2438 ((double*)statData[i])[j % sparse_interval] = ((double*)SDDS_dataset->data[i])[k];
2439 break;
2440 case SDDS_LONGDOUBLE:
2441 ((double*)statData[i])[j % sparse_interval] = (double)(((long double*)SDDS_dataset->data[i])[k]);
2442 break;
2443 }
2444 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2445 if (sparse_statistics == 1) {
2446 // Sparse and get average statistics
2447 compute_average(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2448 } else if (sparse_statistics == 2) {
2449 // Sparse and get median statistics
2450 compute_median(&statResult, (double*)statData[i], (j % sparse_interval) + 1);
2451 } else if (sparse_statistics == 3) {
2452 // Sparse and get minimum statistics
2453 statResult = min_in_array((double*)statData[i], (j % sparse_interval) + 1);
2454 } else if (sparse_statistics == 4) {
2455 // Sparse and get maximum statistics
2456 statResult = max_in_array((double*)statData[i], (j % sparse_interval) + 1);
2457 }
2458 }
2459 switch (SDDS_dataset->layout.column_definition[i].type) {
2460 case SDDS_FLOAT:
2461 ((float*)SDDS_dataset->data[i])[k] = statResult;
2462 break;
2463 case SDDS_DOUBLE:
2464 ((double*)SDDS_dataset->data[i])[k] = statResult;
2465 break;
2466 case SDDS_LONGDOUBLE:
2467 ((long double*)SDDS_dataset->data[i])[k] = statResult;
2468 break;
2469 }
2470 }
2471 if (j % sparse_interval == sparse_interval - 1) {
2472 k++;
2473 }
2474 }
2475 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2476 if (SDDS_FLOATING_TYPE(SDDS_dataset->layout.column_definition[i].type)) {
2477 free(statData[i]);
2478 }
2479 }
2480 free(statData);
2481 } else {
2482 for (j = k = 0; j < n_rows; j++) {
2483 if (!SDDS_ReadBinaryRow(SDDS_dataset, k, mod = j % sparse_interval)) {
2484 SDDS_dataset->n_rows = k;
2485 if (SDDS_dataset->autoRecover) {
2486 SDDS_dataset->autoRecovered = 1;
2488 return (SDDS_dataset->page_number);
2489 }
2490 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadBinaryPageDetailed)");
2491 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2492 return (0);
2493 }
2494 k += mod ? 0 : 1;
2495 }
2496 }
2497 SDDS_dataset->n_rows = k;
2498 return (SDDS_dataset->page_number);
2499 }
2500}
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:639
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
Definition SDDS_utils.c:318
#define SDDS_FLOATING_TYPE(type)
Checks if the given type identifier corresponds to a floating-point type.
Definition SDDStypes.h:124
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:144
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 2150 of file SDDS_binary.c.

2150 {
2151 return SDDS_ReadBinaryPageDetailed(SDDS_dataset, 1, 0, last_rows, 0);
2152}

◆ 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 2947 of file SDDS_binary.c.

2947 {
2948 int32_t i;
2949 SDDS_LAYOUT *layout;
2950 /* char *predefined_format; */
2951 char buffer[SDDS_MAXLINE];
2952#if defined(zLib)
2953 gzFile gzfp = NULL;
2954#endif
2955 FILE *fp = NULL;
2956 struct lzmafile *lzmafp = NULL;
2957 SDDS_FILEBUFFER *fBuffer;
2958
2959 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryParameters"))
2960 return (0);
2961 layout = &SDDS_dataset->layout;
2962 if (!layout->n_parameters)
2963 return (1);
2964#if defined(zLib)
2965 if (SDDS_dataset->layout.gzipFile) {
2966 gzfp = layout->gzfp;
2967 } else {
2968#endif
2969 if (SDDS_dataset->layout.lzmaFile) {
2970 lzmafp = layout->lzmafp;
2971 } else {
2972 fp = layout->fp;
2973 }
2974#if defined(zLib)
2975 }
2976#endif
2977 fBuffer = &SDDS_dataset->fBuffer;
2978 for (i = 0; i < layout->n_parameters; i++) {
2979 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2980 continue;
2981 if (layout->parameter_definition[i].fixed_value) {
2982 strcpy(buffer, layout->parameter_definition[i].fixed_value);
2983 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
2984 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadBinaryParameters)");
2985 return (0);
2986 }
2987 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
2988 if (*(char **)SDDS_dataset->parameter[i])
2989 free(*(char **)SDDS_dataset->parameter[i]);
2990#if defined(zLib)
2991 if (SDDS_dataset->layout.gzipFile) {
2992 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
2993 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
2994 return (0);
2995 }
2996 } else {
2997#endif
2998 if (SDDS_dataset->layout.lzmaFile) {
2999 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
3000 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
3001 return (0);
3002 }
3003 } else {
3004 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
3005 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadBinaryParameters)");
3006 return (0);
3007 }
3008 }
3009#if defined(zLib)
3010 }
3011#endif
3012 } else {
3013#if defined(zLib)
3014 if (SDDS_dataset->layout.gzipFile) {
3015 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)) {
3016 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3017 return (0);
3018 }
3019 } else {
3020#endif
3021 if (SDDS_dataset->layout.lzmaFile) {
3022 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)) {
3023 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3024 return (0);
3025 }
3026 } else {
3027 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)) {
3028 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadBinaryParameters)");
3029 return (0);
3030 }
3031 }
3032#if defined(zLib)
3033 }
3034#endif
3035 }
3036 }
3037 return (1);
3038}
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 2711 of file SDDS_binary.c.

2711 {
2712 int64_t i, type, size;
2713 SDDS_LAYOUT *layout;
2714#if defined(zLib)
2715 gzFile gzfp;
2716#endif
2717 FILE *fp;
2718 struct lzmafile *lzmafp;
2719 SDDS_FILEBUFFER *fBuffer;
2720
2721 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadBinaryRow"))
2722 return (0);
2723 layout = &SDDS_dataset->layout;
2724 fBuffer = &SDDS_dataset->fBuffer;
2725
2726#if defined(zLib)
2727 if (SDDS_dataset->layout.gzipFile) {
2728 gzfp = layout->gzfp;
2729 for (i = 0; i < layout->n_columns; i++) {
2730 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2731 continue;
2732 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2733 if (!skip) {
2734 if (((char ***)SDDS_dataset->data)[i][row])
2735 free((((char ***)SDDS_dataset->data)[i][row]));
2736 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadGZipBinaryString(gzfp, fBuffer, 0))) {
2737 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2738 return (0);
2739 }
2740 } else {
2741 if (!SDDS_ReadGZipBinaryString(gzfp, fBuffer, 1)) {
2742 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2743 return 0;
2744 }
2745 }
2746 } else {
2747 size = SDDS_type_size[type - 1];
2748 if (!SDDS_GZipBufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2749 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2750 return (0);
2751 }
2752 }
2753 }
2754 } else {
2755#endif
2756 if (SDDS_dataset->layout.lzmaFile) {
2757 lzmafp = layout->lzmafp;
2758 for (i = 0; i < layout->n_columns; i++) {
2759 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2760 continue;
2761 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2762 if (!skip) {
2763 if (((char ***)SDDS_dataset->data)[i][row])
2764 free((((char ***)SDDS_dataset->data)[i][row]));
2765 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 0))) {
2766 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2767 return (0);
2768 }
2769 } else {
2770 if (!SDDS_ReadLZMABinaryString(lzmafp, fBuffer, 1)) {
2771 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2772 return 0;
2773 }
2774 }
2775 } else {
2776 size = SDDS_type_size[type - 1];
2777 if (!SDDS_LZMABufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2778 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2779 return (0);
2780 }
2781 }
2782 }
2783 } else {
2784 fp = layout->fp;
2785 for (i = 0; i < layout->n_columns; i++) {
2786 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
2787 continue;
2788 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2789 if (!skip) {
2790 if (((char ***)SDDS_dataset->data)[i][row])
2791 free((((char ***)SDDS_dataset->data)[i][row]));
2792 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadBinaryString(fp, fBuffer, 0))) {
2793 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2794 return (0);
2795 }
2796 } else {
2797 if (!SDDS_ReadBinaryString(fp, fBuffer, 1)) {
2798 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadBinaryRows)");
2799 return 0;
2800 }
2801 }
2802 } else {
2803 size = SDDS_type_size[type - 1];
2804 if (!SDDS_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
2805 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadBinaryRow)");
2806 return (0);
2807 }
2808 }
2809 }
2810 }
2811#if defined(zLib)
2812 }
2813#endif
2814 return (1);
2815}

◆ 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 2616 of file SDDS_binary.c.

2616 {
2617 int32_t length;
2618 char *string;
2619
2620 if (!SDDS_BufferedRead(&length, sizeof(length), fp, fBuffer, SDDS_LONG, 0) || length < 0)
2621 return (0);
2622 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
2623 return (NULL);
2624 if (length && !SDDS_BufferedRead(skip ? NULL : string, sizeof(*string) * length, fp, fBuffer, SDDS_STRING, 0))
2625 return (NULL);
2626 string[length] = 0;
2627 return (string);
2628}

◆ 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 2646 of file SDDS_binary.c.

2646 {
2647 int32_t length;
2648 char *string;
2649
2650 if (!SDDS_LZMABufferedRead(&length, sizeof(length), lzmafp, fBuffer, SDDS_LONG, 0) || length < 0)
2651 return (0);
2652 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
2653 return (NULL);
2654 if (length && !SDDS_LZMABufferedRead(skip ? NULL : string, sizeof(*string) * length, lzmafp, fBuffer, SDDS_STRING, 0))
2655 return (NULL);
2656 string[length] = 0;
2657 return (string);
2658}

◆ 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 2837 of file SDDS_binary.c.

2837 {
2838 int64_t row, offset, newRows = 0;
2839 int32_t rowsPresent32;
2840 int64_t rowsPresent;
2841
2842#if SDDS_MPI_IO
2843 if (SDDS_dataset->parallel_io) {
2844 SDDS_SetError("Error: MPI mode not supported yet in SDDS_ReadNewBinaryRows");
2845 return -1;
2846 }
2847#endif
2848 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
2849 SDDS_SetError("Error: ASCII files not supported in SDDS_ReadNewBinaryRows");
2850 return -1;
2851 }
2852 if (SDDS_dataset->layout.data_mode.column_major) {
2853 SDDS_SetError("Error: column-major order binary files not supported in SDDS_ReadNewBinaryRows");
2854 return -1;
2855 }
2856 if (SDDS_dataset->swapByteOrder) {
2857 SDDS_SetError("Error: Non-native endian not supported yet in SDDS_ReadNewBinaryRows");
2858 return -1;
2859 }
2860#if defined(zLib)
2861 if (SDDS_dataset->layout.gzipFile) {
2862 SDDS_SetError("Error: gzip compressed files not supported yet in SDDS_ReadNewBinaryRows");
2863 return -1;
2864 } else {
2865#endif
2866 if (SDDS_dataset->layout.lzmaFile) {
2867 SDDS_SetError("Error: lzma compressed files not supported yet in SDDS_ReadNewBinaryRows");
2868 return -1;
2869 }
2870#if defined(zLib)
2871 }
2872#endif
2873
2874 // Read how many rows we have now
2875 offset = ftell(SDDS_dataset->layout.fp);
2876 fseek(SDDS_dataset->layout.fp, SDDS_dataset->rowcount_offset, 0);
2877 if (SDDS_dataset->layout.data_mode.mode == SDDS_BINARY) {
2878 if (fread(&rowsPresent32, sizeof(rowsPresent32), 1, SDDS_dataset->layout.fp) == 0) {
2879 SDDS_SetError("Error: row count not present or not correct length");
2880 return -1;
2881 }
2882 if (SDDS_dataset->swapByteOrder) {
2883 SDDS_SwapLong(&rowsPresent32);
2884 }
2885 if (rowsPresent32 == INT32_MIN) {
2886 if (fread(&rowsPresent, sizeof(rowsPresent), 1, SDDS_dataset->layout.fp) == 0) {
2887 SDDS_SetError("Error: row count not present or not correct length");
2888 return -1;
2889 }
2890 if (SDDS_dataset->swapByteOrder) {
2891 SDDS_SwapLong64(&rowsPresent);
2892 }
2893 } else {
2894 rowsPresent = rowsPresent32;
2895 }
2896 } else {
2897 char buffer[30];
2898 if (!fgets(buffer, 30, SDDS_dataset->layout.fp) || strlen(buffer) != 21 || sscanf(buffer, "%" SCNd64, &rowsPresent) != 1) {
2899 SDDS_SetError("Error: row count not present or not correct length");
2900 return -1;
2901 }
2902 }
2903 fseek(SDDS_dataset->layout.fp, offset, 0);
2904
2905 // If the row count listed in the file is greather than the allocated rows, then lengthen the table in memory
2906 if (rowsPresent > SDDS_dataset->n_rows_allocated) {
2907 if (!SDDS_LengthenTable(SDDS_dataset, rowsPresent + 3)) {
2908 return -1;
2909 }
2910 }
2911
2912 for (row = SDDS_dataset->n_rows; row < rowsPresent; row++) {
2913 if (!SDDS_ReadBinaryRow(SDDS_dataset, row, 0)) {
2914 if (SDDS_dataset->autoRecover) {
2915 row--;
2916 SDDS_dataset->autoRecovered = 1;
2918 break;
2919 }
2920 SDDS_SetError("Unable to read page--error reading data row");
2921 return -1;
2922 }
2923 }
2924 newRows = row + 1 - SDDS_dataset->n_rows;
2925 SDDS_dataset->n_rows = row + 1;
2926 return newRows;
2927}
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 4582 of file SDDS_binary.c.

4582 {
4583 int32_t i, j;
4584 SDDS_LAYOUT *layout;
4585 /* char *predefined_format; */
4586 /* static char buffer[SDDS_MAXLINE]; */
4587#if defined(zLib)
4588 gzFile gzfp = NULL;
4589#endif
4590 FILE *fp = NULL;
4591 struct lzmafile *lzmafp = NULL;
4592 SDDS_ARRAY *array;
4593 SDDS_FILEBUFFER *fBuffer;
4594
4595 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryArrays"))
4596 return (0);
4597 layout = &SDDS_dataset->layout;
4598 if (!layout->n_arrays)
4599 return (1);
4600#if defined(zLib)
4601 if (SDDS_dataset->layout.gzipFile) {
4602 gzfp = layout->gzfp;
4603 } else {
4604#endif
4605 if (SDDS_dataset->layout.lzmaFile) {
4606 lzmafp = layout->lzmafp;
4607 } else {
4608 fp = layout->fp;
4609 }
4610#if defined(zLib)
4611 }
4612#endif
4613 fBuffer = &SDDS_dataset->fBuffer;
4614 if (!SDDS_dataset->array) {
4615 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_ReadNonNativeBinaryArrays)");
4616 return (0);
4617 }
4618 for (i = 0; i < layout->n_arrays; i++) {
4619 array = SDDS_dataset->array + i;
4620 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
4621 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_ReadNonNativeBinaryArrays)");
4622 return (0);
4623 }
4624 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
4625 SDDS_SetError("Unable to read array--definition copy failed (SDDS_ReadNonNativeBinaryArrays)");
4626 return (0);
4627 }
4628 /*if (array->dimension) free(array->dimension); */
4629 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
4630 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadNonNativeBinaryArrays)");
4631 return (0);
4632 }
4633#if defined(zLib)
4634 if (SDDS_dataset->layout.gzipFile) {
4635 if (!SDDS_GZipBufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, gzfp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4636 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4637 return (0);
4638 }
4639 } else {
4640#endif
4641 if (SDDS_dataset->layout.lzmaFile) {
4642 if (!SDDS_LZMABufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, lzmafp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4643 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4644 return (0);
4645 }
4646 } else {
4647 if (!SDDS_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, fp, fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4648 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_ReadNonNativeBinaryArrays)");
4649 return (0);
4650 }
4651 }
4652#if defined(zLib)
4653 }
4654#endif
4655 array->elements = 1;
4656 for (j = 0; j < array->definition->dimensions; j++) {
4657 SDDS_SwapLong(&(array->dimension[j]));
4658 array->elements *= array->dimension[j];
4659 }
4660 if (array->data)
4661 free(array->data);
4662 array->data = array->pointer = NULL;
4663 if (array->elements == 0)
4664 continue;
4665 if (array->elements < 0) {
4666 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_ReadNonNativeBinaryArrays)");
4667 return (0);
4668 }
4669 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
4670 SDDS_SetError("Unable to read array--allocation failure (SDDS_ReadNonNativeBinaryArrays)");
4671 return (0);
4672 }
4673 if (array->definition->type == SDDS_STRING) {
4674#if defined(zLib)
4675 if (SDDS_dataset->layout.gzipFile) {
4676 for (j = 0; j < array->elements; j++) {
4677 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4678 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4679 return (0);
4680 }
4681 }
4682 } else {
4683#endif
4684 if (SDDS_dataset->layout.lzmaFile) {
4685 for (j = 0; j < array->elements; j++) {
4686 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4687 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4688 return (0);
4689 }
4690 }
4691 } else {
4692 for (j = 0; j < array->elements; j++) {
4693 if (!(((char **)(array->data))[j] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4694 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_ReadNonNativeBinaryArrays)");
4695 return (0);
4696 }
4697 }
4698 }
4699#if defined(zLib)
4700 }
4701#endif
4702 } else {
4703#if defined(zLib)
4704 if (SDDS_dataset->layout.gzipFile) {
4705 if (!SDDS_GZipBufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, gzfp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4706 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4707 return (0);
4708 }
4709 } else {
4710#endif
4711 if (SDDS_dataset->layout.lzmaFile) {
4712 if (!SDDS_LZMABufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, lzmafp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4713 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4714 return (0);
4715 }
4716 } else {
4717 if (!SDDS_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, fp, fBuffer, array->definition->type, SDDS_dataset->layout.byteOrderDeclared)) {
4718 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_ReadNonNativeBinaryArrays)");
4719 return (0);
4720 }
4721 }
4722#if defined(zLib)
4723 }
4724#endif
4725 }
4726 }
4727 SDDS_SwapEndsArrayData(SDDS_dataset);
4728 return (1);
4729}
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 3465 of file SDDS_binary.c.

3465 {
3466 int64_t i, row;
3467 SDDS_LAYOUT *layout;
3468 /* char *predefined_format; */
3469 /* static char buffer[SDDS_MAXLINE]; */
3470#if defined(zLib)
3471 gzFile gzfp = NULL;
3472#endif
3473 FILE *fp = NULL;
3474 struct lzmafile *lzmafp = NULL;
3475 SDDS_FILEBUFFER *fBuffer;
3476
3477 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryColumns"))
3478 return (0);
3479 layout = &SDDS_dataset->layout;
3480 if (!layout->n_columns || !SDDS_dataset->n_rows)
3481 return (1);
3482#if defined(zLib)
3483 if (SDDS_dataset->layout.gzipFile) {
3484 gzfp = layout->gzfp;
3485 } else {
3486#endif
3487 if (SDDS_dataset->layout.lzmaFile) {
3488 lzmafp = layout->lzmafp;
3489 } else {
3490 fp = layout->fp;
3491 }
3492#if defined(zLib)
3493 }
3494#endif
3495 fBuffer = &SDDS_dataset->fBuffer;
3496
3497 for (i = 0; i < layout->n_columns; i++) {
3498 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
3499 continue;
3500 if (layout->column_definition[i].type == SDDS_STRING) {
3501#if defined(zLib)
3502 if (SDDS_dataset->layout.gzipFile) {
3503 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3504 if (((char ***)SDDS_dataset->data)[i][row])
3505 free((((char ***)SDDS_dataset->data)[i][row]));
3506 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
3507 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumns)");
3508 return (0);
3509 }
3510 }
3511 } else {
3512#endif
3513 if (SDDS_dataset->layout.lzmaFile) {
3514 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3515 if (((char ***)SDDS_dataset->data)[i][row])
3516 free((((char ***)SDDS_dataset->data)[i][row]));
3517 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
3518 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumms)");
3519 return (0);
3520 }
3521 }
3522 } else {
3523 for (row = 0; row < SDDS_dataset->n_rows; row++) {
3524 if (((char ***)SDDS_dataset->data)[i][row])
3525 free((((char ***)SDDS_dataset->data)[i][row]));
3526 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
3527 SDDS_SetError("Unable to read columns--failure reading string (SDDS_ReadNonNativeBinaryColumms)");
3528 return (0);
3529 }
3530 }
3531 }
3532#if defined(zLib)
3533 }
3534#endif
3535 } else {
3536#if defined(zLib)
3537 if (SDDS_dataset->layout.gzipFile) {
3538 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)) {
3539 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3540 return (0);
3541 }
3542 } else {
3543#endif
3544 if (SDDS_dataset->layout.lzmaFile) {
3545 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)) {
3546 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3547 return (0);
3548 }
3549 } else {
3550 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)) {
3551 SDDS_SetError("Unable to read columns--failure reading values (SDDS_ReadNonNativeBinaryColumns)");
3552 return (0);
3553 }
3554 }
3555#if defined(zLib)
3556 }
3557#endif
3558 }
3559 }
3560 return (1);
3561}

◆ 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 4187 of file SDDS_binary.c.

4187 {
4188 return SDDS_ReadNonNativeBinaryPageDetailed(SDDS_dataset, sparse_interval, sparse_offset, 0);
4189}
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 4236 of file SDDS_binary.c.

4236 {
4237 int32_t n_rows32 = 0;
4238 int64_t n_rows, j, k, alloc_rows, rows_to_store, mod;
4239 /* int32_t page_number, i; */
4240#if defined(zLib)
4241 gzFile gzfp = NULL;
4242#endif
4243 FILE *fp = NULL;
4244 struct lzmafile *lzmafp = NULL;
4245 SDDS_FILEBUFFER *fBuffer;
4246
4247 /* static char s[SDDS_MAXLINE]; */
4248 n_rows = 0;
4249 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
4250#if defined(zLib)
4251 if (SDDS_dataset->layout.gzipFile) {
4252 gzfp = SDDS_dataset->layout.gzfp;
4253 } else {
4254#endif
4255 if (SDDS_dataset->layout.lzmaFile) {
4256 lzmafp = SDDS_dataset->layout.lzmafp;
4257 } else {
4258 fp = SDDS_dataset->layout.fp;
4259 }
4260#if defined(zLib)
4261 }
4262#endif
4263 fBuffer = &SDDS_dataset->fBuffer;
4264 if (!fBuffer->buffer) {
4265 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * defaultIOBufferSize))) {
4266 SDDS_SetError("Unable to do buffered read--allocation failure");
4267 return 0;
4268 }
4269 fBuffer->bufferSize = defaultIOBufferSize;
4270 fBuffer->bytesLeft = 0;
4271 }
4272 SDDS_dataset->rowcount_offset = -1;
4273#if defined(zLib)
4274 if (SDDS_dataset->layout.gzipFile) {
4275 if (!SDDS_GZipBufferedRead(&n_rows32, sizeof(n_rows32), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4276 if (gzeof(gzfp))
4277 return (SDDS_dataset->page_number = -1);
4278 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4279 return (0);
4280 }
4281 SDDS_SwapLong(&n_rows32);
4282 if (n_rows32 == INT32_MIN) {
4283 if (!SDDS_GZipBufferedRead(&n_rows, sizeof(n_rows), gzfp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4284 if (gzeof(gzfp))
4285 return (SDDS_dataset->page_number = -1);
4286 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4287 return (0);
4288 }
4289 SDDS_SwapLong64(&n_rows);
4290 } else {
4291 n_rows = n_rows32;
4292 }
4293 } else {
4294#endif
4295 /* This value will only be valid if read buffering is turned off, which is done for
4296 * certain append operations! Should really modify SDDS_BufferedRead and SDDS_BufferedWrite
4297 * to provide ftell capability.
4298 */
4299 if (SDDS_dataset->layout.lzmaFile) {
4300 if (!SDDS_LZMABufferedRead(&n_rows32, sizeof(n_rows32), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4301 if (lzma_eof(lzmafp))
4302 return (SDDS_dataset->page_number = -1);
4303 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4304 return (0);
4305 }
4306 SDDS_SwapLong(&n_rows32);
4307 if (n_rows32 == INT32_MIN) {
4308 if (!SDDS_LZMABufferedRead(&n_rows, sizeof(n_rows), lzmafp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4309 if (lzma_eof(lzmafp))
4310 return (SDDS_dataset->page_number = -1);
4311 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4312 return (0);
4313 }
4314 SDDS_SwapLong64(&n_rows);
4315 } else {
4316 n_rows = n_rows32;
4317 }
4318 } else {
4319 SDDS_dataset->rowcount_offset = ftell(fp);
4320 if (!SDDS_BufferedRead(&n_rows32, sizeof(n_rows32), fp, &SDDS_dataset->fBuffer, SDDS_LONG, SDDS_dataset->layout.byteOrderDeclared)) {
4321 if (feof(fp))
4322 return (SDDS_dataset->page_number = -1);
4323 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4324 return (0);
4325 }
4326 SDDS_SwapLong(&n_rows32);
4327 if (n_rows32 == INT32_MIN) {
4328 if (!SDDS_BufferedRead(&n_rows, sizeof(n_rows), fp, &SDDS_dataset->fBuffer, SDDS_LONG64, SDDS_dataset->layout.byteOrderDeclared)) {
4329 if (feof(fp))
4330 return (SDDS_dataset->page_number = -1);
4331 SDDS_SetError("Unable to read page--failure reading number of rows (SDDS_ReadNonNativeBinaryPage)");
4332 return (0);
4333 }
4334 SDDS_SwapLong64(&n_rows);
4335 } else {
4336 n_rows = n_rows32;
4337 }
4338 }
4339#if defined(zLib)
4340 }
4341#endif
4342 if (n_rows < 0) {
4343 SDDS_SetError("Unable to read page--negative number of rows (SDDS_ReadNonNativeBinaryPage)");
4344 return (0);
4345 }
4346 if (last_rows < 0)
4347 last_rows = 0;
4348 /* Fix this limitation later */
4349 if (SDDS_dataset->layout.data_mode.column_major) {
4350 sparse_interval = 1;
4351 sparse_offset = 0;
4352 last_rows = 0;
4353 }
4354 if (last_rows) {
4355 sparse_interval = 1;
4356 sparse_offset = n_rows - last_rows;
4357 rows_to_store = last_rows + 2;
4358 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
4359 }
4360 if (sparse_interval <= 0)
4361 sparse_interval = 1;
4362 if (sparse_offset < 0)
4363 sparse_offset = 0;
4364
4365 rows_to_store = (n_rows - sparse_offset) / sparse_interval + 2;
4366 alloc_rows = rows_to_store - SDDS_dataset->n_rows_allocated;
4367 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, alloc_rows)) {
4368 SDDS_SetError("Unable to read page--couldn't start page (SDDS_ReadNonNativeBinaryPage)");
4369 return (0);
4370 }
4371
4372 /* read the parameter values */
4373 if (!SDDS_ReadNonNativeBinaryParameters(SDDS_dataset)) {
4374 SDDS_SetError("Unable to read page--parameter reading error (SDDS_ReadNonNativeBinaryPage)");
4375 return (0);
4376 }
4377
4378 /* read the array values */
4379 if (!SDDS_ReadNonNativeBinaryArrays(SDDS_dataset)) {
4380 SDDS_SetError("Unable to read page--array reading error (SDDS_ReadNonNativeBinaryPage)");
4381 return (0);
4382 }
4383 if (SDDS_dataset->layout.data_mode.column_major) {
4384 SDDS_dataset->n_rows = n_rows;
4385 if (!SDDS_ReadNonNativeBinaryColumns(SDDS_dataset)) {
4386 SDDS_SetError("Unable to read page--column reading error (SDDS_ReadNonNativeBinaryPage)");
4387 return (0);
4388 }
4389 SDDS_SwapEndsColumnData(SDDS_dataset);
4390 return (SDDS_dataset->page_number);
4391 }
4392 if ((sparse_interval <= 1) && (sparse_offset == 0)) {
4393 for (j = 0; j < n_rows; j++) {
4394 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, j, 0)) {
4395 SDDS_dataset->n_rows = j - 1;
4396 if (SDDS_dataset->autoRecover) {
4398 SDDS_SwapEndsColumnData(SDDS_dataset);
4399 return (SDDS_dataset->page_number);
4400 }
4401 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4402 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4403 return (0);
4404 }
4405 }
4406 SDDS_dataset->n_rows = j;
4407 SDDS_SwapEndsColumnData(SDDS_dataset);
4408 return (SDDS_dataset->page_number);
4409 } else {
4410 for (j = 0; j < sparse_offset; j++) {
4411 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, 0, 1)) {
4412 SDDS_dataset->n_rows = 0;
4413 if (SDDS_dataset->autoRecover) {
4415 SDDS_SwapEndsColumnData(SDDS_dataset);
4416 return (SDDS_dataset->page_number);
4417 }
4418 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4419 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4420 return (0);
4421 }
4422 }
4423 n_rows -= sparse_offset;
4424 for (j = k = 0; j < n_rows; j++) {
4425 if (!SDDS_ReadNonNativeBinaryRow(SDDS_dataset, k, mod = j % sparse_interval)) {
4426 SDDS_dataset->n_rows = k - 1;
4427 if (SDDS_dataset->autoRecover) {
4429 SDDS_SwapEndsColumnData(SDDS_dataset);
4430 return (SDDS_dataset->page_number);
4431 }
4432 SDDS_SetError("Unable to read page--error reading data row (SDDS_ReadNonNativeBinaryPage)");
4433 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
4434 return (0);
4435 }
4436 k += mod ? 0 : 1;
4437 }
4438 SDDS_dataset->n_rows = k;
4439 SDDS_SwapEndsColumnData(SDDS_dataset);
4440 return (SDDS_dataset->page_number);
4441 }
4442}
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 4209 of file SDDS_binary.c.

4209 {
4210 return SDDS_ReadNonNativeBinaryPageDetailed(SDDS_dataset, 1, 0, last_rows);
4211}

◆ 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 4466 of file SDDS_binary.c.

4466 {
4467 int32_t i;
4468 SDDS_LAYOUT *layout;
4469 /* char *predefined_format; */
4470 char buffer[SDDS_MAXLINE];
4471#if defined(zLib)
4472 gzFile gzfp = NULL;
4473#endif
4474 FILE *fp = NULL;
4475 struct lzmafile *lzmafp = NULL;
4476 SDDS_FILEBUFFER *fBuffer;
4477
4478 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryParameters"))
4479 return (0);
4480 layout = &SDDS_dataset->layout;
4481 if (!layout->n_parameters)
4482 return (1);
4483#if defined(zLib)
4484 if (SDDS_dataset->layout.gzipFile) {
4485 gzfp = layout->gzfp;
4486 } else {
4487#endif
4488 if (SDDS_dataset->layout.lzmaFile) {
4489 lzmafp = layout->lzmafp;
4490 } else {
4491 fp = layout->fp;
4492 }
4493#if defined(zLib)
4494 }
4495#endif
4496 fBuffer = &SDDS_dataset->fBuffer;
4497 for (i = 0; i < layout->n_parameters; i++) {
4498 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4499 continue;
4500 if (layout->parameter_definition[i].fixed_value) {
4501 strcpy(buffer, layout->parameter_definition[i].fixed_value);
4502 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
4503 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_ReadNonNativeBinaryParameters)");
4504 return (0);
4505 }
4506 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
4507 if (*(char **)SDDS_dataset->parameter[i])
4508 free(*(char **)SDDS_dataset->parameter[i]);
4509#if defined(zLib)
4510 if (SDDS_dataset->layout.gzipFile) {
4511 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4512 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4513 return (0);
4514 }
4515 } else {
4516#endif
4517 if (SDDS_dataset->layout.lzmaFile) {
4518 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4519 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4520 return (0);
4521 }
4522 } else {
4523 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4524 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_ReadNonNativeBinaryParameters)");
4525 return (0);
4526 }
4527 }
4528#if defined(zLib)
4529 }
4530#endif
4531 } else {
4532#if defined(zLib)
4533 if (SDDS_dataset->layout.gzipFile) {
4534 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)) {
4535 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4536 return (0);
4537 }
4538 } else {
4539#endif
4540 if (SDDS_dataset->layout.lzmaFile) {
4541 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)) {
4542 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4543 return (0);
4544 }
4545 } else {
4546 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)) {
4547 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_ReadNonNativeBinaryParameters)");
4548 return (0);
4549 }
4550 }
4551#if defined(zLib)
4552 }
4553#endif
4554 }
4555 }
4556 SDDS_SwapEndsParameterData(SDDS_dataset);
4557 return (1);
4558}
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 4752 of file SDDS_binary.c.

4752 {
4753 int64_t i, type, size;
4754 SDDS_LAYOUT *layout;
4755#if defined(zLib)
4756 gzFile gzfp;
4757#endif
4758 FILE *fp;
4759 struct lzmafile *lzmafp;
4760 SDDS_FILEBUFFER *fBuffer;
4761
4762 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativeBinaryRow"))
4763 return (0);
4764 layout = &SDDS_dataset->layout;
4765 fBuffer = &SDDS_dataset->fBuffer;
4766
4767#if defined(zLib)
4768 if (SDDS_dataset->layout.gzipFile) {
4769 gzfp = layout->gzfp;
4770 for (i = 0; i < layout->n_columns; i++) {
4771 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4772 continue;
4773 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4774 if (!skip) {
4775 if (((char ***)SDDS_dataset->data)[i][row])
4776 free((((char ***)SDDS_dataset->data)[i][row]));
4777 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 0))) {
4778 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4779 return (0);
4780 }
4781 } else {
4782 if (!SDDS_ReadNonNativeGZipBinaryString(gzfp, fBuffer, 1)) {
4783 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4784 return 0;
4785 }
4786 }
4787 } else {
4788 size = SDDS_type_size[type - 1];
4789 if (!SDDS_GZipBufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4790 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4791 return (0);
4792 }
4793 }
4794 }
4795 } else {
4796#endif
4797 if (SDDS_dataset->layout.lzmaFile) {
4798 lzmafp = layout->lzmafp;
4799 for (i = 0; i < layout->n_columns; i++) {
4800 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4801 continue;
4802 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4803 if (!skip) {
4804 if (((char ***)SDDS_dataset->data)[i][row])
4805 free((((char ***)SDDS_dataset->data)[i][row]));
4806 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 0))) {
4807 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4808 return (0);
4809 }
4810 } else {
4811 if (!SDDS_ReadNonNativeLZMABinaryString(lzmafp, fBuffer, 1)) {
4812 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4813 return 0;
4814 }
4815 }
4816 } else {
4817 size = SDDS_type_size[type - 1];
4818 if (!SDDS_LZMABufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4819 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4820 return (0);
4821 }
4822 }
4823 }
4824 } else {
4825 fp = layout->fp;
4826 for (i = 0; i < layout->n_columns; i++) {
4827 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
4828 continue;
4829 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
4830 if (!skip) {
4831 if (((char ***)SDDS_dataset->data)[i][row])
4832 free((((char ***)SDDS_dataset->data)[i][row]));
4833 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_ReadNonNativeBinaryString(fp, fBuffer, 0))) {
4834 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4835 return (0);
4836 }
4837 } else {
4838 if (!SDDS_ReadNonNativeBinaryString(fp, fBuffer, 1)) {
4839 SDDS_SetError("Unable to read rows--failure reading string (SDDS_ReadNonNativeBinaryRow)");
4840 return 0;
4841 }
4842 }
4843 } else {
4844 size = SDDS_type_size[type - 1];
4845 if (!SDDS_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer, type, SDDS_dataset->layout.byteOrderDeclared)) {
4846 SDDS_SetError("Unable to read row--failure reading value (SDDS_ReadNonNativeBinaryRow)");
4847 return (0);
4848 }
4849 }
4850 }
4851 }
4852#if defined(zLib)
4853 }
4854#endif
4855 return (1);
4856}

◆ 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 4875 of file SDDS_binary.c.

4875 {
4876 int32_t length;
4877 char *string;
4878
4879 if (!SDDS_BufferedRead(&length, sizeof(length), fp, fBuffer, SDDS_LONG, 0))
4880 return (0);
4881 SDDS_SwapLong(&length);
4882 if (length < 0)
4883 return (0);
4884 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
4885 return (NULL);
4886 if (length && !SDDS_BufferedRead(skip ? NULL : string, sizeof(*string) * length, fp, fBuffer, SDDS_STRING, 0))
4887 return (NULL);
4888 string[length] = 0;
4889 return (string);
4890}

◆ 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 4909 of file SDDS_binary.c.

4909 {
4910 int32_t length;
4911 char *string;
4912
4913 if (!SDDS_LZMABufferedRead(&length, sizeof(length), lzmafp, fBuffer, SDDS_LONG, 0))
4914 return (0);
4915 SDDS_SwapLong(&length);
4916 if (length < 0)
4917 return (0);
4918 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
4919 return (NULL);
4920 if (length && !SDDS_LZMABufferedRead(skip ? NULL : string, sizeof(*string) * length, lzmafp, fBuffer, SDDS_STRING, 0))
4921 return (NULL);
4922 string[length] = 0;
4923 return (string);
4924}

◆ 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 4008 of file SDDS_binary.c.

4008 {
4009 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, 0, 1, 0, 0);
4010}

◆ 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 4057 of file SDDS_binary.c.

4059{
4060 int32_t retval;
4061 /* SDDS_LAYOUT layout_copy; */
4062
4063 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativePageDetailed"))
4064 return (0);
4065 if (SDDS_dataset->layout.disconnected) {
4066 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadNonNativePageDetailed)");
4067 return 0;
4068 }
4069#if defined(zLib)
4070 if (SDDS_dataset->layout.gzipFile) {
4071 if (!SDDS_dataset->layout.gzfp) {
4072 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4073 return (0);
4074 }
4075 } else {
4076#endif
4077 if (SDDS_dataset->layout.lzmaFile) {
4078 if (!SDDS_dataset->layout.lzmafp) {
4079 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4080 return (0);
4081 }
4082 } else {
4083 if (!SDDS_dataset->layout.fp) {
4084 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageDetailed)");
4085 return (0);
4086 }
4087 }
4088#if defined(zLib)
4089 }
4090#endif
4091 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
4092 if ((retval = SDDS_ReadAsciiPage(SDDS_dataset, sparse_interval, sparse_offset, 0)) < 1) {
4093 return (retval);
4094 }
4095 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
4096 if ((retval = SDDS_ReadNonNativeBinaryPage(SDDS_dataset, sparse_interval, sparse_offset)) < 1) {
4097 return (retval);
4098 }
4099 } else {
4100 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadNonNativePageDetailed)");
4101 return (0);
4102 }
4103 return (retval);
4104}
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 4124 of file SDDS_binary.c.

4124 {
4125 int32_t retval;
4126 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ReadNonNativePageLastRows"))
4127 return (0);
4128 if (SDDS_dataset->layout.disconnected) {
4129 SDDS_SetError("Can't read page--file is disconnected (SDDS_ReadNonNativePageLastRows)");
4130 return 0;
4131 }
4132#if defined(zLib)
4133 if (SDDS_dataset->layout.gzipFile) {
4134 if (!SDDS_dataset->layout.gzfp) {
4135 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4136 return (0);
4137 }
4138 } else {
4139#endif
4140 if (SDDS_dataset->layout.lzmaFile) {
4141 if (!SDDS_dataset->layout.lzmafp) {
4142 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4143 return (0);
4144 }
4145 } else {
4146 if (!SDDS_dataset->layout.fp) {
4147 SDDS_SetError("Unable to read page--NULL file pointer (SDDS_ReadNonNativePageLastRows)");
4148 return (0);
4149 }
4150 }
4151#if defined(zLib)
4152 }
4153#endif
4154 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
4155 if ((retval = SDDS_ReadAsciiPageLastRows(SDDS_dataset, last_rows)) < 1) {
4156 return (retval);
4157 }
4158 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
4159 if ((retval = SDDS_ReadNonNativeBinaryPageLastRows(SDDS_dataset, last_rows)) < 1) {
4160 return (retval);
4161 }
4162 } else {
4163 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_ReadNonNativePageLastRows)");
4164 return (0);
4165 }
4166 return (retval);
4167}
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 4030 of file SDDS_binary.c.

4030 {
4031 return SDDS_ReadNonNativePageDetailed(SDDS_dataset, mode, sparse_interval, sparse_offset, 0);
4032}

◆ 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 2054 of file SDDS_binary.c.

2054 {
2055 int32_t returnValue;
2056
2057 returnValue = SDDS_dataset->readRecoveryPossible;
2058 SDDS_dataset->readRecoveryPossible = 0;
2059 return returnValue;
2060}

◆ SDDS_SetBufferedRead()

int32_t SDDS_SetBufferedRead ( int32_t dummy)

Definition at line 49 of file SDDS_binary.c.

49 {
50 return 0;
51}

◆ 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 66 of file SDDS_binary.c.

66 {
67 int32_t previous;
68 if (newValue < 0)
69 return defaultIOBufferSize;
70 if (newValue < 128) /* arbitrary limit */
71 newValue = 0;
72 previous = defaultIOBufferSize;
73 defaultIOBufferSize = newValue;
74 return previous;
75}

◆ 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 2082 of file SDDS_binary.c.

2082 {
2083 SDDS_dataset->readRecoveryPossible = mode;
2084}

◆ 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 3958 of file SDDS_binary.c.

3958 {
3959 double copy;
3960 short i, j;
3961 copy = *data;
3962 for (i = 0, j = 7; i < 8; i++, j--)
3963 *(((char *)data) + i) = *(((char *)&copy) + j);
3964}

◆ 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 3747 of file SDDS_binary.c.

3747 {
3748 int32_t i, j;
3749 SDDS_LAYOUT *layout;
3750 short *sData;
3751 unsigned short *suData;
3752 int32_t *lData;
3753 uint32_t *luData;
3754 int64_t *lData64;
3755 uint64_t *luData64;
3756 float *fData;
3757 double *dData;
3758 long double *ldData;
3759
3760 layout = &SDDSin->layout;
3761
3762 for (i = 0; i < layout->n_arrays; i++) {
3763 switch (layout->array_definition[i].type) {
3764 case SDDS_SHORT:
3765 sData = SDDSin->array[i].data;
3766 for (j = 0; j < SDDSin->array[i].elements; j++)
3767 SDDS_SwapShort(sData + j);
3768 break;
3769 case SDDS_USHORT:
3770 suData = SDDSin->array[i].data;
3771 for (j = 0; j < SDDSin->array[i].elements; j++)
3772 SDDS_SwapUShort(suData + j);
3773 break;
3774 case SDDS_LONG:
3775 lData = SDDSin->array[i].data;
3776 for (j = 0; j < SDDSin->array[i].elements; j++)
3777 SDDS_SwapLong(lData + j);
3778 break;
3779 case SDDS_ULONG:
3780 luData = SDDSin->array[i].data;
3781 for (j = 0; j < SDDSin->array[i].elements; j++)
3782 SDDS_SwapULong(luData + j);
3783 break;
3784 case SDDS_LONG64:
3785 lData64 = SDDSin->array[i].data;
3786 for (j = 0; j < SDDSin->array[i].elements; j++)
3787 SDDS_SwapLong64(lData64 + j);
3788 break;
3789 case SDDS_ULONG64:
3790 luData64 = SDDSin->array[i].data;
3791 for (j = 0; j < SDDSin->array[i].elements; j++)
3792 SDDS_SwapULong64(luData64 + j);
3793 break;
3794 case SDDS_LONGDOUBLE:
3795 ldData = SDDSin->array[i].data;
3796 for (j = 0; j < SDDSin->array[i].elements; j++)
3797 SDDS_SwapLongDouble(ldData + j);
3798 break;
3799 case SDDS_DOUBLE:
3800 dData = SDDSin->array[i].data;
3801 for (j = 0; j < SDDSin->array[i].elements; j++)
3802 SDDS_SwapDouble(dData + j);
3803 break;
3804 case SDDS_FLOAT:
3805 fData = SDDSin->array[i].data;
3806 for (j = 0; j < SDDSin->array[i].elements; j++)
3807 SDDS_SwapFloat(fData + j);
3808 break;
3809 default:
3810 break;
3811 }
3812 }
3813 return (1);
3814}
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 3582 of file SDDS_binary.c.

3582 {
3583 int32_t i, row;
3584 SDDS_LAYOUT *layout;
3585 short *sData;
3586 unsigned short *suData;
3587 int32_t *lData;
3588 uint32_t *luData;
3589 int64_t *lData64;
3590 uint64_t *luData64;
3591 float *fData;
3592 double *dData;
3593 long double *ldData;
3594
3595 layout = &SDDSin->layout;
3596 for (i = 0; i < layout->n_columns; i++) {
3597 switch (layout->column_definition[i].type) {
3598 case SDDS_SHORT:
3599 sData = SDDSin->data[i];
3600 for (row = 0; row < SDDSin->n_rows; row++)
3601 SDDS_SwapShort(sData + row);
3602 break;
3603 case SDDS_USHORT:
3604 suData = SDDSin->data[i];
3605 for (row = 0; row < SDDSin->n_rows; row++)
3606 SDDS_SwapUShort(suData + row);
3607 break;
3608 case SDDS_LONG:
3609 lData = SDDSin->data[i];
3610 for (row = 0; row < SDDSin->n_rows; row++)
3611 SDDS_SwapLong(lData + row);
3612 break;
3613 case SDDS_ULONG:
3614 luData = SDDSin->data[i];
3615 for (row = 0; row < SDDSin->n_rows; row++)
3616 SDDS_SwapULong(luData + row);
3617 break;
3618 case SDDS_LONG64:
3619 lData64 = SDDSin->data[i];
3620 for (row = 0; row < SDDSin->n_rows; row++)
3621 SDDS_SwapLong64(lData64 + row);
3622 break;
3623 case SDDS_ULONG64:
3624 luData64 = SDDSin->data[i];
3625 for (row = 0; row < SDDSin->n_rows; row++)
3626 SDDS_SwapULong64(luData64 + row);
3627 break;
3628 case SDDS_LONGDOUBLE:
3629 ldData = SDDSin->data[i];
3630 for (row = 0; row < SDDSin->n_rows; row++)
3631 SDDS_SwapLongDouble(ldData + row);
3632 break;
3633 case SDDS_DOUBLE:
3634 dData = SDDSin->data[i];
3635 for (row = 0; row < SDDSin->n_rows; row++)
3636 SDDS_SwapDouble(dData + row);
3637 break;
3638 case SDDS_FLOAT:
3639 fData = SDDSin->data[i];
3640 for (row = 0; row < SDDSin->n_rows; row++)
3641 SDDS_SwapFloat(fData + row);
3642 break;
3643 default:
3644 break;
3645 }
3646 }
3647 return (1);
3648}

◆ 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 3668 of file SDDS_binary.c.

3668 {
3669 int32_t i;
3670 SDDS_LAYOUT *layout;
3671 short *sData;
3672 unsigned short *suData;
3673 int32_t *lData;
3674 uint32_t *luData;
3675 int64_t *lData64;
3676 uint64_t *luData64;
3677 float *fData;
3678 double *dData;
3679 long double *ldData;
3680
3681 layout = &SDDSin->layout;
3682 for (i = 0; i < layout->n_parameters; i++) {
3683 if (layout->parameter_definition[i].fixed_value) {
3684 continue;
3685 }
3686 switch (layout->parameter_definition[i].type) {
3687 case SDDS_SHORT:
3688 sData = SDDSin->parameter[i];
3689 SDDS_SwapShort(sData);
3690 break;
3691 case SDDS_USHORT:
3692 suData = SDDSin->parameter[i];
3693 SDDS_SwapUShort(suData);
3694 break;
3695 case SDDS_LONG:
3696 lData = SDDSin->parameter[i];
3697 SDDS_SwapLong(lData);
3698 break;
3699 case SDDS_ULONG:
3700 luData = SDDSin->parameter[i];
3701 SDDS_SwapULong(luData);
3702 break;
3703 case SDDS_LONG64:
3704 lData64 = SDDSin->parameter[i];
3705 SDDS_SwapLong64(lData64);
3706 break;
3707 case SDDS_ULONG64:
3708 luData64 = SDDSin->parameter[i];
3709 SDDS_SwapULong64(luData64);
3710 break;
3711 case SDDS_LONGDOUBLE:
3712 ldData = SDDSin->parameter[i];
3713 SDDS_SwapLongDouble(ldData);
3714 break;
3715 case SDDS_DOUBLE:
3716 dData = SDDSin->parameter[i];
3717 SDDS_SwapDouble(dData);
3718 break;
3719 case SDDS_FLOAT:
3720 fData = SDDSin->parameter[i];
3721 SDDS_SwapFloat(fData);
3722 break;
3723 default:
3724 break;
3725 }
3726 }
3727 return (1);
3728}

◆ 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 3939 of file SDDS_binary.c.

3939 {
3940 float copy;
3941 short i, j;
3942 copy = *data;
3943 for (i = 0, j = 3; i < 4; i++, j--)
3944 *(((char *)data) + i) = *(((char *)&copy) + j);
3945}

◆ 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 3863 of file SDDS_binary.c.

3863 {
3864 int32_t copy;
3865 short i, j;
3866 copy = *data;
3867 for (i = 0, j = 3; i < 4; i++, j--)
3868 *(((char *)data) + i) = *(((char *)&copy) + j);
3869}

◆ 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 3901 of file SDDS_binary.c.

3901 {
3902 int64_t copy;
3903 short i, j;
3904 copy = *data;
3905 for (i = 0, j = 7; i < 8; i++, j--)
3906 *(((char *)data) + i) = *(((char *)&copy) + j);
3907}

◆ 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 3978 of file SDDS_binary.c.

3978 {
3979 long double copy;
3980 short i, j;
3981 copy = *data;
3982 if (LDBL_DIG == 18) {
3983 for (i = 0, j = 11; i < 12; i++, j--)
3984 *(((char *)data) + i) = *(((char *)&copy) + j);
3985 } else {
3986 for (i = 0, j = 7; i < 8; i++, j--)
3987 *(((char *)data) + i) = *(((char *)&copy) + j);
3988 }
3989}

◆ 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 3827 of file SDDS_binary.c.

3827 {
3828 unsigned char c1;
3829 c1 = *((char *)data);
3830 *((char *)data) = *(((char *)data) + 1);
3831 *(((char *)data) + 1) = c1;
3832}

◆ 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 3882 of file SDDS_binary.c.

3882 {
3883 uint32_t copy;
3884 short i, j;
3885 copy = *data;
3886 for (i = 0, j = 3; i < 4; i++, j--)
3887 *(((char *)data) + i) = *(((char *)&copy) + j);
3888}

◆ 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 3920 of file SDDS_binary.c.

3920 {
3921 uint64_t copy;
3922 short i, j;
3923 copy = *data;
3924 for (i = 0, j = 7; i < 8; i++, j--)
3925 *(((char *)data) + i) = *(((char *)&copy) + j);
3926}

◆ 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 3845 of file SDDS_binary.c.

3845 {
3846 unsigned char c1;
3847 c1 = *((char *)data);
3848 *((char *)data) = *(((char *)data) + 1);
3849 *(((char *)data) + 1) = c1;
3850}

◆ 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 1077 of file SDDS_binary.c.

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

5717 {
5718 FILE *fp;
5719 int32_t code, min32 = INT32_MIN, rows32;
5720 int64_t i, rows, offset, fixed_rows;
5721 SDDS_FILEBUFFER *fBuffer;
5722
5723 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_UpdateNonNativeBinaryPage"))
5724 return (0);
5725#if defined(zLib)
5726 if (SDDS_dataset->layout.gzipFile) {
5727 SDDS_SetError("Unable to perform page updates on a gzip file (SDDS_UpdateNonNativeBinaryPage)");
5728 return 0;
5729 }
5730#endif
5731 if (SDDS_dataset->layout.lzmaFile) {
5732 SDDS_SetError("Unable to perform page updates on .lzma or .xz files (SDDS_UpdateNonNativeBinaryPage)");
5733 return 0;
5734 }
5735 if (SDDS_dataset->layout.data_mode.column_major) {
5736 SDDS_SetError("Unable to perform page updates on a column major order file (SDDS_UpdateNonNativeBinaryPage)");
5737 return 0;
5738 }
5739 if (!SDDS_dataset->writing_page) {
5740#ifdef DEBUG
5741 fprintf(stderr, "Page not being written---calling SDDS_UpdateNonNativeBinaryPage\n");
5742#endif
5743 if (!(code = SDDS_WriteNonNativeBinaryPage(SDDS_dataset))) {
5744 return 0;
5745 }
5746 if (mode & FLUSH_TABLE) {
5747 SDDS_FreeTableStrings(SDDS_dataset);
5748 SDDS_dataset->first_row_in_mem = SDDS_CountRowsOfInterest(SDDS_dataset);
5749 SDDS_dataset->last_row_written = -1;
5750 SDDS_dataset->n_rows = 0;
5751 }
5752 return code;
5753 }
5754
5755 if (!(fp = SDDS_dataset->layout.fp)) {
5756 SDDS_SetError("Unable to update page--file pointer is NULL (SDDS_UpdateNonNativeBinaryPage)");
5757 return (0);
5758 }
5759 fBuffer = &SDDS_dataset->fBuffer;
5760 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5761 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateNonNativeBinaryPage)");
5762 return 0;
5763 }
5764 offset = ftell(fp);
5765
5766 rows = SDDS_CountRowsOfInterest(SDDS_dataset) + SDDS_dataset->first_row_in_mem;
5767#ifdef DEBUG
5768 fprintf(stderr, "%" PRId64 " rows stored in table, %" PRId32 " already written\n", rows, SDDS_dataset->n_rows_written);
5769#endif
5770 if (rows == SDDS_dataset->n_rows_written) {
5771 return (1);
5772 }
5773 if (rows < SDDS_dataset->n_rows_written) {
5774 SDDS_SetError("Unable to update page--new number of rows less than previous number (SDDS_UpdateNonNativeBinaryPage)");
5775 return (0);
5776 }
5777 SDDS_SwapLong(&min32);
5778 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))) {
5779 if (SDDS_fseek(fp, SDDS_dataset->rowcount_offset, 0) == -1) {
5780 SDDS_SetError("Unable to update page--failure doing fseek (SDDS_UpdateNonNativeBinaryPage)");
5781 return (0);
5782 }
5783 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5784 if ((rows - SDDS_dataset->n_rows_written) + 1 > SDDS_dataset->layout.data_mode.fixed_row_increment) {
5785 SDDS_dataset->layout.data_mode.fixed_row_increment = (rows - SDDS_dataset->n_rows_written) + 1;
5786 }
5787 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5788#if defined(DEBUG)
5789 fprintf(stderr, "Setting %" PRId64 " fixed rows\n", fixed_rows);
5790#endif
5791 if ((fixed_rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
5792 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateNonNativeBinaryPage)");
5793 return (0);
5794 }
5795 if (fixed_rows > INT32_MAX) {
5796 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
5797 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
5798 return (0);
5799 }
5800 SDDS_SwapLong64(&fixed_rows);
5801 if (fwrite(&fixed_rows, sizeof(fixed_rows), 1, fp) != 1) {
5802 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5803 return (0);
5804 }
5805 SDDS_SwapLong64(&fixed_rows);
5806 } else {
5807 rows32 = (int32_t)fixed_rows;
5808 SDDS_SwapLong(&rows32);
5809 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
5810 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5811 return (0);
5812 }
5813 }
5814 } else {
5815#if defined(DEBUG)
5816 fprintf(stderr, "Setting %" PRId64 " rows\n", rows);
5817#endif
5818 if ((rows > INT32_MAX) && (SDDS_dataset->n_rows_written <= INT32_MAX)) {
5819 SDDS_SetError("Unable to update page--crossed the INT32_MAX row boundary (SDDS_UpdateNonNativeBinaryPage)");
5820 return (0);
5821 }
5822 if (rows > INT32_MAX) {
5823 if (fwrite(&min32, sizeof(min32), 1, fp) != 1) {
5824 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateBinaryPage)");
5825 return (0);
5826 }
5827 SDDS_SwapLong64(&rows);
5828 if (fwrite(&rows, sizeof(rows), 1, fp) != 1) {
5829 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5830 return (0);
5831 }
5832 SDDS_SwapLong64(&rows);
5833 } else {
5834 rows32 = (int32_t)rows;
5835 SDDS_SwapLong(&rows32);
5836 if (fwrite(&rows32, sizeof(rows32), 1, fp) != 1) {
5837 SDDS_SetError("Unable to update page--failure writing number of rows (SDDS_UpdateNonNativeBinaryPage)");
5838 return (0);
5839 }
5840 }
5841 }
5842 if (SDDS_fseek(fp, offset, 0) == -1) {
5843 SDDS_SetError("Unable to update page--failure doing fseek to end of page (SDDS_UpdateNonNativeBinaryPage)");
5844 return (0);
5845 }
5846 }
5847 SDDS_SwapEndsColumnData(SDDS_dataset);
5848 for (i = SDDS_dataset->last_row_written + 1; i < SDDS_dataset->n_rows; i++) {
5849 if (SDDS_dataset->row_flag[i] && !SDDS_WriteNonNativeBinaryRow(SDDS_dataset, i)) {
5850 SDDS_SetError("Unable to update page--failure writing row (SDDS_UpdateNonNativeBinaryPage)");
5851 return (0);
5852 }
5853 }
5854 SDDS_SwapEndsColumnData(SDDS_dataset);
5855#ifdef DEBUG
5856 fprintf(stderr, "Flushing buffer\n");
5857#endif
5858 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5859 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_UpdateNonNativeBinaryPage)");
5860 return 0;
5861 }
5862 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
5863 SDDS_dataset->n_rows_written = rows;
5864 if (mode & FLUSH_TABLE) {
5865 SDDS_FreeTableStrings(SDDS_dataset);
5866 SDDS_dataset->first_row_in_mem = rows;
5867 SDDS_dataset->last_row_written = -1;
5868 SDDS_dataset->n_rows = 0;
5869 }
5870 return (1);
5871}
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 1533 of file SDDS_binary.c.

1533 {
1534 int32_t i, j, zero = 0;
1535 SDDS_LAYOUT *layout;
1536#if defined(zLib)
1537 gzFile gzfp;
1538#endif
1539 FILE *fp;
1540 struct lzmafile *lzmafp;
1541 SDDS_FILEBUFFER *fBuffer;
1542
1543 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryArrays"))
1544 return (0);
1545 layout = &SDDS_dataset->layout;
1546#if defined(zLib)
1547 if (SDDS_dataset->layout.gzipFile) {
1548 gzfp = layout->gzfp;
1549 fBuffer = &SDDS_dataset->fBuffer;
1550 for (i = 0; i < layout->n_arrays; i++) {
1551 if (!SDDS_dataset->array[i].dimension) {
1552 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1553 if (!SDDS_GZipBufferedWrite(&zero, sizeof(zero), gzfp, fBuffer)) {
1554 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1555 return 0;
1556 }
1557 continue;
1558 }
1559 if (!SDDS_GZipBufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, gzfp, fBuffer)) {
1560 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1561 return (0);
1562 }
1563 if (layout->array_definition[i].type == SDDS_STRING) {
1564 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1565 if (!SDDS_GZipWriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], gzfp, fBuffer)) {
1566 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1567 return (0);
1568 }
1569 }
1570 } 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)) {
1571 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1572 return (0);
1573 }
1574 }
1575 } else {
1576#endif
1577 if (SDDS_dataset->layout.gzipFile) {
1578 lzmafp = layout->lzmafp;
1579 fBuffer = &SDDS_dataset->fBuffer;
1580 for (i = 0; i < layout->n_arrays; i++) {
1581 if (!SDDS_dataset->array[i].dimension) {
1582 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1583 if (!SDDS_LZMABufferedWrite(&zero, sizeof(zero), lzmafp, fBuffer)) {
1584 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1585 return 0;
1586 }
1587 continue;
1588 }
1589 if (!SDDS_LZMABufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, lzmafp, fBuffer)) {
1590 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1591 return (0);
1592 }
1593 if (layout->array_definition[i].type == SDDS_STRING) {
1594 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1595 if (!SDDS_LZMAWriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], lzmafp, fBuffer)) {
1596 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1597 return (0);
1598 }
1599 }
1600 } 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)) {
1601 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1602 return (0);
1603 }
1604 }
1605 } else {
1606 fp = layout->fp;
1607 fBuffer = &SDDS_dataset->fBuffer;
1608 for (i = 0; i < layout->n_arrays; i++) {
1609 if (!SDDS_dataset->array[i].dimension) {
1610 for (j = 0; j < layout->array_definition[i].dimensions; j++)
1611 if (!SDDS_BufferedWrite(&zero, sizeof(zero), fp, fBuffer)) {
1612 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteBinaryArrays)");
1613 return 0;
1614 }
1615 continue;
1616 }
1617 if (!SDDS_BufferedWrite(SDDS_dataset->array[i].dimension, sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions, fp, fBuffer)) {
1618 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteBinaryArrays)");
1619 return (0);
1620 }
1621 if (layout->array_definition[i].type == SDDS_STRING) {
1622 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
1623 if (!SDDS_WriteBinaryString(((char **)SDDS_dataset->array[i].data)[j], fp, fBuffer)) {
1624 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
1625 return (0);
1626 }
1627 }
1628 } 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)) {
1629 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteBinaryArrays)");
1630 return (0);
1631 }
1632 }
1633 }
1634#if defined(zLib)
1635 }
1636#endif
1637 return (1);
1638}
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 1673 of file SDDS_binary.c.

1673 {
1674 int64_t i, row, rows, type, size;
1675 SDDS_LAYOUT *layout;
1676#if defined(zLib)
1677 gzFile gzfp;
1678#endif
1679 FILE *fp;
1680 struct lzmafile *lzmafp;
1681 SDDS_FILEBUFFER *fBuffer;
1682
1683 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryColumns"))
1684 return (0);
1685 layout = &SDDS_dataset->layout;
1686 fBuffer = &SDDS_dataset->fBuffer;
1687 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1688#if defined(zLib)
1689 if (SDDS_dataset->layout.gzipFile) {
1690 gzfp = layout->gzfp;
1691 for (i = 0; i < layout->n_columns; i++) {
1692 type = layout->column_definition[i].type;
1693 size = SDDS_type_size[type - 1];
1694 if (type == SDDS_STRING) {
1695 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1696 if (SDDS_dataset->row_flag[row] && !SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1697 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1698 return (0);
1699 }
1700 }
1701 } else {
1702 if (rows == SDDS_dataset->n_rows) {
1703 if (!SDDS_GZipBufferedWrite(SDDS_dataset->data[i], size * rows, gzfp, fBuffer)) {
1704 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1705 return (0);
1706 }
1707 } else {
1708 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1709 if (SDDS_dataset->row_flag[row] && !SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
1710 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1711 return (0);
1712 }
1713 }
1714 }
1715 }
1716 }
1717 } else {
1718#endif
1719 if (SDDS_dataset->layout.lzmaFile) {
1720 lzmafp = layout->lzmafp;
1721 for (i = 0; i < layout->n_columns; i++) {
1722 type = layout->column_definition[i].type;
1723 size = SDDS_type_size[type - 1];
1724 if (layout->column_definition[i].type == SDDS_STRING) {
1725 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1726 if (SDDS_dataset->row_flag[row] && !SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
1727 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1728 return (0);
1729 }
1730 }
1731 } else {
1732 if (rows == SDDS_dataset->n_rows) {
1733 if (!SDDS_LZMABufferedWrite(SDDS_dataset->data[i], size * rows, lzmafp, fBuffer)) {
1734 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1735 return (0);
1736 }
1737 } else {
1738 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1739 if (SDDS_dataset->row_flag[row] && !SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
1740 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1741 return (0);
1742 }
1743 }
1744 }
1745 }
1746 }
1747 } else {
1748 fp = layout->fp;
1749 for (i = 0; i < layout->n_columns; i++) {
1750 type = layout->column_definition[i].type;
1751 size = SDDS_type_size[type - 1];
1752 if (layout->column_definition[i].type == SDDS_STRING) {
1753 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1754 if (SDDS_dataset->row_flag[row] && !SDDS_WriteBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
1755 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryColumns)");
1756 return (0);
1757 }
1758 }
1759 } else {
1760 if (rows == SDDS_dataset->n_rows) {
1761 if (!SDDS_BufferedWrite(SDDS_dataset->data[i], size * rows, fp, fBuffer)) {
1762 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1763 return (0);
1764 }
1765 } else {
1766 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1767 if (SDDS_dataset->row_flag[row] && !SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
1768 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteBinaryColumns)");
1769 return (0);
1770 }
1771 }
1772 }
1773 }
1774 }
1775 }
1776#if defined(zLib)
1777 }
1778#endif
1779 return (1);
1780}

◆ 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 749 of file SDDS_binary.c.

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

1426 {
1427 int32_t i;
1428 SDDS_LAYOUT *layout;
1429 /* char *predefined_format; */
1430 /* static char buffer[SDDS_MAXLINE]; */
1431#if defined(zLib)
1432 gzFile gzfp;
1433#endif
1434 FILE *fp;
1435 struct lzmafile *lzmafp;
1436 SDDS_FILEBUFFER *fBuffer;
1437
1438 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryParameters"))
1439 return (0);
1440 layout = &SDDS_dataset->layout;
1441#if defined(zLib)
1442 if (SDDS_dataset->layout.gzipFile) {
1443 gzfp = layout->gzfp;
1444 fBuffer = &SDDS_dataset->fBuffer;
1445 for (i = 0; i < layout->n_parameters; i++) {
1446 if (layout->parameter_definition[i].fixed_value)
1447 continue;
1448 if (layout->parameter_definition[i].type == SDDS_STRING) {
1449 if (!SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->parameter[i]), gzfp, fBuffer)) {
1450 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1451 return (0);
1452 }
1453 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer)) {
1454 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1455 return (0);
1456 }
1457 }
1458 } else {
1459#endif
1460 if (SDDS_dataset->layout.lzmaFile) {
1461 lzmafp = layout->lzmafp;
1462 fBuffer = &SDDS_dataset->fBuffer;
1463 for (i = 0; i < layout->n_parameters; i++) {
1464 if (layout->parameter_definition[i].fixed_value)
1465 continue;
1466 if (layout->parameter_definition[i].type == SDDS_STRING) {
1467 if (!SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->parameter[i]), lzmafp, fBuffer)) {
1468 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1469 return (0);
1470 }
1471 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer)) {
1472 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1473 return (0);
1474 }
1475 }
1476 } else {
1477 fp = layout->fp;
1478 fBuffer = &SDDS_dataset->fBuffer;
1479 for (i = 0; i < layout->n_parameters; i++) {
1480 if (layout->parameter_definition[i].fixed_value)
1481 continue;
1482 if (layout->parameter_definition[i].type == SDDS_STRING) {
1483 if (!SDDS_WriteBinaryString(*((char **)SDDS_dataset->parameter[i]), fp, fBuffer)) {
1484 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteBinaryParameters)");
1485 return (0);
1486 }
1487 } else if (!SDDS_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer)) {
1488 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
1489 return (0);
1490 }
1491 }
1492 }
1493#if defined(zLib)
1494 }
1495#endif
1496 return (1);
1497}

◆ 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 1957 of file SDDS_binary.c.

1957 {
1958 int64_t i, type, size;
1959 SDDS_LAYOUT *layout;
1960#if defined(zLib)
1961 gzFile gzfp;
1962#endif
1963 FILE *fp;
1964 struct lzmafile *lzmafp;
1965 SDDS_FILEBUFFER *fBuffer;
1966
1967 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryRow"))
1968 return (0);
1969 layout = &SDDS_dataset->layout;
1970#if defined(zLib)
1971 if (SDDS_dataset->layout.gzipFile) {
1972 gzfp = layout->gzfp;
1973 fBuffer = &SDDS_dataset->fBuffer;
1974 for (i = 0; i < layout->n_columns; i++) {
1975 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
1976 if (!SDDS_GZipWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1977 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
1978 return (0);
1979 }
1980 } else {
1981 size = SDDS_type_size[type - 1];
1982 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
1983 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
1984 return (0);
1985 }
1986 }
1987 }
1988 } else {
1989#endif
1990 if (SDDS_dataset->layout.lzmaFile) {
1991 lzmafp = layout->lzmafp;
1992 fBuffer = &SDDS_dataset->fBuffer;
1993 for (i = 0; i < layout->n_columns; i++) {
1994 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
1995 if (!SDDS_LZMAWriteBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
1996 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
1997 return (0);
1998 }
1999 } else {
2000 size = SDDS_type_size[type - 1];
2001 if (!SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
2002 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
2003 return (0);
2004 }
2005 }
2006 }
2007 } else {
2008 fp = layout->fp;
2009 fBuffer = &SDDS_dataset->fBuffer;
2010 for (i = 0; i < layout->n_columns; i++) {
2011 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
2012 if (!SDDS_WriteBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
2013 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteBinaryRows)");
2014 return (0);
2015 }
2016 } else {
2017 size = SDDS_type_size[type - 1];
2018 if (!SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
2019 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteBinaryRow)");
2020 return (0);
2021 }
2022 }
2023 }
2024 }
2025#if defined(zLib)
2026 }
2027#endif
2028 return (1);
2029}

◆ 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 2517 of file SDDS_binary.c.

2517 {
2518 int32_t length;
2519 static char *dummy_string = "";
2520 if (!string)
2521 string = dummy_string;
2522 length = strlen(string);
2523 if (!SDDS_BufferedWrite(&length, sizeof(length), fp, fBuffer)) {
2524 SDDS_SetError("Unable to write string--error writing length");
2525 return (0);
2526 }
2527 if (length && !SDDS_BufferedWrite(string, sizeof(*string) * length, fp, fBuffer)) {
2528 SDDS_SetError("Unable to write string--error writing contents");
2529 return (0);
2530 }
2531 return (1);
2532}

◆ 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 5350 of file SDDS_binary.c.

5350 {
5351 int32_t i, j, dimension, zero = 0;
5352 SDDS_LAYOUT *layout;
5353 FILE *fp;
5354 struct lzmafile *lzmafp;
5355 SDDS_FILEBUFFER *fBuffer;
5356#if defined(zLib)
5357 gzFile gzfp;
5358#endif
5359 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryArrays"))
5360 return (0);
5361 SDDS_SwapEndsArrayData(SDDS_dataset);
5362
5363 layout = &SDDS_dataset->layout;
5364 fBuffer = &SDDS_dataset->fBuffer;
5365#if defined(zLib)
5366 if (SDDS_dataset->layout.gzipFile) {
5367 gzfp = layout->gzfp;
5368 for (i = 0; i < layout->n_arrays; i++) {
5369 if (!SDDS_dataset->array[i].dimension) {
5370 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5371 if (!SDDS_GZipBufferedWrite(&zero, sizeof(zero), gzfp, fBuffer)) {
5372 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5373 SDDS_SwapEndsArrayData(SDDS_dataset);
5374 return 0;
5375 }
5376 continue;
5377 }
5378
5379 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5380 dimension = SDDS_dataset->array[i].dimension[j];
5381 SDDS_SwapLong(&dimension);
5382 if (!SDDS_GZipBufferedWrite(&dimension, sizeof(dimension), gzfp, fBuffer)) {
5383 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5384 SDDS_SwapEndsArrayData(SDDS_dataset);
5385 return (0);
5386 }
5387 }
5388 if (layout->array_definition[i].type == SDDS_STRING) {
5389 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5390 if (!SDDS_GZipWriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], gzfp, fBuffer)) {
5391 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5392 SDDS_SwapEndsArrayData(SDDS_dataset);
5393 return (0);
5394 }
5395 }
5396 } 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)) {
5397 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5398 SDDS_SwapEndsArrayData(SDDS_dataset);
5399 return (0);
5400 }
5401 }
5402 } else {
5403#endif
5404 if (SDDS_dataset->layout.lzmaFile) {
5405 lzmafp = layout->lzmafp;
5406 for (i = 0; i < layout->n_arrays; i++) {
5407 if (!SDDS_dataset->array[i].dimension) {
5408 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5409 if (!SDDS_LZMABufferedWrite(&zero, sizeof(zero), lzmafp, fBuffer)) {
5410 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5411 SDDS_SwapEndsArrayData(SDDS_dataset);
5412 return 0;
5413 }
5414 continue;
5415 }
5416
5417 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5418 dimension = SDDS_dataset->array[i].dimension[j];
5419 SDDS_SwapLong(&dimension);
5420 if (!SDDS_LZMABufferedWrite(&dimension, sizeof(dimension), lzmafp, fBuffer)) {
5421 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5422 SDDS_SwapEndsArrayData(SDDS_dataset);
5423 return (0);
5424 }
5425 }
5426 if (layout->array_definition[i].type == SDDS_STRING) {
5427 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5428 if (!SDDS_LZMAWriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], lzmafp, fBuffer)) {
5429 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5430 SDDS_SwapEndsArrayData(SDDS_dataset);
5431 return (0);
5432 }
5433 }
5434 } 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)) {
5435 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5436 SDDS_SwapEndsArrayData(SDDS_dataset);
5437 return (0);
5438 }
5439 }
5440 } else {
5441 fp = layout->fp;
5442 for (i = 0; i < layout->n_arrays; i++) {
5443 if (!SDDS_dataset->array[i].dimension) {
5444 for (j = 0; j < layout->array_definition[i].dimensions; j++)
5445 if (!SDDS_BufferedWrite(&zero, sizeof(zero), fp, fBuffer)) {
5446 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5447 SDDS_SwapEndsArrayData(SDDS_dataset);
5448 return 0;
5449 }
5450 continue;
5451 }
5452
5453 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
5454 dimension = SDDS_dataset->array[i].dimension[j];
5455 SDDS_SwapLong(&dimension);
5456 if (!SDDS_BufferedWrite(&dimension, sizeof(dimension), fp, fBuffer)) {
5457 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_WriteNonNativeBinaryArrays)");
5458 SDDS_SwapEndsArrayData(SDDS_dataset);
5459 return (0);
5460 }
5461 }
5462 if (layout->array_definition[i].type == SDDS_STRING) {
5463 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
5464 if (!SDDS_WriteNonNativeBinaryString(((char **)SDDS_dataset->array[i].data)[j], fp, fBuffer)) {
5465 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryArrays)");
5466 SDDS_SwapEndsArrayData(SDDS_dataset);
5467 return (0);
5468 }
5469 }
5470 } 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)) {
5471 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_WriteNonNativeBinaryArrays)");
5472 SDDS_SwapEndsArrayData(SDDS_dataset);
5473 return (0);
5474 }
5475 }
5476 }
5477#if defined(zLib)
5478 }
5479#endif
5480 SDDS_SwapEndsArrayData(SDDS_dataset);
5481 return (1);
5482}
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 1816 of file SDDS_binary.c.

1816 {
1817 int64_t i, row, rows, size, type;
1818 SDDS_LAYOUT *layout;
1819#if defined(zLib)
1820 gzFile gzfp;
1821#endif
1822 FILE *fp;
1823 struct lzmafile *lzmafp;
1824 SDDS_FILEBUFFER *fBuffer;
1825
1826 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryColumns"))
1827 return (0);
1828 layout = &SDDS_dataset->layout;
1829 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1830 fBuffer = &SDDS_dataset->fBuffer;
1831#if defined(zLib)
1832 if (SDDS_dataset->layout.gzipFile) {
1833 gzfp = layout->gzfp;
1834 for (i = 0; i < layout->n_columns; i++) {
1835 type = layout->column_definition[i].type;
1836 size = SDDS_type_size[type - 1];
1837 if (type == SDDS_STRING) {
1838 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1839 if (SDDS_dataset->row_flag[row] && !SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
1840 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1841 return (0);
1842 }
1843 }
1844 } else {
1845 if (rows == SDDS_dataset->n_rows) {
1846 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i], size * rows, gzfp, fBuffer)) {
1847 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1848 return (0);
1849 }
1850 } else {
1851 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1852 if (SDDS_dataset->row_flag[row] && !SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
1853 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1854 return (0);
1855 }
1856 }
1857 }
1858 }
1859 }
1860 } else {
1861#endif
1862 if (SDDS_dataset->layout.lzmaFile) {
1863 lzmafp = layout->lzmafp;
1864 for (i = 0; i < layout->n_columns; i++) {
1865 type = layout->column_definition[i].type;
1866 size = SDDS_type_size[type - 1];
1867 if (type == SDDS_STRING) {
1868 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1869 if (SDDS_dataset->row_flag[row] && !SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
1870 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1871 return (0);
1872 }
1873 }
1874 } else {
1875 if (rows == SDDS_dataset->n_rows) {
1876 if (!SDDS_LZMABufferedWrite(SDDS_dataset->data[i], size * rows, lzmafp, fBuffer)) {
1877 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1878 return (0);
1879 }
1880 } else {
1881 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1882 if (SDDS_dataset->row_flag[row] && !SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
1883 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1884 return (0);
1885 }
1886 }
1887 }
1888 }
1889 }
1890 } else {
1891 fp = layout->fp;
1892 for (i = 0; i < layout->n_columns; i++) {
1893 type = layout->column_definition[i].type;
1894 size = SDDS_type_size[type - 1];
1895 if (type == SDDS_STRING) {
1896 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1897 if (SDDS_dataset->row_flag[row] && !SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
1898 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteNonNativeBinaryColumns)");
1899 return (0);
1900 }
1901 }
1902 } else {
1903 if (rows == SDDS_dataset->n_rows) {
1904 if (!SDDS_BufferedWrite(SDDS_dataset->data[i], size * rows, fp, fBuffer)) {
1905 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1906 return (0);
1907 }
1908 } else {
1909 for (row = 0; row < SDDS_dataset->n_rows; row++) {
1910 if (SDDS_dataset->row_flag[row] && !SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
1911 SDDS_SetError("Unable to write columns--failure writing values (SDDS_WriteNonNativeBinaryColumns)");
1912 return (0);
1913 }
1914 }
1915 }
1916 }
1917 }
1918 }
1919#if defined(zLib)
1920 }
1921#endif
1922 return (1);
1923}

◆ 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 4986 of file SDDS_binary.c.

4990{
4991 FILE *fp;
4992 struct lzmafile *lzmafp = NULL;
4993 int64_t i, rows, fixed_rows;
4994 int32_t min32 = INT32_MIN, rows32;
4995 SDDS_FILEBUFFER *fBuffer;
4996#if defined(zLib)
4997 gzFile gzfp = NULL;
4998#endif
4999
5000 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryPage"))
5001 return (0);
5002 if (!(fp = SDDS_dataset->layout.fp)) {
5003 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5004 return (0);
5005 }
5006 fBuffer = &SDDS_dataset->fBuffer;
5007
5008 if (!fBuffer->buffer) {
5009 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * defaultIOBufferSize))) {
5010 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteNonNativeBinaryPage)");
5011 return 0;
5012 }
5013 fBuffer->bufferSize = defaultIOBufferSize;
5014 fBuffer->bytesLeft = defaultIOBufferSize;
5015 }
5016 SDDS_SwapLong(&min32);
5017
5018 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
5019#if defined(zLib)
5020 if (SDDS_dataset->layout.gzipFile) {
5021 if (!(gzfp = SDDS_dataset->layout.gzfp)) {
5022 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5023 return (0);
5024 }
5025 SDDS_dataset->rowcount_offset = gztell(gzfp);
5026 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5027 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5028 if (fixed_rows > INT32_MAX) {
5029 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
5030 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5031 return (0);
5032 }
5033 SDDS_SwapLong64(&fixed_rows);
5034 if (!SDDS_GZipBufferedWrite(&fixed_rows, sizeof(fixed_rows), gzfp, fBuffer)) {
5035 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5036 return (0);
5037 }
5038 SDDS_SwapLong64(&fixed_rows);
5039 } else {
5040 rows32 = (int32_t)fixed_rows;
5041 SDDS_SwapLong(&rows32);
5042 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
5043 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5044 return (0);
5045 }
5046 }
5047 } else {
5048 if (rows > INT32_MAX) {
5049 if (!SDDS_GZipBufferedWrite(&min32, sizeof(min32), gzfp, fBuffer)) {
5050 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5051 return (0);
5052 }
5053 SDDS_SwapLong64(&rows);
5054 if (!SDDS_GZipBufferedWrite(&rows, sizeof(rows), gzfp, fBuffer)) {
5055 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5056 return (0);
5057 }
5058 SDDS_SwapLong64(&rows);
5059 } else {
5060 rows32 = (int32_t)rows;
5061 SDDS_SwapLong(&rows32);
5062 if (!SDDS_GZipBufferedWrite(&rows32, sizeof(rows32), gzfp, fBuffer)) {
5063 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5064 return (0);
5065 }
5066 }
5067 }
5068 } else {
5069#endif
5070 if (SDDS_dataset->layout.lzmaFile) {
5071 if (!(lzmafp = SDDS_dataset->layout.lzmafp)) {
5072 SDDS_SetError("Unable to write page--file pointer is NULL (SDDS_WriteNonNativeBinaryPage)");
5073 return (0);
5074 }
5075 SDDS_dataset->rowcount_offset = lzma_tell(lzmafp);
5076 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5077 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5078 if (fixed_rows > INT32_MAX) {
5079 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
5080 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5081 return (0);
5082 }
5083 SDDS_SwapLong64(&fixed_rows);
5084 if (!SDDS_LZMABufferedWrite(&fixed_rows, sizeof(fixed_rows), lzmafp, fBuffer)) {
5085 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5086 return (0);
5087 }
5088 SDDS_SwapLong64(&fixed_rows);
5089 } else {
5090 rows32 = (int32_t)fixed_rows;
5091 SDDS_SwapLong(&rows32);
5092 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
5093 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5094 return (0);
5095 }
5096 }
5097 } else {
5098 if (rows > INT32_MAX) {
5099 if (!SDDS_LZMABufferedWrite(&min32, sizeof(min32), lzmafp, fBuffer)) {
5100 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5101 return (0);
5102 }
5103 SDDS_SwapLong64(&rows);
5104 if (!SDDS_LZMABufferedWrite(&rows, sizeof(rows), lzmafp, fBuffer)) {
5105 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5106 return (0);
5107 }
5108 SDDS_SwapLong64(&rows);
5109 } else {
5110 rows32 = (int32_t)rows;
5111 SDDS_SwapLong(&rows32);
5112 if (!SDDS_LZMABufferedWrite(&rows32, sizeof(rows32), lzmafp, fBuffer)) {
5113 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5114 return (0);
5115 }
5116 }
5117 }
5118 } else {
5119 SDDS_dataset->rowcount_offset = ftell(fp);
5120 if (SDDS_dataset->layout.data_mode.fixed_row_count) {
5121 fixed_rows = ((rows / SDDS_dataset->layout.data_mode.fixed_row_increment) + 2) * SDDS_dataset->layout.data_mode.fixed_row_increment;
5122 if (fixed_rows > INT32_MAX) {
5123 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
5124 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5125 return (0);
5126 }
5127 SDDS_SwapLong64(&fixed_rows);
5128 if (!SDDS_BufferedWrite(&fixed_rows, sizeof(fixed_rows), fp, fBuffer)) {
5129 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5130 return (0);
5131 }
5132 SDDS_SwapLong64(&fixed_rows);
5133 } else {
5134 rows32 = (int32_t)fixed_rows;
5135 SDDS_SwapLong(&rows32);
5136 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
5137 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5138 return (0);
5139 }
5140 }
5141 } else {
5142 if (rows > INT32_MAX) {
5143 if (!SDDS_BufferedWrite(&min32, sizeof(min32), fp, fBuffer)) {
5144 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5145 return (0);
5146 }
5147 SDDS_SwapLong64(&rows);
5148 if (!SDDS_BufferedWrite(&rows, sizeof(rows), fp, fBuffer)) {
5149 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5150 return (0);
5151 }
5152 SDDS_SwapLong64(&rows);
5153 } else {
5154 rows32 = (int32_t)rows;
5155 SDDS_SwapLong(&rows32);
5156 if (!SDDS_BufferedWrite(&rows32, sizeof(rows32), fp, fBuffer)) {
5157 SDDS_SetError("Unable to write page--failure writing number of rows (SDDS_WriteNonNativeBinaryPage)");
5158 return (0);
5159 }
5160 }
5161 }
5162 }
5163#if defined(zLib)
5164 }
5165#endif
5166 if (!SDDS_WriteNonNativeBinaryParameters(SDDS_dataset)) {
5167 SDDS_SetError("Unable to write page--parameter writing problem (SDDS_WriteNonNativeBinaryPage)");
5168 return 0;
5169 }
5170 if (!SDDS_WriteNonNativeBinaryArrays(SDDS_dataset)) {
5171 SDDS_SetError("Unable to write page--array writing problem (SDDS_WriteNonNativeBinaryPage)");
5172 return 0;
5173 }
5174 SDDS_SwapEndsColumnData(SDDS_dataset);
5175 if (SDDS_dataset->layout.n_columns) {
5176 if (SDDS_dataset->layout.data_mode.column_major) {
5177 if (!SDDS_WriteNonNativeBinaryColumns(SDDS_dataset)) {
5178 SDDS_SetError("Unable to write page--column writing problem (SDDS_WriteNonNativeBinaryPage)");
5179 return 0;
5180 }
5181 } else {
5182 for (i = 0; i < SDDS_dataset->n_rows; i++) {
5183 if (SDDS_dataset->row_flag[i]) {
5184 if (!SDDS_WriteNonNativeBinaryRow(SDDS_dataset, i)) {
5185 SDDS_SetError("Unable to write page--row writing problem (SDDS_WriteNonNativeBinaryPage)");
5186 return 0;
5187 }
5188 }
5189 }
5190 }
5191 }
5192 SDDS_SwapEndsColumnData(SDDS_dataset);
5193#if defined(zLib)
5194 if (SDDS_dataset->layout.gzipFile) {
5195 if (!SDDS_GZipFlushBuffer(gzfp, fBuffer)) {
5196 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5197 return 0;
5198 }
5199 } else {
5200#endif
5201 if (SDDS_dataset->layout.lzmaFile) {
5202 if (!SDDS_LZMAFlushBuffer(lzmafp, fBuffer)) {
5203 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5204 return 0;
5205 }
5206 } else {
5207 if (!SDDS_FlushBuffer(fp, fBuffer)) {
5208 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteNonNativeBinaryPage)");
5209 return 0;
5210 }
5211 }
5212#if defined(zLib)
5213 }
5214#endif
5215 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
5216 SDDS_dataset->n_rows_written = rows;
5217 SDDS_dataset->writing_page = 1;
5218 return (1);
5219}
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 5242 of file SDDS_binary.c.

5242 {
5243 int32_t i;
5244 SDDS_LAYOUT *layout;
5245 FILE *fp;
5246 struct lzmafile *lzmafp;
5247 SDDS_FILEBUFFER *fBuffer;
5248#if defined(zLib)
5249 gzFile gzfp;
5250#endif
5251
5252 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryParameters"))
5253 return (0);
5254
5255 SDDS_SwapEndsParameterData(SDDS_dataset);
5256
5257 layout = &SDDS_dataset->layout;
5258 fBuffer = &SDDS_dataset->fBuffer;
5259#if defined(zLib)
5260 if (SDDS_dataset->layout.gzipFile) {
5261 if (!(gzfp = layout->gzfp)) {
5262 SDDS_SetError("Unable to write parameters--file pointer is NULL (SDDS_WriteNonNativeBinaryParameters)");
5263 return (0);
5264 }
5265 for (i = 0; i < layout->n_parameters; i++) {
5266 if (layout->parameter_definition[i].fixed_value)
5267 continue;
5268 if (layout->parameter_definition[i].type == SDDS_STRING) {
5269 if (!SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), gzfp, fBuffer)) {
5270 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5271 SDDS_SwapEndsParameterData(SDDS_dataset);
5272 return (0);
5273 }
5274 } else if (!SDDS_GZipBufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], gzfp, fBuffer)) {
5275 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5276 SDDS_SwapEndsParameterData(SDDS_dataset);
5277 return (0);
5278 }
5279 }
5280 } else {
5281#endif
5282 if (SDDS_dataset->layout.lzmaFile) {
5283 if (!(lzmafp = layout->lzmafp)) {
5284 SDDS_SetError("Unable to write parameters--file pointer is NULL (SDDS_WriteNonNativeBinaryParameters)");
5285 return (0);
5286 }
5287 for (i = 0; i < layout->n_parameters; i++) {
5288 if (layout->parameter_definition[i].fixed_value)
5289 continue;
5290 if (layout->parameter_definition[i].type == SDDS_STRING) {
5291 if (!SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), lzmafp, fBuffer)) {
5292 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5293 SDDS_SwapEndsParameterData(SDDS_dataset);
5294 return (0);
5295 }
5296 } else if (!SDDS_LZMABufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], lzmafp, fBuffer)) {
5297 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5298 SDDS_SwapEndsParameterData(SDDS_dataset);
5299 return (0);
5300 }
5301 }
5302 } else {
5303 fp = layout->fp;
5304 for (i = 0; i < layout->n_parameters; i++) {
5305 if (layout->parameter_definition[i].fixed_value)
5306 continue;
5307 if (layout->parameter_definition[i].type == SDDS_STRING) {
5308 if (!SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->parameter[i]), fp, fBuffer)) {
5309 SDDS_SetError("Unable to write parameters--failure writing string (SDDS_WriteNonNativeBinaryParameters)");
5310 SDDS_SwapEndsParameterData(SDDS_dataset);
5311 return (0);
5312 }
5313 } else if (!SDDS_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], fp, fBuffer)) {
5314 SDDS_SetError("Unable to write parameters--failure writing value (SDDS_WriteBinaryParameters)");
5315 SDDS_SwapEndsParameterData(SDDS_dataset);
5316 return (0);
5317 }
5318 }
5319 }
5320#if defined(zLib)
5321 }
5322#endif
5323
5324 SDDS_SwapEndsParameterData(SDDS_dataset);
5325 return (1);
5326}

◆ 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 5505 of file SDDS_binary.c.

5505 {
5506 int64_t i, type, size;
5507 SDDS_LAYOUT *layout;
5508 FILE *fp;
5509 struct lzmafile *lzmafp;
5510 SDDS_FILEBUFFER *fBuffer;
5511#if defined(zLib)
5512 gzFile gzfp;
5513#endif
5514
5515 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteNonNativeBinaryRow"))
5516 return (0);
5517 layout = &SDDS_dataset->layout;
5518 fBuffer = &SDDS_dataset->fBuffer;
5519#if defined(zLib)
5520 if (SDDS_dataset->layout.gzipFile) {
5521 gzfp = layout->gzfp;
5522 for (i = 0; i < layout->n_columns; i++) {
5523 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5524 if (!SDDS_GZipWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), gzfp, fBuffer)) {
5525 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5526 return (0);
5527 }
5528 } else {
5529 size = SDDS_type_size[type - 1];
5530 if (!SDDS_GZipBufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, gzfp, fBuffer)) {
5531 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5532 return (0);
5533 }
5534 }
5535 }
5536 } else {
5537#endif
5538 if (SDDS_dataset->layout.lzmaFile) {
5539 lzmafp = layout->lzmafp;
5540 for (i = 0; i < layout->n_columns; i++) {
5541 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5542 if (!SDDS_LZMAWriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), lzmafp, fBuffer)) {
5543 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5544 return (0);
5545 }
5546 } else {
5547 size = SDDS_type_size[type - 1];
5548 if (!SDDS_LZMABufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, lzmafp, fBuffer)) {
5549 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5550 return (0);
5551 }
5552 }
5553 }
5554 } else {
5555 fp = layout->fp;
5556 for (i = 0; i < layout->n_columns; i++) {
5557 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
5558 if (!SDDS_WriteNonNativeBinaryString(*((char **)SDDS_dataset->data[i] + row), fp, fBuffer)) {
5559 SDDS_SetError("Unable to write rows--failure writing string (SDDS_WriteNonNativeBinaryRows)");
5560 return (0);
5561 }
5562 } else {
5563 size = SDDS_type_size[type - 1];
5564 if (!SDDS_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, fp, fBuffer)) {
5565 SDDS_SetError("Unable to write row--failure writing value (SDDS_WriteNonNativeBinaryRow)");
5566 return (0);
5567 }
5568 }
5569 }
5570 }
5571#if defined(zLib)
5572 }
5573#endif
5574 return (1);
5575}

◆ 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 5597 of file SDDS_binary.c.

5597 {
5598 int32_t length;
5599 static char *dummy_string = "";
5600 if (!string)
5601 string = dummy_string;
5602 length = strlen(string);
5603 SDDS_SwapLong(&length);
5604 if (!SDDS_BufferedWrite(&length, sizeof(length), fp, fBuffer)) {
5605 SDDS_SetError("Unable to write string--error writing length");
5606 return (0);
5607 }
5608 SDDS_SwapLong(&length);
5609 if (length && !SDDS_BufferedWrite(string, sizeof(*string) * length, fp, fBuffer)) {
5610 SDDS_SetError("Unable to write string--error writing contents");
5611 return (0);
5612 }
5613 return (1);
5614}