/* This example c code will convert a SNG or ELS binary file into a text file.       */
/* Each line is one record, and the columns represent the different Objects.         */
/* To compile under linux: gcc -O3 -lm -Wall -W -o SNG_example_c.exe SNG_example_c.c */

#include <stdio.h>
#include <string.h>

void SwapUnsignedInt16( unsigned short int *a );
void SwapDouble( double *a );

/* Add routines that will swap bytes in case we need to correct for Endianity */
void SwapUnsignedInt16( unsigned short int *a ){
    unsigned char   b[2], c[2];
    memcpy( b, a, 2);
    c[0] = b[1];
    c[1] = b[0];
    memcpy( a, c, 2);
}
void SwapDouble( double *a ){
    unsigned char   b[8], c[8];
    memcpy( b, a, 8);
    c[0] = b[7];
    c[1] = b[6];
    c[2] = b[5];
    c[3] = b[4];
    c[4] = b[3];
    c[5] = b[2];
    c[6] = b[1];
    c[7] = b[0];
    memcpy( a, c, 8);
}

/* Main Routine */
int main(void) {
/* Declarations for Endiatity checking */
	unsigned char EndianTest[2] = { 1, 0 };
	short int  iLE; /* iLE = Is Little Endian */
/* Declarations for file reading and file sizes */
    FILE          *fi, *fo;
    unsigned long rec, fileLen, recLen;
    int           bytes_per_rec;
/* Declarations for objects in FMT file */
    unsigned char       ui8;
    unsigned short int  ui16;
    double	d;
    int		j; /* Just needed for the loop for the DATA object */

/* Open Binary for reading - put filename here */
	fi = fopen( "SNG_200528400_U3.DAT", "rb" );
/* SNG and ELS have 40 bytes per record, so get number of records */
	bytes_per_rec = 40; 
/* Open output files for writing */
	fo = fopen( "output_c.txt", "wt" );


/* Get file length in bytes, then number of records */
	fseek(fi, 0L, SEEK_END);
	fileLen = ftell(fi);
	fseek(fi, 0L, SEEK_SET); /* return to start of file */
	recLen = fileLen/bytes_per_rec;

/* Check what endianity this computer is */
	iLE = *(short *) EndianTest;   /* 1 = little endian, 256 = big endian */

/* Read each record in the file */
	for (rec = 0; rec < recLen; rec++) { 
	/* B_CYCLE_NUMBER */
		fread(&ui16, 2, 1, fi);                   /* read value from file          */
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); /* Convert Endianity if required */
		fprintf(fo, "%u\t", (unsigned int)ui16);  /* Write out text to file        */
	/* A_CYCLE_NUMBER */
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); 
		fprintf(fo, "%u\t", (unsigned int)ui16); 
	/* TIME */
		fread(&d   , 8, 1, fi);
		if (iLE == 1) SwapDouble( &d ); 
		fprintf(fo, "%f\t", d   );
	/* TELEMETRY_MODE */
		fread(&ui8, 1, 1, fi);
		/* 1-byte has no endianity issues */
		fprintf(fo, "%u\t", (unsigned int)ui8);
	/* SPARE if SNG, COLLAPSE_FLAG if ELS */	
		fread(&ui8, 1, 1, fi);
		/* 1-byte has no endianity issues */
		fprintf(fo, "%u\t", (unsigned int)ui8);
	/* OFFSET_TIME */
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 );
		fprintf(fo, "%u\t", (unsigned int)ui16); 
	/* FIRST_ENERGY_STEP */	
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); 
		fprintf(fo, "%u\t", (unsigned int)ui16); 
	/* LAST_ENERGY_STEP */	
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); 
		fprintf(fo, "%u\t", (unsigned int)ui16); 
	/* FIRST_AZIMUTH_VALUE */
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); 
		fprintf(fo, "%u\t", (unsigned int)ui16);
	/* LAST_AZIMUTH_VALUE */
		fread(&ui16, 2, 1, fi);
		if (iLE == 1) SwapUnsignedInt16( &ui16 ); 
		fprintf(fo, "%u\t", (unsigned int)ui16); 
	/* DATA */
		for (j = 0; j < 8; j++) {
			fread(&ui16, 2, 1, fi);
			if (iLE == 1) SwapUnsignedInt16( &ui16 );
			fprintf(fo, "%u\t", (unsigned int)ui16); 
		}
		fprintf(fo,"\n"); /* end line */
	}

/* Close files and exit */
	fclose(fi);
	fclose(fo);	
	return 0;
}
