53typedef signed __int16 int16_t;
54typedef signed __int8 int8_t;
55typedef unsigned __int16 uint16_t;
56typedef signed __int64 int64_t;
63 uint64_t next_segment_offset;
64 uint64_t raw_data_offset;
77 uint32_t raw_data_index;
78 int32_t raw_data_datatype;
79 uint32_t raw_data_dimensions;
80 uint64_t raw_data_count;
81 uint64_t raw_data_total_size;
82 uint32_t n_properties;
110 long double start_time;
111 long double start_offset;
112 long double increment;
135void TDMS_ReadRawData(FILE *fd,
TDMS_FILE *tdms, uint32_t n_segment,
long filesize);
136void TDMS_GetValue(FILE *fd,
void **value, int32_t datatype);
139#define kTocMetaData (1L << 1)
140#define kTocNewObjList (1L << 2)
141#define kTocRawData (1L << 3)
142#define kTocInterleavedData (1L << 5)
143#define kTocBigEndian (1L << 6)
144#define kTocDAQmxRawData (1L << 7)
147#define tdsTypeVoid 0x00000000
148#define tdsTypeI8 0x00000001
149#define tdsTypeI16 0x00000002
150#define tdsTypeI32 0x00000003
151#define tdsTypeI64 0x00000004
152#define tdsTypeU8 0x00000005
153#define tdsTypeU16 0x00000006
154#define tdsTypeU32 0x00000007
155#define tdsTypeU64 0x00000008
156#define tdsTypeSingleFloat 0x00000009
157#define tdsTypeDoubleFloat 0x0000000A
158#define tdsTypeExtendedFloat 0x0000000B
159#define tdsTypeSingleFloatWithUnit 0x00000019
160#define tdsTypeDoubleFloatWithUnit 0x0000001A
161#define tdsTypeExtendedFloatWithUnit 0x0000001B
162#define tdsTypeString 0x00000020
163#define tdsTypeBoolean 0x00000021
164#define tdsTypeTimeStamp 0x00000044
165#define tdsTypeDAQmxRawData 0xFFFFFFFF
177char *option[N_OPTIONS] = {
186 "Usage: tdms2sdds <inputFile> [<outputFile>]\n"
188 " [-ascii | -binary] \n"
189 " [-numOfSegments] \n"
190 " [-segment=<integer>]\n"
192 " -pipe=out SDDS toolkit pipe option.\n"
193 " -ascii Requests SDDS ASCII output. Default is binary.\n"
194 " -binary Requests SDDS BINARY output.\n"
195 " -numOfSegments Print out the number of TDMS segments.\n"
196 " -segment=<integer> Select a specific segment to convert.\n\n"
197 "Converts National Instruments TDMS files to SDDS.\n"
198 "Program by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
200int main(
int argc,
char **argv) {
202 char *input = NULL, *output = NULL;
204 SCANNED_ARG *scanned;
207 unsigned long pipeFlags = 0;
208 int i = 0, n, found, ii, jj, kk, segment = 0, querySegments = 0;
209 long double timeValue;
210 short timeDefined = 0;
214 uint64_t rows = 0, j = 0, k;
217 argc =
scanargs(&scanned, argc, argv);
219 fprintf(stderr,
"%s", USAGE);
220 return (EXIT_FAILURE);
223 for (iArg = 1; iArg < argc; iArg++) {
224 if (scanned[iArg].arg_type == OPTION) {
225 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
233 if (scanned[iArg].n_items < 2) {
234 fprintf(stderr,
"Error (%s): invalid -segment syntax\n", argv[0]);
235 return (EXIT_FAILURE);
237 if (sscanf(scanned[iArg].list[1],
"%d", &segment) != 1 || segment <= 0) {
238 fprintf(stderr,
"Error (%s): invalid -segment syntax or value\n", argv[0]);
239 return (EXIT_FAILURE);
242 case SET_NUMOFSEGMENTS:
246 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
247 fprintf(stderr,
"invalid -pipe syntax\n");
248 return (EXIT_FAILURE);
252 fprintf(stderr,
"invalid option seen\n");
253 fprintf(stderr,
"%s", USAGE);
254 return (EXIT_FAILURE);
258 input = scanned[iArg].list[0];
260 output = scanned[iArg].list[0];
262 fprintf(stderr,
"too many filenames\n");
263 fprintf(stderr,
"%s", USAGE);
264 return (EXIT_FAILURE);
268 if (!querySegments) {
274 fprintf(stderr,
"input file not found\n");
275 return (EXIT_FAILURE);
277 if (!(fd = fopen(input,
"rb"))) {
278 fprintf(stderr,
"problem opening input file\n");
279 return (EXIT_FAILURE);
282 fprintf(stderr,
"tdms2sdds cannot -pipe=in tdms files\n");
283 return (EXIT_FAILURE);
286 fseek(fd, 0L, SEEK_END);
287 tdms.filesize = ftell(fd);
288 fseek(fd, 0L, SEEK_SET);
291 while (ftell(fd) < tdms.filesize) {
293 if (tdms.n_segments == 1) {
296 tdms.segment = realloc(tdms.segment,
sizeof(
TDMS_SEGMENT) * tdms.n_segments);
299 TDMS_ReadLeadIn(fd, &(tdms.segment[tdms.n_segments - 1]));
300 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocBigEndian) {
302 fprintf(stderr,
"tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
303 return (EXIT_FAILURE);
307 fprintf(stderr,
"tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
308 return (EXIT_FAILURE);
312 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocMetaData) {
313 TDMS_ReadMetaData(fd, &(tdms.segment[tdms.n_segments - 1]));
316 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocRawData) {
317 TDMS_ReadRawData(fd, &tdms, tdms.n_segments - 1, tdms.filesize);
323 fprintf(stdout,
"Number of segments: %u\n", tdms.n_segments);
324 return (EXIT_SUCCESS);
328 return (EXIT_FAILURE);
333 return (EXIT_FAILURE);
336 if (segment > tdms.n_segments) {
337 fprintf(stderr,
"tdms2sdds: Error: segment selected does not exist\n");
338 return (EXIT_FAILURE);
342 for (i = 0; i < tdms.n_segments; i++) {
343 if ((segment != -1) && (segment != i)) {
346 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
348 rows = tdms.segment[i].raw_data.channel[j].n_values;
350 if (rows != tdms.segment[i].raw_data.channel[j].n_values) {
351 fprintf(stderr,
"tdms2sdds: Error: channels in the same TDMS segment have different lengths which is not allowed in SDDS\n");
352 return (EXIT_FAILURE);
357 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
359 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
360 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name,
"NI_ChannelName") == 0) {
362 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].value);
367 strcpy(buffer, tdms.segment[i].meta_data.object[j].path);
369 if (!
edit_string(buffer,
"1Z/%g/ /_/%ga/a_a%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
370 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
371 return (EXIT_FAILURE);
374 if (!(isalpha(*buffer) || strchr(
".:", *buffer))) {
376 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
377 return (EXIT_FAILURE);
380 strcpy(tdms.segment[i].meta_data.object[j].path, buffer);
381 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
382 tdms.segment[i].raw_data.channel[k].name = tdms.segment[i].meta_data.object[j].path;
383 tdms.segment[i].raw_data.channel[k].datatype = tdms.segment[i].meta_data.object[j].raw_data_datatype;
385 if (((segment == -1) && (i == 0)) || (segment != -1)) {
386 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
387 if (timeDefined == 0) {
388 if (tdms.segment[i].xpart.samples > 0) {
389 if (tdms.segment[i].xpart.name == NULL) {
390 tdms.segment[i].xpart.name = malloc(5);
391 sprintf(tdms.segment[i].xpart.name,
"Time");
395 return (EXIT_FAILURE);
400 if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeBoolean) ||
401 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU8) ||
402 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU16)) {
405 return (EXIT_FAILURE);
407 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI8) ||
408 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI16)) {
411 return (EXIT_FAILURE);
413 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI32) {
416 return (EXIT_FAILURE);
418 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU32) {
421 return (EXIT_FAILURE);
423 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI64) {
426 return (EXIT_FAILURE);
428 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU64) {
431 return (EXIT_FAILURE);
433 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloat) ||
434 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
437 return (EXIT_FAILURE);
439 }
else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloat) ||
440 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloatWithUnit) ||
441 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeTimeStamp)) {
444 return (EXIT_FAILURE);
446 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeString) {
447 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
448 return (EXIT_FAILURE);
449 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeVoid) {
450 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
451 return (EXIT_FAILURE);
452 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloat) {
453 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
454 return (EXIT_FAILURE);
455 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
456 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
457 return (EXIT_FAILURE);
458 }
else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDAQmxRawData) {
459 fprintf(stderr,
"tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
460 return (EXIT_FAILURE);
462 fprintf(stderr,
"tdms2sdds: unknown data type\n");
463 return (EXIT_FAILURE);
466 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
467 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name,
"name") == 0) {
470 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].name);
471 if (!
edit_string(buffer,
"%g/ /_/%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
472 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
473 return (EXIT_FAILURE);
476 if (!(isalpha(*buffer) || strchr(
".:", *buffer))) {
478 fprintf(stderr,
"tdms2sdds: Error: problem editing column label\n");
479 return (EXIT_FAILURE);
482 strcpy(tdms.segment[i].meta_data.object[j].property[n].name, buffer);
489 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
490 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) ||
491 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16)) {
494 return (EXIT_FAILURE);
496 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8) ||
497 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16)) {
500 return (EXIT_FAILURE);
502 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) {
505 return (EXIT_FAILURE);
507 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) {
510 return (EXIT_FAILURE);
512 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) {
515 return (EXIT_FAILURE);
517 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) {
520 return (EXIT_FAILURE);
522 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
523 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit)) {
526 return (EXIT_FAILURE);
528 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
529 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
530 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
533 return (EXIT_FAILURE);
535 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
538 return (EXIT_FAILURE);
540 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
541 fprintf(stderr,
"tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
542 return (EXIT_FAILURE);
543 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
544 fprintf(stderr,
"tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
545 return (EXIT_FAILURE);
546 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
547 fprintf(stderr,
"tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
548 return (EXIT_FAILURE);
549 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
550 fprintf(stderr,
"tdms2sdds: DAQmx raw data parameters are not yet supported in tdms2sdds\n");
551 return (EXIT_FAILURE);
553 fprintf(stderr,
"tdms2sdds: unknown data type\n");
554 return (EXIT_FAILURE);
558 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
562 if (((segment == -1) && (i == 0)) || (segment != -1)) {
565 return (EXIT_FAILURE);
568 if (!SDDS_StartTable(&SDDSout, rows)) {
570 return (EXIT_FAILURE);
573 if ((tdms.segment[i].xpart.name != NULL) &&
574 (tdms.segment[i].xpart.samples > 0) &&
575 (tdms.segment[i].raw_data.n_channels > 0)) {
576 timeValue = tdms.segment[i].xpart.start_time + tdms.segment[i].xpart.start_offset;
577 for (j = 0; j < rows; j++) {
578 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, j, tdms.segment[i].xpart.name, (
double)timeValue, NULL)) {
580 return (EXIT_FAILURE);
582 timeValue += tdms.segment[i].xpart.increment;
585 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
586 if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI16) ||
587 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU16) ||
588 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI32) ||
589 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU32) ||
590 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI64) ||
591 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU64) ||
592 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloat) ||
593 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloatWithUnit) ||
594 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloat) ||
595 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloatWithUnit) ||
596 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeTimeStamp)) {
597 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, tdms.segment[i].raw_data.channel[j].values,
598 tdms.segment[i].raw_data.channel[j].n_values, tdms.segment[i].raw_data.channel[j].name)) {
600 return (EXIT_FAILURE);
602 }
else if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeBoolean) ||
603 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI8)) {
604 for (k = 0; k < rows; k++) {
606 tdms.segment[i].raw_data.channel[j].name,
607 (int16_t)(((int8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
609 return (EXIT_FAILURE);
612 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU8) {
613 for (k = 0; k < rows; k++) {
615 tdms.segment[i].raw_data.channel[j].name,
616 (uint16_t)(((uint8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
618 return (EXIT_FAILURE);
621 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeString) {
622 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
623 return (EXIT_FAILURE);
624 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeVoid) {
625 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
626 return (EXIT_FAILURE);
627 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloat) {
628 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
629 return (EXIT_FAILURE);
630 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloatWithUnit) {
631 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
632 return (EXIT_FAILURE);
633 }
else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDAQmxRawData) {
634 fprintf(stderr,
"tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
635 return (EXIT_FAILURE);
637 fprintf(stderr,
"tdms2sdds: unknown data type\n");
638 return (EXIT_FAILURE);
642 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
643 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
649 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16) ||
650 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16) ||
651 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) ||
652 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) ||
653 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) ||
654 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) ||
655 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
656 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit) ||
657 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
658 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
659 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
661 tdms.segment[i].meta_data.object[j].property[n].name,
662 tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
664 return (EXIT_FAILURE);
666 }
else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
667 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8)) {
669 tdms.segment[i].meta_data.object[j].property[n].name,
670 (int16_t)(*(int8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
672 return (EXIT_FAILURE);
674 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) {
676 tdms.segment[i].meta_data.object[j].property[n].name,
677 (uint16_t)(*(uint8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
679 return (EXIT_FAILURE);
681 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
683 tdms.segment[i].meta_data.object[j].property[n].name,
684 tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
686 return (EXIT_FAILURE);
688 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
689 fprintf(stderr,
"tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
690 return (EXIT_FAILURE);
691 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
692 fprintf(stderr,
"tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
693 return (EXIT_FAILURE);
694 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
695 fprintf(stderr,
"tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
696 return (EXIT_FAILURE);
697 }
else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
698 fprintf(stderr,
"tdms2sdds: DAQmx raw data parameters are not yet supported in tdms2sdds\n");
699 return (EXIT_FAILURE);
701 fprintf(stderr,
"tdms2sdds: unknown data type\n");
702 return (EXIT_FAILURE);
706 if (!SDDS_WriteTable(&SDDSout)) {
708 return (EXIT_FAILURE);
713 return (EXIT_FAILURE);
716 if (tdms.n_segments > 0) {
717 for (i = 0; i < tdms.n_segments; i++) {
718 if (tdms.segment[i].raw_data.n_channels > 0) {
719 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
720 if (tdms.segment[i].raw_data.channel[j].n_values > 0) {
721 free(tdms.segment[i].raw_data.channel[j].values);
724 free(tdms.segment[i].raw_data.channel);
726 if (tdms.segment[i].meta_data.n_objects > 0) {
727 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
728 if (tdms.segment[i].meta_data.object[j].path) {
729 free(tdms.segment[i].meta_data.object[j].path);
731 if (tdms.segment[i].meta_data.object[j].n_properties > 0) {
732 for (k = 0; k < tdms.segment[i].meta_data.object[j].n_properties; k++) {
733 if (tdms.segment[i].meta_data.object[j].property[k].name) {
734 for (ii = i + 1; ii < tdms.n_segments; ii++) {
735 for (jj = 0; jj < tdms.segment[ii].meta_data.n_objects; jj++) {
736 for (kk = 0; kk < tdms.segment[ii].meta_data.object[jj].n_properties; kk++) {
737 if (tdms.segment[i].meta_data.object[j].property[k].name == tdms.segment[ii].meta_data.object[jj].property[kk].name) {
738 tdms.segment[ii].meta_data.object[jj].property[kk].name = NULL;
739 tdms.segment[ii].meta_data.object[jj].property[kk].value = NULL;
744 free(tdms.segment[i].meta_data.object[j].property[k].name);
745 tdms.segment[i].meta_data.object[j].property[k].name = NULL;
747 if (tdms.segment[i].meta_data.object[j].property[k].value) {
748 free(tdms.segment[i].meta_data.object[j].property[k].value);
749 tdms.segment[i].meta_data.object[j].property[k].value = NULL;
752 free(tdms.segment[i].meta_data.object[j].property);
755 free(tdms.segment[i].meta_data.object);
763 return (EXIT_SUCCESS);
770 bytesRead = fread(buffer, 1, 4, fd);
773 if (strcmp(buffer,
"TDSm") != 0) {
774 fprintf(stderr,
"tdms2sdds: Error: File does not start with TDSm\n");
777 bytesRead = fread(&(segment->lead_in.toc), 1, 4, fd);
779 bytesRead = fread(&(segment->lead_in.version), 1, 4, fd);
781 if (segment->lead_in.version == 4712) {
782 fprintf(stderr,
"tdms2sdds: Error: TDMS version 1.0 files unsupported\n");
785 if (segment->lead_in.version != 4713) {
786 fprintf(stderr,
"tdms2sdds: Error: Unknown TDMS version\n");
789 bytesRead = fread(&(segment->lead_in.next_segment_offset), 1, 8, fd);
791 bytesRead = fread(&(segment->lead_in.raw_data_offset), 1, 8, fd);
795void TDMS_ReadMetaData(FILE *fd,
TDMS_SEGMENT *segment) {
796 uint32_t uLong, i, j;
799 segment->xpart.name = NULL;
800 segment->xpart.unit = NULL;
801 segment->xpart.start_time = 0;
802 segment->xpart.start_offset = 0;
803 segment->xpart.increment = 0;
804 segment->xpart.samples = 0;
805 segment->xpart.time_pref = NULL;
806 segment->xpart.range = 0;
808 bytesRead = fread(&(segment->meta_data.n_objects), 1, 4, fd);
812 for (i = 0; i < segment->meta_data.n_objects; i++) {
813 bytesRead = fread(&uLong, 1, 4, fd);
815 segment->meta_data.object[i].path = malloc(
sizeof(
char) * (uLong + 1));
816 bytesRead = fread(segment->meta_data.object[i].path, 1, uLong, fd);
818 segment->meta_data.object[i].path[uLong] =
'\0';
819 bytesRead = fread(&(segment->meta_data.object[i].raw_data_index), 1, 4, fd);
821 if ((segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) && (segment->meta_data.object[i].raw_data_index != 0x00000000)) {
822 bytesRead = fread(&(segment->meta_data.object[i].raw_data_datatype), 1, 4, fd);
824 bytesRead = fread(&(segment->meta_data.object[i].raw_data_dimensions), 1, 4, fd);
826 bytesRead = fread(&(segment->meta_data.object[i].raw_data_count), 1, 8, fd);
828 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
829 bytesRead = fread(&(segment->meta_data.object[i].raw_data_total_size), 1, 8, fd);
833 bytesRead = fread(&(segment->meta_data.object[i].n_properties), 1, 4, fd);
836 for (j = 0; j < segment->meta_data.object[i].n_properties; j++) {
837 bytesRead = fread(&uLong, 1, 4, fd);
839 segment->meta_data.object[i].property[j].name = malloc(
sizeof(
char) * (uLong + 1));
840 bytesRead = fread(segment->meta_data.object[i].property[j].name, 1, uLong, fd);
842 segment->meta_data.object[i].property[j].name[uLong] =
'\0';
843 bytesRead = fread(&(segment->meta_data.object[i].property[j].datatype), 1, 4, fd);
845 if (segment->meta_data.object[i].property[j].datatype == tdsTypeString) {
846 bytesRead = fread(&uLong, 1, 4, fd);
848 segment->meta_data.object[i].property[j].value = malloc(
sizeof(
char) * (uLong + 1));
849 bytesRead = fread(segment->meta_data.object[i].property[j].value, 1, uLong, fd);
851 ((
char *)(segment->meta_data.object[i].property[j].value))[uLong] =
'\0';
853 TDMS_GetValue(fd, &(segment->meta_data.object[i].property[j].value), segment->meta_data.object[i].property[j].datatype);
856 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xname") == 0) {
857 segment->xpart.name = segment->meta_data.object[i].property[j].value;
859 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xunit_string") == 0) {
860 segment->xpart.unit = segment->meta_data.object[i].property[j].value;
862 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_time") == 0) {
863 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[j].value);
865 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_offset") == 0) {
866 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[j].value);
868 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_increment") == 0) {
869 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[j].value);
871 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_samples") == 0) {
872 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[j].value);
874 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_time_pref") == 0) {
875 segment->xpart.time_pref = segment->meta_data.object[i].property[j].value;
882void TDMS_ReadRawData(FILE *fd,
TDMS_FILE *tdms, uint32_t n_segment,
long filesize) {
883 uint32_t i, j, k, n, p, a;
884 uint32_t channel_size;
885 uint32_t chunk_size = 0;
886 uint32_t total_chunks;
895 segment->raw_data.n_channels = 0;
896 for (i = 0; i < segment->meta_data.n_objects; i++) {
897 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
898 if (segment->meta_data.object[i].raw_data_index == 0x00000000) {
903 while (prevFound == 0) {
906 fprintf(stderr,
"tdms2sdds: Error: unable to find %s in a previous segment.\n", segment->meta_data.object[i].path);
909 for (n = 0; n < (*tdms).segment[n_segment - a].meta_data.n_objects; n++) {
910 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].path, segment->meta_data.object[i].path) == 0) {
912 segment->meta_data.object[i].raw_data_datatype = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_datatype;
913 segment->meta_data.object[i].raw_data_dimensions = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_dimensions;
914 segment->meta_data.object[i].raw_data_count = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_count;
915 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
916 segment->meta_data.object[i].raw_data_total_size = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_total_size;
921 for (j = 0; j < (*tdms).segment[n_segment - a].meta_data.object[n].n_properties; j++) {
922 for (k = 0; k < segment->meta_data.object[i].n_properties; k++) {
923 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].property[j].name, segment->meta_data.object[i].property[k].name) == 0) {
927 p = segment->meta_data.object[i].n_properties;
928 segment->meta_data.object[i].n_properties++;
929 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);
930 segment->meta_data.object[i].property[p].name = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].name;
931 segment->meta_data.object[i].property[p].datatype = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].datatype;
932 segment->meta_data.object[i].property[p].value = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].value;
934 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xname") == 0) {
935 segment->xpart.name = segment->meta_data.object[i].property[p].value;
937 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xunit_string") == 0) {
938 segment->xpart.unit = segment->meta_data.object[i].property[p].value;
940 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_time") == 0) {
941 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[p].value);
943 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_offset") == 0) {
944 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[p].value);
945 segment->xpart.start_offset += (*tdms).segment[n_segment - a].xpart.range;
948 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_increment") == 0) {
949 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[p].value);
951 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_samples") == 0) {
952 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[p].value);
954 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_time_pref") == 0) {
955 segment->xpart.time_pref = segment->meta_data.object[i].property[p].value;
963 segment->raw_data.n_channels++;
964 if (segment->meta_data.object[i].raw_data_dimensions != 1) {
965 fprintf(stderr,
"tdms2sdds: Error: raw data dimension is %d and should have been 1.\n", segment->meta_data.object[i].raw_data_dimensions);
968 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
969 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
970 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
971 channel_size = 1 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
972 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
973 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
974 channel_size = 2 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
975 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
976 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
977 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
978 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
979 channel_size = 4 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
980 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
981 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
982 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
983 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
984 channel_size = 8 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
985 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
986 channel_size = 16 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
987 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
988 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
990 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
991 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
993 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
994 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
996 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
997 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
999 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1000 fprintf(stderr,
"tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
1003 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1006 chunk_size += channel_size;
1010 if (segment->lead_in.next_segment_offset == -1) {
1011 if (filesize == -1) {
1012 fprintf(stderr,
"tdms2sdds: Error: cannot calculate file size because you are using stdin\n");
1015 segment->lead_in.next_segment_offset = filesize;
1017 total_chunks = segment->lead_in.next_segment_offset - segment->lead_in.raw_data_offset;
1018 n_chunks = total_chunks / chunk_size;
1022 if (segment->lead_in.toc & kTocInterleavedData) {
1023 fprintf(stderr,
"tdms2sdds does not yet support interleaved data\n");
1027 for (i = 0; i < segment->meta_data.n_objects; i++) {
1028 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1029 segment->xpart.range = segment->xpart.increment * segment->meta_data.object[i].raw_data_count * n_chunks;
1031 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
1032 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
1033 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
1034 segment->raw_data.channel[j].values = malloc(1 * segment->meta_data.object[i].raw_data_count * n_chunks);
1035 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
1036 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
1037 segment->raw_data.channel[j].values = malloc(2 * segment->meta_data.object[i].raw_data_count * n_chunks);
1038 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
1039 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
1040 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1041 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1042 segment->raw_data.channel[j].values = malloc(4 * segment->meta_data.object[i].raw_data_count * n_chunks);
1043 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
1044 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
1045 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1046 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1047 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1048 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1050 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1051 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1052 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1054 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1055 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1057 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1058 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1060 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1061 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
1063 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1064 fprintf(stderr,
"tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
1067 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1070 segment->raw_data.channel[j].n_values = segment->meta_data.object[i].raw_data_count * n_chunks;
1074 for (chunk = 0; chunk < n_chunks; chunk++) {
1076 for (i = 0; i < segment->meta_data.n_objects; i++) {
1077 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1078 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean) {
1079 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1080 bytesRead = fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1082 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) {
1083 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1084 bytesRead = fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1086 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) {
1087 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1088 bytesRead = fread(&(((uint8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1090 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) {
1091 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1092 bytesRead = fread(&(((int16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1094 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16) {
1095 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1096 bytesRead = fread(&(((uint16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1098 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) {
1099 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1100 bytesRead = fread(&(((int32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1102 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) {
1103 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1104 bytesRead = fread(&(((uint32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1106 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) {
1107 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1108 bytesRead = fread(&(((int64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1110 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) {
1111 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1112 bytesRead = fread(&(((uint64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1114 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1115 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1116 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1117 bytesRead = fread(&(((
float *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1119 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1120 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1121 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1122 bytesRead = fread(&(((
double *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1124 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1125 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1126 bytesRead = fread(&uLLong, 1, 8, fd);
1127 bytesRead = fread(&LLong, 1, 8, fd);
1129 segment->raw_data.channel[j].values[k] = LLong + (uLLong * 5.42101086242752217e-20);
1131 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1132 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1134 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1135 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1137 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1138 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1140 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1141 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
1143 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1144 fprintf(stderr,
"tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
1147 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1158void TDMS_GetValue(FILE *fd,
void **value, int32_t datatype) {
1163 if (datatype == tdsTypeI8) {
1164 *value = malloc(
sizeof(int8_t));
1165 bytesRead = fread(((int8_t *)(*value)), 1, 1, fd);
1166 }
else if (datatype == tdsTypeU8) {
1167 *value = malloc(
sizeof(uint8_t));
1168 bytesRead = fread(((uint8_t *)(*value)), 1, 1, fd);
1169 }
else if (datatype == tdsTypeI16) {
1170 *value = malloc(
sizeof(int16_t));
1171 bytesRead = fread(((int16_t *)(*value)), 1, 2, fd);
1172 }
else if (datatype == tdsTypeU16) {
1173 *value = malloc(
sizeof(uint16_t));
1174 bytesRead = fread(((uint16_t *)(*value)), 1, 2, fd);
1175 }
else if (datatype == tdsTypeI32) {
1176 *value = malloc(
sizeof(int32_t));
1177 bytesRead = fread(((int32_t *)(*value)), 1, 4, fd);
1178 }
else if (datatype == tdsTypeU32) {
1179 *value = malloc(
sizeof(uint32_t));
1180 bytesRead = fread(((uint32_t *)(*value)), 1, 4, fd);
1181 }
else if (datatype == tdsTypeI64) {
1182 *value = malloc(
sizeof(int64_t));
1183 bytesRead = fread(((int64_t *)(*value)), 1, 8, fd);
1184 }
else if (datatype == tdsTypeU64) {
1185 *value = malloc(
sizeof(uint64_t));
1186 bytesRead = fread(((uint64_t *)(*value)), 1, 8, fd);
1187 }
else if ((datatype == tdsTypeSingleFloat) || (datatype == tdsTypeSingleFloatWithUnit)) {
1188 *value = malloc(
sizeof(
float));
1189 bytesRead = fread(((
float *)(*value)), 1, 4, fd);
1190 }
else if ((datatype == tdsTypeDoubleFloat) || (datatype == tdsTypeDoubleFloatWithUnit)) {
1191 *value = malloc(
sizeof(
double));
1192 bytesRead = fread(((
double *)(*value)), 1, 8, fd);
1193 }
else if (datatype == tdsTypeBoolean) {
1194 *value = malloc(
sizeof(int8_t));
1195 bytesRead = fread(((int8_t *)(*value)), 1, 1, fd);
1196 }
else if (datatype == tdsTypeTimeStamp) {
1197 *value = malloc(
sizeof(
double));
1198 bytesRead = fread(&uLLong, 1, 8, fd);
1199 bytesRead = fread(&LLong, 1, 8, fd);
1201 *((
double *)(*value)) = LLong + (uLLong * 5.42101086242752217e-20);
1202 }
else if (datatype == tdsTypeVoid) {
1203 fprintf(stderr,
"tdms2sdds: datatype Void is not yet supported in tdms2sdds\n");
1205 }
else if (datatype == tdsTypeExtendedFloat) {
1206 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloat is not yet supported in tdms2sdds\n");
1208 }
else if (datatype == tdsTypeExtendedFloatWithUnit) {
1209 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloatWithUnit is not yet supported in tdms2sdds\n");
1211 }
else if (datatype == tdsTypeDAQmxRawData) {
1212 fprintf(stderr,
"tdms2sdds: datatype DAQmxRawData is not yet supported in tdms2sdds\n");
1215 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.
long edit_string(char *text, char *edit)
Edits the provided text based on the specified edit commands.
#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)