18typedef signed __int16 int16_t;
19typedef signed __int8 int8_t;
20typedef unsigned __int16 uint16_t;
21typedef signed __int64 int64_t;
28 uint64_t next_segment_offset;
29 uint64_t raw_data_offset;
42 uint32_t raw_data_index;
43 int32_t raw_data_datatype;
44 uint32_t raw_data_dimensions;
45 uint64_t raw_data_count;
46 uint64_t raw_data_total_size;
47 uint32_t n_properties;
75 long double start_time;
76 long double start_offset;
77 long double increment;
100void TDMS_ReadRawData(FILE *fd,
TDMS_FILE *tdms, uint32_t n_segment,
long filesize);
101void TDMS_GetValue(FILE *fd,
void **value, int32_t datatype);
103#define kTocMetaData (1L << 1)
104#define kTocNewObjList (1L << 2)
105#define kTocRawData (1L << 3)
106#define kTocInterleavedData (1L << 5)
107#define kTocBigEndian (1L << 6)
108#define kTocDAQmxRawData (1L << 7)
110#define tdsTypeVoid 0x00000000
111#define tdsTypeI8 0x00000001
112#define tdsTypeI16 0x00000002
113#define tdsTypeI32 0x00000003
114#define tdsTypeI64 0x00000004
115#define tdsTypeU8 0x00000005
116#define tdsTypeU16 0x00000006
117#define tdsTypeU32 0x00000007
118#define tdsTypeU64 0x00000008
119#define tdsTypeSingleFloat 0x00000009
120#define tdsTypeDoubleFloat 0x0000000A
121#define tdsTypeExtendedFloat 0x0000000B
122#define tdsTypeSingleFloatWithUnit 0x00000019
123#define tdsTypeDoubleFloatWithUnit 0x0000001A
124#define tdsTypeExtendedFloatWithUnit 0x0000001B
125#define tdsTypeString 0x00000020
126#define tdsTypeBoolean 0x00000021
127#define tdsTypeTimeStamp 0x00000044
128#define tdsTypeDAQmxRawData 0xFFFFFFFF
134#define SET_NUMOFSEGMENTS 4
137char *option[N_OPTIONS] = {
138 "ascii",
"binary",
"pipe",
"segment",
"numofsegments"};
140char *USAGE =
"tdms2sdds [<inputFile>] [<outputFile>] [-pipe=out]\n\
141[-ascii | -binary] [-numOfSegments] [-segment=<integer>]\n\n\
142pipe SDDS toolkit pipe option.\n\
143ascii Requests SDDS ASCII output. Default is binary.\n\
144binary Requests SDDS BINARY output.\n\
145numofsegments Print out number of TDMS segments.\n\
146segment Some TDMS files have different types of data in different segments. \n\
147 SDDS can't handle this unless you split it up into multiple SDDS \n\
148 files, one for each segment.\n\n\
149Converts National Instruments TDMS files to SDDS.\n\
150Program by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
152int main(
int argc,
char **argv) {
154 char *input = NULL, *output = NULL;
156 SCANNED_ARG *scanned;
159 unsigned long pipeFlags = 0;
160 int i = 0, n, found, ii, jj, kk, segment = 0, querySegments = 0;
161 long double timeValue;
162 short timeDefined = 0;
166 uint64_t rows = 0, j = 0, k;
169 argc =
scanargs(&scanned, argc, argv);
171 fprintf(stderr,
"%s", USAGE);
175 for (iArg = 1; iArg < argc; iArg++) {
176 if (scanned[iArg].arg_type == OPTION) {
177 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
185 if (scanned[iArg].n_items < 2) {
186 fprintf(stderr,
"Error (%s): invalid -segment syntax\n", argv[0]);
189 if (sscanf(scanned[iArg].list[1],
"%d", &segment) != 1 || segment <= 0) {
190 fprintf(stderr,
"Error (%s): invalid -segment syntax or value\n", argv[0]);
194 case SET_NUMOFSEGMENTS:
198 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
199 fprintf(stderr,
"invalid -pipe syntax\n");
204 fprintf(stderr,
"invalid option seen\n");
205 fprintf(stderr,
"%s", USAGE);
210 input = scanned[iArg].list[0];
212 output = scanned[iArg].list[0];
214 fprintf(stderr,
"too many filenames\n");
215 fprintf(stderr,
"%s", USAGE);
220 if (!querySegments) {
226 fprintf(stderr,
"input file not found\n");
229 if (!(fd = fopen(input,
"rb"))) {
230 fprintf(stderr,
"problem opening input file\n");
234 fprintf(stderr,
"tdms2sdds cannot -pipe=in tdms files\n");
238 fseek(fd, 0L, SEEK_END);
239 tdms.filesize = ftell(fd);
240 fseek(fd, 0L, SEEK_SET);
243 while (ftell(fd) < tdms.filesize) {
245 if (tdms.n_segments == 1) {
248 tdms.segment = realloc(tdms.segment,
sizeof(
TDMS_SEGMENT) * tdms.n_segments);
251 TDMS_ReadLeadIn(fd, &(tdms.segment[tdms.n_segments - 1]));
252 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocBigEndian) {
254 fprintf(stderr,
"tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
259 fprintf(stderr,
"tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
264 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocMetaData) {
265 TDMS_ReadMetaData(fd, &(tdms.segment[tdms.n_segments - 1]));
268 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocRawData) {
269 TDMS_ReadRawData(fd, &tdms, tdms.n_segments - 1, tdms.filesize);
275 fprintf(stdout,
"Number of segments: %u\n", tdms.n_segments);
288 if (segment > tdms.n_segments) {
289 fprintf(stderr,
"tdms2sdds: Error: segment selected does not exist\n");
294 for (i = 0; i < tdms.n_segments; i++) {
295 if ((segment != -1) && (segment != i)) {
298 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
300 rows = tdms.segment[i].raw_data.channel[j].n_values;
302 if (rows != tdms.segment[i].raw_data.channel[j].n_values) {
303 fprintf(stderr,
"tdms2sdds: Error: channels in the same TDMS segment have different lengths which is not allowed in SDDS\n");
309 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
311 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
312 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name,
"NI_ChannelName") == 0) {
314 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].value);
319 strcpy(buffer, tdms.segment[i].meta_data.object[j].path);
321 if (!edit_string(buffer,
"1Z/%g/ /_/%ga/a_a%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
322 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
326 if (!(isalpha(*buffer) || strchr(
".:", *buffer))) {
327 if (!edit_string(buffer,
"i/:/")) {
328 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
332 strcpy(tdms.segment[i].meta_data.object[j].path, buffer);
333 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
334 tdms.segment[i].raw_data.channel[k].name = tdms.segment[i].meta_data.object[j].path;
335 tdms.segment[i].raw_data.channel[k].datatype = tdms.segment[i].meta_data.object[j].raw_data_datatype;
337 if (((segment == -1) && (i == 0)) || (segment != -1)) {
338 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
339 if (timeDefined == 0) {
340 if (tdms.segment[i].xpart.samples > 0) {
341 if (tdms.segment[i].xpart.name == NULL) {
342 tdms.segment[i].xpart.name = malloc(5);
343 sprintf(tdms.segment[i].xpart.name,
"Time");
352 if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeBoolean) ||
353 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU8) ||
354 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU16)) {
359 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI8) ||
360 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI16)) {
365 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI32) {
370 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU32) {
375 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI64) {
380 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU64) {
385 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloat) ||
386 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
391 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloat) ||
392 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloatWithUnit) ||
393 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeTimeStamp)) {
398 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeString) {
399 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
401 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeVoid) {
402 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
404 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloat) {
405 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
407 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
408 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
410 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDAQmxRawData) {
411 fprintf(stderr,
"tdms2sdds: DAW mx ra data channels are not yet supported in tdms2sdds\n");
414 fprintf(stderr,
"tdms2sdds: unknown data type\n");
418 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
419 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name,
"name") == 0) {
422 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].name);
423 if (!edit_string(buffer,
"%g/ /_/%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
424 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
428 if (!(isalpha(*buffer) || strchr(
".:", *buffer))) {
429 if (!edit_string(buffer,
"i/:/")) {
430 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
434 strcpy(tdms.segment[i].meta_data.object[j].property[n].name, buffer);
441 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
442 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) ||
443 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16)) {
448 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8) ||
449 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16)) {
454 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) {
459 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) {
464 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) {
469 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) {
474 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
475 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit)) {
480 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
481 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
482 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
487 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
492 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
493 fprintf(stderr,
"tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
495 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
496 fprintf(stderr,
"tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
498 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
499 fprintf(stderr,
"tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
501 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
502 fprintf(stderr,
"tdms2sdds: DAW mx ra data parameters are not yet supported in tdms2sdds\n");
505 fprintf(stderr,
"tdms2sdds: unknown data type\n");
510 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
514 if (((segment == -1) && (i == 0)) || (segment != -1)) {
520 if (!SDDS_StartTable(&SDDSout, rows)) {
525 if ((tdms.segment[i].xpart.name != NULL) &&
526 (tdms.segment[i].xpart.samples > 0) &&
527 (tdms.segment[i].raw_data.n_channels > 0)) {
528 timeValue = tdms.segment[i].xpart.start_time + tdms.segment[i].xpart.start_offset;
529 for (j = 0; j < rows; j++) {
530 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, j, tdms.segment[i].xpart.name, (
double)timeValue, NULL)) {
534 timeValue += tdms.segment[i].xpart.increment;
537 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
538 if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI16) ||
539 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU16) ||
540 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI32) ||
541 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU32) ||
542 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI64) ||
543 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU64) ||
544 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloat) ||
545 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloatWithUnit) ||
546 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloat) ||
547 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloatWithUnit) ||
548 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeTimeStamp)) {
549 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, tdms.segment[i].raw_data.channel[j].values,
550 tdms.segment[i].raw_data.channel[j].n_values, tdms.segment[i].raw_data.channel[j].name)) {
554 }
else if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeBoolean) ||
555 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI8)) {
556 for (k = 0; k < rows; k++) {
558 tdms.segment[i].raw_data.channel[j].name,
559 (int16_t)(((int8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
564 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU8) {
565 for (k = 0; k < rows; k++) {
567 tdms.segment[i].raw_data.channel[j].name,
568 (uint16_t)(((uint8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
573 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeString) {
574 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
576 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeVoid) {
577 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
579 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloat) {
580 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
582 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloatWithUnit) {
583 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
585 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDAQmxRawData) {
586 fprintf(stderr,
"tdms2sdds: DAW mx ra data channels are not yet supported in tdms2sdds\n");
589 fprintf(stderr,
"tdms2sdds: unknown data type\n");
594 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
595 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
601 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16) ||
602 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16) ||
603 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) ||
604 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) ||
605 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) ||
606 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) ||
607 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
608 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit) ||
609 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
610 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
611 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
612 if (!
SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, tdms.segment[i].meta_data.object[j].property[n].name, tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
616 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
617 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8)) {
618 if (!
SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, tdms.segment[i].meta_data.object[j].property[n].name, (int16_t)(*(int8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
622 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) {
623 if (!
SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, tdms.segment[i].meta_data.object[j].property[n].name, (uint16_t)(*(uint8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
627 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
628 if (!
SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, tdms.segment[i].meta_data.object[j].property[n].name, tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
632 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
633 fprintf(stderr,
"tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
635 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
636 fprintf(stderr,
"tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
638 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
639 fprintf(stderr,
"tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
641 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
642 fprintf(stderr,
"tdms2sdds: DAW mx ra data parameters are not yet supported in tdms2sdds\n");
645 fprintf(stderr,
"tdms2sdds: unknown data type\n");
650 if (!SDDS_WriteTable(&SDDSout)) {
660 if (tdms.n_segments > 0) {
661 for (i = 0; i < tdms.n_segments; i++) {
662 if (tdms.segment[i].raw_data.n_channels > 0) {
663 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
664 if (tdms.segment[i].raw_data.channel[j].n_values > 0) {
665 free(tdms.segment[i].raw_data.channel[j].values);
668 free(tdms.segment[i].raw_data.channel);
670 if (tdms.segment[i].meta_data.n_objects > 0) {
671 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
672 if (tdms.segment[i].meta_data.object[j].path) {
673 free(tdms.segment[i].meta_data.object[j].path);
675 if (tdms.segment[i].meta_data.object[j].n_properties > 0) {
676 for (k = 0; k < tdms.segment[i].meta_data.object[j].n_properties; k++) {
677 if (tdms.segment[i].meta_data.object[j].property[k].name) {
678 for (ii = i + 1; ii < tdms.n_segments; ii++) {
679 for (jj = 0; jj < tdms.segment[ii].meta_data.n_objects; jj++) {
680 for (kk = 0; kk < tdms.segment[ii].meta_data.object[jj].n_properties; kk++) {
681 if (tdms.segment[i].meta_data.object[j].property[k].name == tdms.segment[ii].meta_data.object[jj].property[kk].name) {
682 tdms.segment[ii].meta_data.object[jj].property[kk].name = NULL;
683 tdms.segment[ii].meta_data.object[jj].property[kk].value = NULL;
688 free(tdms.segment[i].meta_data.object[j].property[k].name);
689 tdms.segment[i].meta_data.object[j].property[k].name = NULL;
691 if (tdms.segment[i].meta_data.object[j].property[k].value) {
692 free(tdms.segment[i].meta_data.object[j].property[k].value);
693 tdms.segment[i].meta_data.object[j].property[k].value = NULL;
696 free(tdms.segment[i].meta_data.object[j].property);
699 free(tdms.segment[i].meta_data.object);
713 fread(buffer, 1, 4, fd);
715 if (strcmp(buffer,
"TDSm") != 0) {
716 fprintf(stderr,
"tdms2sdds: Error: File does not start with TDSm\n");
719 fread(&(segment->lead_in.toc), 1, 4, fd);
720 fread(&(segment->lead_in.version), 1, 4, fd);
721 if (segment->lead_in.version == 4712) {
722 fprintf(stderr,
"tdms2sdds: Error: TDMS version 1.0 files unsupported\n");
725 if (segment->lead_in.version != 4713) {
726 fprintf(stderr,
"tdms2sdds: Error: Unknown TDMS version\n");
729 fread(&(segment->lead_in.next_segment_offset), 1, 8, fd);
730 fread(&(segment->lead_in.raw_data_offset), 1, 8, fd);
733void TDMS_ReadMetaData(FILE *fd,
TDMS_SEGMENT *segment) {
734 uint32_t uLong, i, j;
736 segment->xpart.name = NULL;
737 segment->xpart.unit = NULL;
738 segment->xpart.start_time = 0;
739 segment->xpart.start_offset = 0;
740 segment->xpart.increment = 0;
741 segment->xpart.samples = 0;
742 segment->xpart.time_pref = NULL;
743 segment->xpart.range = 0;
745 fread(&(segment->meta_data.n_objects), 1, 4, fd);
748 for (i = 0; i < segment->meta_data.n_objects; i++) {
749 fread(&uLong, 1, 4, fd);
750 segment->meta_data.object[i].path = malloc(
sizeof(
char) * (uLong + 1));
751 fread(segment->meta_data.object[i].path, 1, uLong, fd);
752 segment->meta_data.object[i].path[uLong] =
'\0';
753 fread(&(segment->meta_data.object[i].raw_data_index), 1, 4, fd);
754 if ((segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) && (segment->meta_data.object[i].raw_data_index != 0x00000000)) {
755 fread(&(segment->meta_data.object[i].raw_data_datatype), 1, 4, fd);
756 fread(&(segment->meta_data.object[i].raw_data_dimensions), 1, 4, fd);
757 fread(&(segment->meta_data.object[i].raw_data_count), 1, 8, fd);
758 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
759 fread(&(segment->meta_data.object[i].raw_data_total_size), 1, 8, fd);
762 fread(&(segment->meta_data.object[i].n_properties), 1, 4, fd);
764 for (j = 0; j < segment->meta_data.object[i].n_properties; j++) {
765 fread(&uLong, 1, 4, fd);
766 segment->meta_data.object[i].property[j].name = malloc(
sizeof(
char) * (uLong + 1));
767 fread(segment->meta_data.object[i].property[j].name, 1, uLong, fd);
768 segment->meta_data.object[i].property[j].name[uLong] =
'\0';
769 fread(&(segment->meta_data.object[i].property[j].datatype), 1, 4, fd);
770 if (segment->meta_data.object[i].property[j].datatype == tdsTypeString) {
771 fread(&uLong, 1, 4, fd);
772 segment->meta_data.object[i].property[j].value = malloc(
sizeof(
char) * (uLong + 1));
773 fread(segment->meta_data.object[i].property[j].value, 1, uLong, fd);
774 ((
char *)(segment->meta_data.object[i].property[j].value))[uLong] =
'\0';
776 TDMS_GetValue(fd, &(segment->meta_data.object[i].property[j].value), segment->meta_data.object[i].property[j].datatype);
779 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xname") == 0) {
780 segment->xpart.name = segment->meta_data.object[i].property[j].value;
782 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xunit_string") == 0) {
783 segment->xpart.unit = segment->meta_data.object[i].property[j].value;
785 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_time") == 0) {
786 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[j].value);
788 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_offset") == 0) {
789 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[j].value);
791 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_increment") == 0) {
792 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[j].value);
794 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_samples") == 0) {
795 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[j].value);
797 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_time_pref") == 0) {
798 segment->xpart.time_pref = segment->meta_data.object[i].property[j].value;
804void TDMS_ReadRawData(FILE *fd,
TDMS_FILE *tdms, uint32_t n_segment,
long filesize) {
805 uint32_t i, j, k, n, p, a;
806 uint32_t channel_size;
807 uint32_t chunk_size = 0;
808 uint32_t total_chunks;
816 segment->raw_data.n_channels = 0;
817 for (i = 0; i < segment->meta_data.n_objects; i++) {
818 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
819 if (segment->meta_data.object[i].raw_data_index == 0x00000000) {
824 while (prevFound == 0) {
827 fprintf(stderr,
"tdms2sdds: Error: unable to find %s in a previous segment.\n", segment->meta_data.object[i].path);
830 for (n = 0; n < (*tdms).segment[n_segment - a].meta_data.n_objects; n++) {
831 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].path, segment->meta_data.object[i].path) == 0) {
833 segment->meta_data.object[i].raw_data_datatype = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_datatype;
834 segment->meta_data.object[i].raw_data_dimensions = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_dimensions;
835 segment->meta_data.object[i].raw_data_count = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_count;
836 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
837 segment->meta_data.object[i].raw_data_total_size = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_total_size;
842 for (j = 0; j < (*tdms).segment[n_segment - a].meta_data.object[n].n_properties; j++) {
843 for (k = 0; k < segment->meta_data.object[i].n_properties; k++) {
844 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].property[j].name, segment->meta_data.object[i].property[k].name) == 0) {
848 p = segment->meta_data.object[i].n_properties;
849 segment->meta_data.object[i].n_properties++;
850 segment->meta_data.object[i].property = realloc(segment->meta_data.object[i].property,
sizeof(
TDMS_META_DATA_OBJECT_PROPERTY) * segment->meta_data.object[i].n_properties);
851 segment->meta_data.object[i].property[p].name = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].name;
852 segment->meta_data.object[i].property[p].datatype = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].datatype;
853 segment->meta_data.object[i].property[p].value = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].value;
855 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xname") == 0) {
856 segment->xpart.name = segment->meta_data.object[i].property[p].value;
858 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xunit_string") == 0) {
859 segment->xpart.unit = segment->meta_data.object[i].property[p].value;
861 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_time") == 0) {
862 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[p].value);
864 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_offset") == 0) {
865 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[p].value);
866 segment->xpart.start_offset += (*tdms).segment[n_segment - a].xpart.range;
869 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_increment") == 0) {
870 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[p].value);
872 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_samples") == 0) {
873 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[p].value);
875 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_time_pref") == 0) {
876 segment->xpart.time_pref = segment->meta_data.object[i].property[p].value;
884 segment->raw_data.n_channels++;
885 if (segment->meta_data.object[i].raw_data_dimensions != 1) {
886 fprintf(stderr,
"tdms2sdds: Error: raw data dimension is %d and should have been 1.\n", segment->meta_data.object[i].raw_data_dimensions);
889 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
890 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
891 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
892 channel_size = 1 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
893 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
894 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
895 channel_size = 2 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
896 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
897 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
898 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
899 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
900 channel_size = 4 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
901 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
902 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
903 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
904 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
905 channel_size = 8 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
906 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
907 channel_size = 16 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
908 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
909 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
911 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
912 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
914 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
915 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
917 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
918 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
920 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
921 fprintf(stderr,
"tdms2sdds: extended DAQ mx raw data channels are not yet supported in tdms2sdds\n");
924 fprintf(stderr,
"tdms2sdds: unknown data type\n");
927 chunk_size += channel_size;
931 if (segment->lead_in.next_segment_offset == -1) {
932 if (filesize == -1) {
933 fprintf(stderr,
"tdms2sdds: Error: cannot calculate file size because you are using stdin\n");
936 segment->lead_in.next_segment_offset = filesize;
938 total_chunks = segment->lead_in.next_segment_offset - segment->lead_in.raw_data_offset;
939 n_chunks = total_chunks / chunk_size;
943 if (segment->lead_in.toc & kTocInterleavedData) {
944 fprintf(stderr,
"tdms2sdds does not yet support interleaved data\n");
948 for (i = 0; i < segment->meta_data.n_objects; i++) {
949 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
950 segment->xpart.range = segment->xpart.increment * segment->meta_data.object[i].raw_data_count * n_chunks;
952 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
953 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
954 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
955 segment->raw_data.channel[j].values = malloc(1 * segment->meta_data.object[i].raw_data_count * n_chunks);
956 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
957 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
958 segment->raw_data.channel[j].values = malloc(2 * segment->meta_data.object[i].raw_data_count * n_chunks);
959 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
960 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
961 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
962 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
963 segment->raw_data.channel[j].values = malloc(4 * segment->meta_data.object[i].raw_data_count * n_chunks);
964 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
965 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
966 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
967 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
968 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
969 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
971 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
972 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
973 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
975 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
976 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
978 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
979 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
981 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
982 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
984 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
985 fprintf(stderr,
"tdms2sdds: extended DAQ mx raw data channels are not yet supported in tdms2sdds\n");
988 fprintf(stderr,
"tdms2sdds: unknown data type\n");
991 segment->raw_data.channel[j].n_values = segment->meta_data.object[i].raw_data_count * n_chunks;
995 for (chunk = 0; chunk < n_chunks; chunk++) {
997 for (i = 0; i < segment->meta_data.n_objects; i++) {
998 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
999 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean) {
1000 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1001 fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1003 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) {
1004 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1005 fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1007 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) {
1008 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1009 fread(&(((uint8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1011 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) {
1012 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1013 fread(&(((int16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1015 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16) {
1016 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1017 fread(&(((uint16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1019 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) {
1020 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1021 fread(&(((int32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1023 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) {
1024 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1025 fread(&(((uint32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1027 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) {
1028 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1029 fread(&(((int64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1031 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) {
1032 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1033 fread(&(((uint64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1035 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) || (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1036 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1037 fread(&(((
float *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1039 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) || (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1040 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1041 fread(&(((
double *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1043 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1044 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1045 fread(&uLLong, 1, 8, fd);
1046 fread(&LLong, 1, 8, fd);
1048 segment->raw_data.channel[j].values[k] = LLong + (uLLong * 5.42101086242752217e-20);
1050 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1051 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1053 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1054 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1056 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1057 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1059 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1060 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
1062 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1063 fprintf(stderr,
"tdms2sdds: extended DAQ mx raw data channels are not yet supported in tdms2sdds\n");
1066 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1076void TDMS_GetValue(FILE *fd,
void **value, int32_t datatype) {
1080 if (datatype == tdsTypeI8) {
1081 *value = malloc(
sizeof(int8_t));
1082 fread(((int8_t *)(*value)), 1, 1, fd);
1083 }
else if (datatype == tdsTypeU8) {
1084 *value = malloc(
sizeof(uint8_t));
1085 fread(((uint8_t *)(*value)), 1, 1, fd);
1086 }
else if (datatype == tdsTypeI16) {
1087 *value = malloc(
sizeof(int16_t));
1088 fread(((int16_t *)(*value)), 1, 2, fd);
1089 }
else if (datatype == tdsTypeU16) {
1090 *value = malloc(
sizeof(uint16_t));
1091 fread(((uint16_t *)(*value)), 1, 2, fd);
1092 }
else if (datatype == tdsTypeI32) {
1093 *value = malloc(
sizeof(int32_t));
1094 fread(((int32_t *)(*value)), 1, 4, fd);
1095 }
else if (datatype == tdsTypeU32) {
1096 *value = malloc(
sizeof(uint32_t));
1097 fread(((uint32_t *)(*value)), 1, 4, fd);
1098 }
else if (datatype == tdsTypeI64) {
1099 *value = malloc(
sizeof(int64_t));
1100 fread(((int64_t *)(*value)), 1, 8, fd);
1101 }
else if (datatype == tdsTypeU64) {
1102 *value = malloc(
sizeof(uint64_t));
1103 fread(((uint64_t *)(*value)), 1, 8, fd);
1104 }
else if ((datatype == tdsTypeSingleFloat) || (datatype == tdsTypeSingleFloatWithUnit)) {
1105 *value = malloc(
sizeof(
float));
1106 fread(((
float *)(*value)), 1, 4, fd);
1107 }
else if ((datatype == tdsTypeDoubleFloat) || (datatype == tdsTypeDoubleFloatWithUnit)) {
1108 *value = malloc(
sizeof(
double));
1109 fread(((
double *)(*value)), 1, 8, fd);
1110 }
else if (datatype == tdsTypeBoolean) {
1111 *value = malloc(
sizeof(int8_t));
1112 fread(((int8_t *)(*value)), 1, 1, fd);
1113 }
else if (datatype == tdsTypeTimeStamp) {
1114 *value = malloc(
sizeof(
double));
1115 fread(&uLLong, 1, 8, fd);
1116 fread(&LLong, 1, 8, fd);
1118 *((
double *)(*value)) = LLong + (uLLong * 5.42101086242752217e-20);
1119 }
else if (datatype == tdsTypeVoid) {
1120 fprintf(stderr,
"tdms2sdds: datatype Void is not yet supported in tdms2sdds\n");
1122 }
else if (datatype == tdsTypeExtendedFloat) {
1123 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloat is not yet supported in tdms2sdds\n");
1125 }
else if (datatype == tdsTypeExtendedFloatWithUnit) {
1126 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloatWithUnit is not yet supported in tdms2sdds\n");
1128 }
else if (datatype == tdsTypeDAQmxRawData) {
1129 fprintf(stderr,
"tdms2sdds: datatype DAQmxRawData is not yet supported in tdms2sdds\n");
1132 fprintf(stderr,
"tdms2sdds: unknown data type\n");
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data parameter within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
long fexists(const char *filename)
Checks if a file exists.
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)
void free_scanargs(SCANNED_ARG **scanned, int argc)