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

Converts SDDS files into binary data without headers. More...

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Macros

#define ROW_ORDER   0
 
#define COLUMN_ORDER   1
 
#define ORDERS   2
 

Enumerations

enum  option_type { SET_COLUMN , SET_PIPE , SET_ORDER , N_OPTIONS }
 

Functions

int main (int argc, char **argv)
 

Variables

static char * order_names [ORDERS]
 
static char * option [N_OPTIONS]
 
static char * usage
 

Detailed Description

Converts SDDS files into binary data without headers.

This program reads an SDDS file, extracts specified columns, and writes the data to a binary file in either row-major or column-major order. The program supports flexible options for specifying columns, output order, and piping data.

Usage:

sdds2headlessdata <input> <output>
[-order={rowMajor|columnMajor}] [-pipe=in|out]
[-column=<name>]
  • -order: Specifies the output order:
    • rowMajor (default): Each row consists of one element from each column.
    • columnMajor: Each column is written entirely in one row.
  • -column: Specifies the columns to include in the output.
  • -pipe: Allows piping data into or out of the program.

Options:

  • The program requires at least one column to be specified with -column.
  • Input and output file names can be specified, or data can be piped.

Example:

sdds2headlessdata input.sdds output.bin -order=rowMajor -column=x -column=y
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday

Definition in file sdds2headlessdata.c.

Macro Definition Documentation

◆ COLUMN_ORDER

#define COLUMN_ORDER   1

Definition at line 50 of file sdds2headlessdata.c.

◆ ORDERS

#define ORDERS   2

Definition at line 51 of file sdds2headlessdata.c.

◆ ROW_ORDER

#define ROW_ORDER   0

Definition at line 49 of file sdds2headlessdata.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 58 of file sdds2headlessdata.c.

58 {
59 SET_COLUMN,
60 SET_PIPE,
61 SET_ORDER,
62 N_OPTIONS
63};

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 82 of file sdds2headlessdata.c.

