SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsendian.c File Reference

Detailed Description

Converts between big-endian and little-endian formats for SDDS files.

This program processes Self-Describing Data Sets (SDDS) to convert data between big-endian and little-endian byte orders. It supports both binary and ASCII SDDS files and provides options for handling data piping and specifying row or column major order.

Usage

sddsendian [<input>] [<output>]
[-pipe=[input][,output]]
[-nonNative]
[-majorOrder=row|column]

Options

Option Description
-pipe Use pipe for input and/or output. Requires specifying at least one of input or output.
-nonNative Handle non-native byte order files.
-majorOrder Set the major order to row or column. Must be followed by either row or column.
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, R. Soliday, H. Shang

Definition in file sddsendian.c.

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

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 73 of file sddsendian.c.

73 {
74 SDDS_DATASET SDDSin, SDDSout;
75 long i_arg, tmpfile_used;
76 SCANNED_ARG *s_arg;
77 char *input, *output, *description_text, *description_contents;
78 unsigned long pipe_flags, major_order_flag;
79 long page_number, non_native = 0;
80 char *output_endianess = NULL;
81 char buffer[40];
82 short column_major_order = -1;
83
84 // Register the program name for SDDS utilities
86
87 // Parse command-line arguments
88 argc = scanargs(&s_arg, argc, argv);
89 if (argc < 2) // Ensure at least one argument is provided
90 bomb(NULL, USAGE);
91
92 // Initialize variables for input/output files and options
93 input = output = description_text = description_contents = NULL;
94 pipe_flags = 0;
95
96 // Process each command-line argument
97 for (i_arg = 1; i_arg < argc; i_arg++) {
98 if (s_arg[i_arg].arg_type == OPTION) {
99 delete_chars(s_arg[i_arg].list[0], "_"); // Normalize option string
100 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
101 case SET_MAJOR_ORDER:
102 major_order_flag = 0;
103 s_arg[i_arg].n_items--;
104 // Parse major order option
105 if (s_arg[i_arg].n_items > 0 && (!scanItemList(&major_order_flag, s_arg[i_arg].list + 1,
106 &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0,
107 SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0,
108 SDDS_COLUMN_MAJOR_ORDER, NULL)))
109 SDDS_Bomb("invalid -majorOrder syntax/values");
110 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
111 column_major_order = 1; // Set column major order
112 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
113 column_major_order = 0; // Set row major order
114 break;
115 case SET_PIPE:
116 // Parse pipe option
117 if (!processPipeOption(s_arg[i_arg].list + 1,
118 s_arg[i_arg].n_items - 1, &pipe_flags))
119 SDDS_Bomb("invalid -pipe syntax");
120 break;
121 case NONNATIVE:
122 non_native = 1; // Enable non-native byte order handling
123 break;
124 default:
125 // Handle unknown options
126 fprintf(stderr, "Error (%s): unknown switch: %s\n", argv[0],
127 s_arg[i_arg].list[0]);
128 exit(1);
129 break;
130 }
131 } else {
132 // Assign input and output filenames
133 if (input == NULL)
134 input = s_arg[i_arg].list[0];
135 else if (output == NULL)
136 output = s_arg[i_arg].list[0];
137 else
138 SDDS_Bomb("too many filenames");
139 }
140 }
141
142 // Process filenames and handle temporary files
143 processFilenames("sddsendian", &input, &output, pipe_flags, 0,
144 &tmpfile_used);
145
146 // Check and clear output endianess environment variable
147 output_endianess = getenv("SDDS_OUTPUT_ENDIANESS");
148
149 if (output_endianess) {
150 putenv("SDDS_OUTPUT_ENDIANESS=");
151 }
152
153 // Initialize the input SDDS dataset
154 if (!SDDS_InitializeInput(&SDDSin, input)) {
155 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
156 exit(1);
157 }
158
159 // Retrieve description text if available
160 if (!description_text)
161 SDDS_GetDescription(&SDDSin, &description_text, &description_contents);
162
163 // Initialize the output SDDS dataset and set data mode
164 if (!SDDS_InitializeCopy(&SDDSout, &SDDSin, output, "w") || !SDDS_SetDataMode(&SDDSout, non_native ? SDDS_BINARY : -SDDS_BINARY)) {
165 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
166 exit(1);
167 }
168
169 // Set column/row major order based on parsed options
170 if (column_major_order != -1)
171 SDDSout.layout.data_mode.column_major = column_major_order;
172 else
173 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
174
175 // Write the layout of the output file
176 if (!SDDS_WriteLayout(&SDDSout)) {
177 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
178 exit(1);
179 }
180
181 // Process pages in the input file and write to the output file
182 if (non_native) {
183 while ((page_number = SDDS_ReadNonNativePage(&SDDSin)) >= 0) {
184 if (!SDDS_CopyPage(&SDDSout, &SDDSin) || !SDDS_WritePage(&SDDSout)) {
185 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
186 exit(1);
187 }
188 }
189 } else {
190 while ((page_number = SDDS_ReadPage(&SDDSin)) >= 0) {
191 if (!SDDS_CopyPage(&SDDSout, &SDDSin) || !SDDS_WriteNonNativeBinaryPage(&SDDSout)) {
192 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
193 exit(1);
194 }
195 }
196 }
197
198 // Terminate the input and output datasets
199 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
200 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
201 exit(1);
202 }
203
204 // Replace temporary files if necessary
205 if (tmpfile_used && !replaceFileAndBackUp(input, output))
206 exit(1);
207
208 // Restore output endianess environment variable if it was set
209 if (output_endianess) {
210 sprintf(buffer, "SDDS_OUTPUT_ENDIANESS=%s", output_endianess);
211 putenv(buffer);
212 }
213
214 return 0; // Return success
215}
int32_t SDDS_WriteNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset)
Writes a non-native endian binary page to an SDDS dataset.
int32_t SDDS_ReadNonNativePage(SDDS_DATASET *SDDS_dataset)
Reads a non-native endian page from an SDDS dataset.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_GetDescription(SDDS_DATASET *SDDS_dataset, char **text, char **contents)
Retrieves the text and contents descriptions from an SDDS dataset.
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)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_SetDataMode(SDDS_DATASET *SDDS_dataset, int32_t newmode)
Sets the data mode (ASCII or Binary) for 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_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
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
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.