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);
769 fread(buffer, 1, 4, fd);
771 if (strcmp(buffer,
"TDSm") != 0) {
772 fprintf(stderr,
"tdms2sdds: Error: File does not start with TDSm\n");
775 fread(&(segment->lead_in.toc), 1, 4, fd);
776 fread(&(segment->lead_in.version), 1, 4, fd);
777 if (segment->lead_in.version == 4712) {
778 fprintf(stderr,
"tdms2sdds: Error: TDMS version 1.0 files unsupported\n");
781 if (segment->lead_in.version != 4713) {
782 fprintf(stderr,
"tdms2sdds: Error: Unknown TDMS version\n");
785 fread(&(segment->lead_in.next_segment_offset), 1, 8, fd);
786 fread(&(segment->lead_in.raw_data_offset), 1, 8, fd);
789void TDMS_ReadMetaData(FILE *fd,
TDMS_SEGMENT *segment) {
790 uint32_t uLong, i, j;
792 segment->xpart.name = NULL;
793 segment->xpart.unit = NULL;
794 segment->xpart.start_time = 0;
795 segment->xpart.start_offset = 0;
796 segment->xpart.increment = 0;
797 segment->xpart.samples = 0;
798 segment->xpart.time_pref = NULL;
799 segment->xpart.range = 0;
801 fread(&(segment->meta_data.n_objects), 1, 4, fd);
804 for (i = 0; i < segment->meta_data.n_objects; i++) {
805 fread(&uLong, 1, 4, fd);
806 segment->meta_data.object[i].path = malloc(
sizeof(
char) * (uLong + 1));
807 fread(segment->meta_data.object[i].path, 1, uLong, fd);
808 segment->meta_data.object[i].path[uLong] =
'\0';
809 fread(&(segment->meta_data.object[i].raw_data_index), 1, 4, fd);
810 if ((segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) && (segment->meta_data.object[i].raw_data_index != 0x00000000)) {
811 fread(&(segment->meta_data.object[i].raw_data_datatype), 1, 4, fd);
812 fread(&(segment->meta_data.object[i].raw_data_dimensions), 1, 4, fd);
813 fread(&(segment->meta_data.object[i].raw_data_count), 1, 8, fd);
814 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
815 fread(&(segment->meta_data.object[i].raw_data_total_size), 1, 8, fd);
818 fread(&(segment->meta_data.object[i].n_properties), 1, 4, fd);
820 for (j = 0; j < segment->meta_data.object[i].n_properties; j++) {
821 fread(&uLong, 1, 4, fd);
822 segment->meta_data.object[i].property[j].name = malloc(
sizeof(
char) * (uLong + 1));
823 fread(segment->meta_data.object[i].property[j].name, 1, uLong, fd);
824 segment->meta_data.object[i].property[j].name[uLong] =
'\0';
825 fread(&(segment->meta_data.object[i].property[j].datatype), 1, 4, fd);
826 if (segment->meta_data.object[i].property[j].datatype == tdsTypeString) {
827 fread(&uLong, 1, 4, fd);
828 segment->meta_data.object[i].property[j].value = malloc(
sizeof(
char) * (uLong + 1));
829 fread(segment->meta_data.object[i].property[j].value, 1, uLong, fd);
830 ((
char *)(segment->meta_data.object[i].property[j].value))[uLong] =
'\0';
832 TDMS_GetValue(fd, &(segment->meta_data.object[i].property[j].value), segment->meta_data.object[i].property[j].datatype);
835 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xname") == 0) {
836 segment->xpart.name = segment->meta_data.object[i].property[j].value;
838 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_xunit_string") == 0) {
839 segment->xpart.unit = segment->meta_data.object[i].property[j].value;
841 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_time") == 0) {
842 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[j].value);
844 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_start_offset") == 0) {
845 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[j].value);
847 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_increment") == 0) {
848 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[j].value);
850 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_samples") == 0) {
851 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[j].value);
853 if (strcmp(segment->meta_data.object[i].property[j].name,
"wf_time_pref") == 0) {
854 segment->xpart.time_pref = segment->meta_data.object[i].property[j].value;
860void TDMS_ReadRawData(FILE *fd,
TDMS_FILE *tdms, uint32_t n_segment,
long filesize) {
861 uint32_t i, j, k, n, p, a;
862 uint32_t channel_size;
863 uint32_t chunk_size = 0;
864 uint32_t total_chunks;
872 segment->raw_data.n_channels = 0;
873 for (i = 0; i < segment->meta_data.n_objects; i++) {
874 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
875 if (segment->meta_data.object[i].raw_data_index == 0x00000000) {
880 while (prevFound == 0) {
883 fprintf(stderr,
"tdms2sdds: Error: unable to find %s in a previous segment.\n", segment->meta_data.object[i].path);
886 for (n = 0; n < (*tdms).segment[n_segment - a].meta_data.n_objects; n++) {
887 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].path, segment->meta_data.object[i].path) == 0) {
889 segment->meta_data.object[i].raw_data_datatype = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_datatype;
890 segment->meta_data.object[i].raw_data_dimensions = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_dimensions;
891 segment->meta_data.object[i].raw_data_count = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_count;
892 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
893 segment->meta_data.object[i].raw_data_total_size = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_total_size;
898 for (j = 0; j < (*tdms).segment[n_segment - a].meta_data.object[n].n_properties; j++) {
899 for (k = 0; k < segment->meta_data.object[i].n_properties; k++) {
900 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].property[j].name, segment->meta_data.object[i].property[k].name) == 0) {
904 p = segment->meta_data.object[i].n_properties;
905 segment->meta_data.object[i].n_properties++;
906 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);
907 segment->meta_data.object[i].property[p].name = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].name;
908 segment->meta_data.object[i].property[p].datatype = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].datatype;
909 segment->meta_data.object[i].property[p].value = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].value;
911 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xname") == 0) {
912 segment->xpart.name = segment->meta_data.object[i].property[p].value;
914 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_xunit_string") == 0) {
915 segment->xpart.unit = segment->meta_data.object[i].property[p].value;
917 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_time") == 0) {
918 segment->xpart.start_time = *(
double *)(segment->meta_data.object[i].property[p].value);
920 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_start_offset") == 0) {
921 segment->xpart.start_offset = *(
double *)(segment->meta_data.object[i].property[p].value);
922 segment->xpart.start_offset += (*tdms).segment[n_segment - a].xpart.range;
925 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_increment") == 0) {
926 segment->xpart.increment = *(
double *)(segment->meta_data.object[i].property[p].value);
928 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_samples") == 0) {
929 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[p].value);
931 if (strcmp(segment->meta_data.object[i].property[p].name,
"wf_time_pref") == 0) {
932 segment->xpart.time_pref = segment->meta_data.object[i].property[p].value;
940 segment->raw_data.n_channels++;
941 if (segment->meta_data.object[i].raw_data_dimensions != 1) {
942 fprintf(stderr,
"tdms2sdds: Error: raw data dimension is %d and should have been 1.\n", segment->meta_data.object[i].raw_data_dimensions);
945 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
946 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
947 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
948 channel_size = 1 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
949 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
950 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
951 channel_size = 2 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
952 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
953 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
954 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
955 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
956 channel_size = 4 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
957 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
958 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
959 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
960 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
961 channel_size = 8 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
962 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
963 channel_size = 16 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
964 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
965 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
967 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
968 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
970 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
971 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
973 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
974 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
976 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
977 fprintf(stderr,
"tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
980 fprintf(stderr,
"tdms2sdds: unknown data type\n");
983 chunk_size += channel_size;
987 if (segment->lead_in.next_segment_offset == -1) {
988 if (filesize == -1) {
989 fprintf(stderr,
"tdms2sdds: Error: cannot calculate file size because you are using stdin\n");
992 segment->lead_in.next_segment_offset = filesize;
994 total_chunks = segment->lead_in.next_segment_offset - segment->lead_in.raw_data_offset;
995 n_chunks = total_chunks / chunk_size;
999 if (segment->lead_in.toc & kTocInterleavedData) {
1000 fprintf(stderr,
"tdms2sdds does not yet support interleaved data\n");
1004 for (i = 0; i < segment->meta_data.n_objects; i++) {
1005 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1006 segment->xpart.range = segment->xpart.increment * segment->meta_data.object[i].raw_data_count * n_chunks;
1008 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
1009 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
1010 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
1011 segment->raw_data.channel[j].values = malloc(1 * segment->meta_data.object[i].raw_data_count * n_chunks);
1012 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
1013 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
1014 segment->raw_data.channel[j].values = malloc(2 * segment->meta_data.object[i].raw_data_count * n_chunks);
1015 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
1016 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
1017 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1018 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1019 segment->raw_data.channel[j].values = malloc(4 * segment->meta_data.object[i].raw_data_count * n_chunks);
1020 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
1021 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
1022 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1023 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1024 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1025 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1027 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1028 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1029 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1031 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1032 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1034 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1035 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1037 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1038 fprintf(stderr,
"tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
1040 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1041 fprintf(stderr,
"tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
1044 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1047 segment->raw_data.channel[j].n_values = segment->meta_data.object[i].raw_data_count * n_chunks;
1051 for (chunk = 0; chunk < n_chunks; chunk++) {
1053 for (i = 0; i < segment->meta_data.n_objects; i++) {
1054 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1055 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean) {
1056 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1057 fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1059 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) {
1060 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1061 fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1063 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) {
1064 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1065 fread(&(((uint8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1067 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) {
1068 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1069 fread(&(((int16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1071 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16) {
1072 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1073 fread(&(((uint16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1075 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) {
1076 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1077 fread(&(((int32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1079 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) {
1080 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1081 fread(&(((uint32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1083 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) {
1084 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1085 fread(&(((int64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1087 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) {
1088 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1089 fread(&(((uint64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1091 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1092 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1093 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1094 fread(&(((
float *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1096 }
else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1097 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1098 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1099 fread(&(((
double *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1101 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1102 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1103 fread(&uLLong, 1, 8, fd);
1104 fread(&LLong, 1, 8, fd);
1106 segment->raw_data.channel[j].values[k] = LLong + (uLLong * 5.42101086242752217e-20);
1108 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1109 fprintf(stderr,
"tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1111 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1112 fprintf(stderr,
"tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1114 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1115 fprintf(stderr,
"tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1117 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1118 fprintf(stderr,
"tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
1120 }
else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1121 fprintf(stderr,
"tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
1124 fprintf(stderr,
"tdms2sdds: unknown data type\n");
1134void TDMS_GetValue(FILE *fd,
void **value, int32_t datatype) {
1138 if (datatype == tdsTypeI8) {
1139 *value = malloc(
sizeof(int8_t));
1140 fread(((int8_t *)(*value)), 1, 1, fd);
1141 }
else if (datatype == tdsTypeU8) {
1142 *value = malloc(
sizeof(uint8_t));
1143 fread(((uint8_t *)(*value)), 1, 1, fd);
1144 }
else if (datatype == tdsTypeI16) {
1145 *value = malloc(
sizeof(int16_t));
1146 fread(((int16_t *)(*value)), 1, 2, fd);
1147 }
else if (datatype == tdsTypeU16) {
1148 *value = malloc(
sizeof(uint16_t));
1149 fread(((uint16_t *)(*value)), 1, 2, fd);
1150 }
else if (datatype == tdsTypeI32) {
1151 *value = malloc(
sizeof(int32_t));
1152 fread(((int32_t *)(*value)), 1, 4, fd);
1153 }
else if (datatype == tdsTypeU32) {
1154 *value = malloc(
sizeof(uint32_t));
1155 fread(((uint32_t *)(*value)), 1, 4, fd);
1156 }
else if (datatype == tdsTypeI64) {
1157 *value = malloc(
sizeof(int64_t));
1158 fread(((int64_t *)(*value)), 1, 8, fd);
1159 }
else if (datatype == tdsTypeU64) {
1160 *value = malloc(
sizeof(uint64_t));
1161 fread(((uint64_t *)(*value)), 1, 8, fd);
1162 }
else if ((datatype == tdsTypeSingleFloat) || (datatype == tdsTypeSingleFloatWithUnit)) {
1163 *value = malloc(
sizeof(
float));
1164 fread(((
float *)(*value)), 1, 4, fd);
1165 }
else if ((datatype == tdsTypeDoubleFloat) || (datatype == tdsTypeDoubleFloatWithUnit)) {
1166 *value = malloc(
sizeof(
double));
1167 fread(((
double *)(*value)), 1, 8, fd);
1168 }
else if (datatype == tdsTypeBoolean) {
1169 *value = malloc(
sizeof(int8_t));
1170 fread(((int8_t *)(*value)), 1, 1, fd);
1171 }
else if (datatype == tdsTypeTimeStamp) {
1172 *value = malloc(
sizeof(
double));
1173 fread(&uLLong, 1, 8, fd);
1174 fread(&LLong, 1, 8, fd);
1176 *((
double *)(*value)) = LLong + (uLLong * 5.42101086242752217e-20);
1177 }
else if (datatype == tdsTypeVoid) {
1178 fprintf(stderr,
"tdms2sdds: datatype Void is not yet supported in tdms2sdds\n");
1180 }
else if (datatype == tdsTypeExtendedFloat) {
1181 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloat is not yet supported in tdms2sdds\n");
1183 }
else if (datatype == tdsTypeExtendedFloatWithUnit) {
1184 fprintf(stderr,
"tdms2sdds: datatype ExtendedFloatWithUnit is not yet supported in tdms2sdds\n");
1186 }
else if (datatype == tdsTypeDAQmxRawData) {
1187 fprintf(stderr,
"tdms2sdds: datatype DAQmxRawData is not yet supported in tdms2sdds\n");
1190 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)