Well! Maybe I wrote this word incorrect but its not included im my
e-dictionary!
I have a structure with many int, short etc
I execute this function:
fread(&my_struct, sizeof(struct), 1, filepointer);
The problem is this:
In different endianess platforms from same file will be loaded different
data in the class.
Is there a method to load whole structure at once without this problem?
Until now my approach is:
load whole structure from file.
Instead of my_struct.integer_no_1 I use load_integer(my_struct.integer_no_1)
with load_integer:
--------------------------------
// swap char of an 4 bytes long if machine has "LSB last" storage
//
unsigned long load_integer(unsigned long a)
{
const static short sample = 0x1234;
const static char *test = (char*) &sample;
if (test[0] == 0x34) return a;
return (a << 24) + ((a & 0xff00) << 8) + ((a & 0xff0000) >> 8) + (a >> 24);
}
-------------------------------
but it is very funny approach....
well! another problem is if long is not 4 bytes, but don't do it so
diffucult!...
Hi,
Here is a example for Little/Big Endian machines/files.
NOT for middle endian machines/files (PDP).
Marco
/*
** This program works ONLY for
** Little-Endian and Big-Endian files/processors
** NOT for Middle-Endian
*/
#include <stdio.h>
typedef enum {
ENDIAN_NO_INFORMATION,
ENDIAN_LITTLE,
ENDIAN_MIDDLE,
ENDIAN_BIG
} ENDIAN_TYPE;
static int FileWrite(const char*,ENDIAN_TYPE,ENDIAN_TYPE);
static int FileRead(const char*,ENDIAN_TYPE,ENDIAN_TYPE);
static ENDIAN_TYPE UtilEndianType(void);
static void *ReverseBytesInArray(void*,size_t);
static void DumpArray(const void*,size_t);
int main()
{
ENDIAN_TYPE ProcType,FileType;
char *EndianTypeName[]={"NO Information","Little","Middle","Big"};
ProcType=UtilEndianType();
(void)printf("This is a %s-Endian processor.\n",EndianTypeName[ProcType]);
FileType=ENDIAN_LITTLE;
if ( FileWrite("Test.bin",ProcType,FileType)!=0 ) return 1;
FileType=ENDIAN_LITTLE;
if ( FileRead("Test.bin",ProcType,FileType)!=0 ) return 1;
return 0;
}
static int FileWrite(const char *cFile,ENDIAN_TYPE ProcType,ENDIAN_TYPE
FileType)
{
FILE *File;
short sTest;
long lTest;
float fTest;
double dTest;
if ( (File=fopen(cFile,"wb"))==NULL ) return 1;
(void)printf("Writing file '%s'\n",cFile);
sTest=0x1234;
(void)printf("%04X\n",sTest);
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&sTest,sizeof(short));
if ( fwrite(&sTest,sizeof(short),1,File)!=1 ) return 1;
lTest=0x12345678L;
(void)printf("%08X\n",lTest);
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&lTest,sizeof(long));
if ( fwrite(&lTest,sizeof(long),1,File)!=1 ) return 1;
fTest=63.0F;
(void)printf("%.8f\n",fTest);
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&fTest,sizeof(float));
if ( fwrite(&fTest,sizeof(float),1,File)!=1 ) return 1;
dTest=1.234567890123456789;
(void)printf("%.18lf\n",dTest);
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&dTest,sizeof(double));
if ( fwrite(&dTest,sizeof(double),1,File)!=1 ) return 1;
if ( fclose(File)!=0 ) return 1;
return 0;
}
static int FileRead(const char *cFile,ENDIAN_TYPE ProcType,ENDIAN_TYPE
FileType)
{
FILE *File;
short sTest;
long lTest;
float fTest;
double dTest;
if ( (File=fopen(cFile,"rb"))==NULL ) return 1;
(void)printf("Reading file '%s'\n",cFile);
if ( fread(&sTest,sizeof(short),1,File)!=1 ) return 1;
DumpArray(&sTest,sizeof(short));
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&sTest,sizeof(short));
(void)printf("%04X\n",sTest);
if ( fread(&lTest,sizeof(long),1,File)!=1 ) return 1;
DumpArray(&lTest,sizeof(long));
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&lTest,sizeof(long));
(void)printf("%08X\n",lTest);
if ( fread(&fTest,sizeof(float),1,File)!=1 ) return 1;
DumpArray(&fTest,sizeof(float));
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&fTest,sizeof(float));
(void)printf("%.8f\n",fTest);
if ( fread(&dTest,sizeof(double),1,File)!=1 ) return 1;
DumpArray(&dTest,sizeof(double));
if ( ProcType!=FileType ) (void)ReverseBytesInArray(&dTest,sizeof(double));
(void)printf("%.18lf\n",dTest);
if ( fclose(File)!=0 ) return 1;
return 0;
}
static ENDIAN_TYPE UtilEndianType()
{
ENDIAN_TYPE EndianType=ENDIAN_NO_INFORMATION;
unsigned long Value=0x12345678;
unsigned char *cPtr=(unsigned char*)&Value;
if ( *cPtr==0x12 && *(cPtr+1)==0x34 && *(cPtr+2)==0x56 && *(cPtr+3)==0x78 )
EndianType=ENDIAN_BIG;
else if ( *cPtr==0x78 && *(cPtr+1)==0x56 && *(cPtr+2)==0x34 &&
*(cPtr+3)==0x12 )
EndianType=ENDIAN_LITTLE;
else if ( *cPtr==0x34 && *(cPtr+1)==0x12 && *(cPtr+2)==0x78 &&
*(cPtr+3)==0x56 )
EndianType=ENDIAN_MIDDLE;
return EndianType;
}
static void *ReverseBytesInArray(void *Buffer,size_t Size)
{
unsigned char *cPtr0,*cPtr1,cTmp;
cPtr0=Buffer;
cPtr1=cPtr0+Size;
while ( cPtr0<--cPtr1 ) {
cTmp=*cPtr0;
*cPtr0++=*cPtr1;
*cPtr1=cTmp;
}
return Buffer;
}
static void DumpArray(const void *Array,size_t Size)
{
const unsigned char *cPtr=Array;
size_t i;
for ( i=0; i<Size; i++ )
(void)printf("%02X%c",*cPtr++,(i+1<Size)?' ':',');
return;
}