82 {
83 FILE *file_id;
85
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) {
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) {
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:
122 break;
123 }
124 break;
125 case SET_COLUMN:
126 if ((s_arg[i_arg].n_items < 2)) {
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
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++) {
178 fprintf(stderr, "error: column %s does not exist\n", column[i]);
179 exit(1);
180 }
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 }
222 exit(1);
223 }
224 if (rows) {
225 if (column_order) {
226 for (j = 0; j < columns; j++) {
228 for (i = 0; i < rows; i++) {
230 fprintf(stderr, "Unable to write rows--failure writing string\n");
231 exit(1);
232 }
233 }
234 } else {
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++) {
249 fprintf(stderr, "Unable to write rows--failure writing string\n");
250 exit(1);
251 }
252 } else {
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) {
265 exit(1);
266 }
267 }
269 SDDS_SetError(
"Unable to write page--buffer flushing problem (SDDS_WriteBinaryPage)");
270 return 0;
271 }
272 fclose(file_id);
273
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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
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.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
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.
#define SDDS_STRING
Identifier for the string data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)