82 {
83 FILE *file_id;
84 SDDS_FILEBUFFER *f_buffer = NULL;
85
86 SDDS_DATASET sdds_dataset, sdds_dummy;
87 SCANNED_ARG *s_arg;
88 long j, i_arg, retval, page_number = 0, size, column_order = 0;
89 int64_t i, rows = 0;
90 char *input = NULL, *output = NULL;
91 unsigned long pipe_flags = 0;
92 long no_warnings = 0, tmpfile_used = 0;
93
94 long *column_type = NULL, *column_index = NULL;
95 void **column_data = NULL;
96 char **column = NULL, **column_match = NULL;
97 int32_t column_matches = 0;
98 int32_t columns = 0;
99
101 argc = scanargs(&s_arg, argc, argv);
102 if (argc < 3) {
103 bomb(NULL, usage);
104 }
105
106 for (i_arg = 1; i_arg < argc; i_arg++) {
107 if (s_arg[i_arg].arg_type == OPTION) {
108 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
109 case SET_ORDER:
110 if (s_arg[i_arg].n_items != 2) {
111 SDDS_Bomb("invalid -order syntax");
112 }
113 switch (match_string(s_arg[i_arg].list[1], order_names, ORDERS, 0)) {
114 case ROW_ORDER:
115 column_order = 0;
116 break;
117 case COLUMN_ORDER:
118 column_order = 1;
119 break;
120 default:
121 SDDS_Bomb("invalid -order syntax");
122 break;
123 }
124 break;
125 case SET_COLUMN:
126 if ((s_arg[i_arg].n_items < 2)) {
127 SDDS_Bomb("invalid -column syntax");
128 }
129 column_matches = s_arg[i_arg].n_items - 1;
130 column_match = tmalloc(sizeof(*column_match) * column_matches);
131 for (i = 0; i < column_matches; i++) {
132 column_match[i] = s_arg[i_arg].list[i + 1];
133 }
134 break;
135 case SET_PIPE:
136 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipe_flags)) {
137 fprintf(stderr, "Error (%s): invalid -pipe syntax\n", argv[0]);
138 return 1;
139 }
140 break;
141 default:
142 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
143 exit(1);
144 }
145 } else {
146 if (input == NULL) {
147 input = s_arg[i_arg].list[0];
148 } else if (output == NULL) {
149 output = s_arg[i_arg].list[0];
150 } else {
151 fprintf(stderr, "too many filenames");
152 exit(1);
153 }
154 }
155 }
156
157 processFilenames("sdds2headlessdata", &input, &output, pipe_flags, no_warnings, &tmpfile_used);
158
159 if (!column_matches) {
160 SDDS_Bomb("you must specify -column options");
161 }
162
163 if (!SDDS_InitializeInput(&sdds_dataset, input)) {
164 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
165 exit(1);
166 }
167
168 column = getMatchingSDDSNames(&sdds_dataset, column_match, column_matches, &columns, SDDS_MATCH_COLUMN);
169 if (!columns) {
170 SDDS_Bomb("No columns found in the input file.");
171 }
172
173 column_type = tmalloc(sizeof(*column_type) * columns);
174 column_index = tmalloc(sizeof(*column_index) * columns);
175 column_data = tmalloc(sizeof(*column_data) * columns);
176 for (i = 0; i < columns; i++) {
177 if ((column_index[i] = SDDS_GetColumnIndex(&sdds_dataset, column[i])) < 0) {
178 fprintf(stderr, "error: column %s does not exist\n", column[i]);
179 exit(1);
180 }
181 if ((column_type[i] = SDDS_GetColumnType(&sdds_dataset, column_index[i])) <= 0) {
182 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
183 exit(1);
184 }
185 }
186
187 if (!output) {
188#ifdef _WIN32
189 if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
190 fprintf(stderr, "error: unable to set stdout to binary mode\n");
191 exit(1);
192 }
193#endif
194 file_id = stdout;
195 } else {
196 file_id = fopen(output, "wb");
197 }
198 if (file_id == NULL) {
199 fprintf(stderr, "unable to open output file for writing\n");
200 exit(1);
201 }
202
203 f_buffer = &sdds_dummy.fBuffer;
204 f_buffer->buffer = NULL;
205 if (!f_buffer->buffer) {
206 if (!(f_buffer->buffer = f_buffer->data = SDDS_Malloc(sizeof(char) * SDDS_FILEBUFFER_SIZE))) {
207 fprintf(stderr, "Unable to do buffered read--allocation failure\n");
208 exit(1);
209 }
210 f_buffer->bufferSize = SDDS_FILEBUFFER_SIZE;
211 f_buffer->bytesLeft = SDDS_FILEBUFFER_SIZE;
212 }
213
214 retval = -1;
215
216 while (retval != page_number && (retval = SDDS_ReadPage(&sdds_dataset)) > 0) {
217 if (page_number && retval != page_number) {
218 continue;
219 }
220 if ((rows = SDDS_CountRowsOfInterest(&sdds_dataset)) < 0) {
221 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
222 exit(1);
223 }
224 if (rows) {
225 if (column_order) {
226 for (j = 0; j < columns; j++) {
227 if (column_type[j] == SDDS_STRING) {
228 for (i = 0; i < rows; i++) {
229 if (!SDDS_WriteBinaryString(*((char **)sdds_dataset.data[column_index[j]] + i), file_id, f_buffer)) {
230 fprintf(stderr, "Unable to write rows--failure writing string\n");
231 exit(1);
232 }
233 }
234 } else {
235 size = SDDS_type_size[column_type[j] - 1];
236 for (i = 0; i < rows; i++) {
237 if (!SDDS_BufferedWrite((char *)sdds_dataset.data[column_index[j]] + i * size, size, file_id, f_buffer)) {
238 fprintf(stderr, "Unable to write rows--failure writing string\n");
239 exit(1);
240 }
241 }
242 }
243 }
244 } else {
245 for (i = 0; i < rows; i++) {
246 for (j = 0; j < columns; j++) {
247 if (column_type[j] == SDDS_STRING) {
248 if (!SDDS_WriteBinaryString(*((char **)sdds_dataset.data[column_index[j]] + i), file_id, f_buffer)) {
249 fprintf(stderr, "Unable to write rows--failure writing string\n");
250 exit(1);
251 }
252 } else {
253 size = SDDS_type_size[column_type[j] - 1];
254 if (!SDDS_BufferedWrite((char *)sdds_dataset.data[column_index[j]] + i * size, size, file_id, f_buffer)) {
255 fprintf(stderr, "Unable to write rows--failure writing string\n");
256 exit(1);
257 }
258 }
259 }
260 }
261 }
262 }
263 if (retval == 0) {
264 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
265 exit(1);
266 }
267 }
268 if (!SDDS_FlushBuffer(file_id, f_buffer)) {
269 SDDS_SetError("Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
270 return 0;
271 }
272 fclose(file_id);
273
274 if (!SDDS_Terminate(&sdds_dataset)) {
275 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
276 exit(1);
277 }
278 exit(0);
279}
int32_t SDDS_BufferedWrite(void *target, int64_t targetSize, FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_WriteBinaryString(char *string, FILE *fp, SDDS_FILEBUFFER *fBuffer)
Writes a binary string to a file with buffering.
int32_t SDDS_FlushBuffer(FILE *fp, SDDS_FILEBUFFER *fBuffer)
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390

Variable Documentation

◆ option

char* option[N_OPTIONS]
static
Initial value:
= {
"column",
"pipe",
"order",
}

Definition at line 65 of file sdds2headlessdata.c.

65 {
66 "column",
67 "pipe",
68 "order",
69};

◆ order_names

char* order_names[ORDERS]
static
Initial value:
= {
"rowMajor",
"columnMajor",
}

Definition at line 52 of file sdds2headlessdata.c.

52 {
53 "rowMajor",
54 "columnMajor",
55};

◆ usage

char* usage
static
Initial value:
=
"sdds2headlessdata <input> <output>\n"
"[-order={rowMajor|columnMajor}] [-pipe=in|out]\n"
"[-column=<name>]\n\n"
"-order: Row major order is the default. Each row consists of one element\n"
" from each column. In column major order, each column is written entirely\n"
" on one row.\n"
"-column: Provide the columns whose data are to be written.\n\n"
"Program by Hairong Shang.\n"
"Link date: " __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION "\n"

Definition at line 71 of file sdds2headlessdata.c.