334 lines
7.8 KiB
C
334 lines
7.8 KiB
C
/* endian.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Little/Big-Endian-Routinen */
|
|
/* */
|
|
/* Historie: 30. 5.1996 Grundsteinlegung */
|
|
/* 6. 7.1997 Dec32BlankString dazu */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "endian.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
Boolean BigEndian;
|
|
|
|
char *Integ16Format,*Integ32Format,*Integ64Format;
|
|
char *IntegerFormat,*LongIntFormat,*QuadIntFormat;
|
|
char *LargeIntFormat;
|
|
|
|
/*****************************************************************************/
|
|
|
|
void WSwap(void *Field, int Cnt)
|
|
BEGIN
|
|
register unsigned char *Run=(unsigned char *) Field,Swap;
|
|
register int z;
|
|
|
|
for (z=0; z<Cnt/2; z++,Run+=2)
|
|
BEGIN
|
|
Swap=Run[0]; Run[0]=Run[1]; Run[1]=Swap;
|
|
END
|
|
END
|
|
|
|
void DSwap(void *Field, int Cnt)
|
|
BEGIN
|
|
register unsigned char *Run=(unsigned char *) Field,Swap;
|
|
register int z;
|
|
|
|
for (z=0; z<Cnt/4; z++,Run+=4)
|
|
BEGIN
|
|
Swap=Run[0]; Run[0]=Run[3]; Run[3]=Swap;
|
|
Swap=Run[1]; Run[1]=Run[2]; Run[2]=Swap;
|
|
END
|
|
END
|
|
|
|
void QSwap(void *Field, int Cnt)
|
|
BEGIN
|
|
register unsigned char *Run=(unsigned char *) Field,Swap;
|
|
register int z;
|
|
|
|
for (z=0; z<Cnt/8; z++,Run+=8)
|
|
BEGIN
|
|
Swap=Run[0]; Run[0]=Run[7]; Run[7]=Swap;
|
|
Swap=Run[1]; Run[1]=Run[6]; Run[6]=Swap;
|
|
Swap=Run[2]; Run[2]=Run[5]; Run[5]=Swap;
|
|
Swap=Run[3]; Run[3]=Run[4]; Run[4]=Swap;
|
|
END
|
|
END
|
|
|
|
void DWSwap(void *Field, int Cnt)
|
|
BEGIN
|
|
register unsigned char *Run=(unsigned char *) Field,Swap;
|
|
register int z;
|
|
|
|
for (z=0; z<Cnt/4; z++,Run+=4)
|
|
BEGIN
|
|
Swap=Run[0]; Run[0]=Run[2]; Run[2]=Swap;
|
|
Swap=Run[1]; Run[1]=Run[3]; Run[3]=Swap;
|
|
END
|
|
END
|
|
|
|
void QWSwap(void *Field, int Cnt)
|
|
BEGIN
|
|
register unsigned char *Run=(unsigned char *) Field,Swap;
|
|
register int z;
|
|
|
|
for (z=0; z<Cnt/8; z++,Run+=8)
|
|
BEGIN
|
|
Swap=Run[0]; Run[0]=Run[6]; Run[6]=Swap;
|
|
Swap=Run[1]; Run[1]=Run[7]; Run[7]=Swap;
|
|
Swap=Run[2]; Run[2]=Run[4]; Run[4]=Swap;
|
|
Swap=Run[3]; Run[3]=Run[5]; Run[5]=Swap;
|
|
END
|
|
END
|
|
|
|
void Double_2_ieee4(Double inp, Byte *dest, Boolean NeedsBig)
|
|
BEGIN
|
|
#ifdef IEEEFLOAT
|
|
Single tmp=inp;
|
|
memcpy(dest,&tmp,4);
|
|
if (BigEndian!=NeedsBig) DSwap(dest,4);
|
|
#endif
|
|
#ifdef VAXFLOAT
|
|
Single tmp=inp/4;
|
|
memcpy(dest,&tmp,4);
|
|
WSwap(dest,4);
|
|
if (NOT NeedsBig) DSwap(dest,4);
|
|
#endif
|
|
END
|
|
|
|
void Double_2_ieee8(Double inp, Byte *dest, Boolean NeedsBig)
|
|
BEGIN
|
|
#ifdef IEEEFLOAT
|
|
memcpy(dest,&inp,8);
|
|
if (BigEndian!=NeedsBig) QSwap(dest,8);
|
|
#endif
|
|
#ifdef VAXFLOAT
|
|
Byte tmp[8];
|
|
Word Exp;
|
|
int z;
|
|
Boolean cont;
|
|
|
|
memcpy(tmp,&inp,8);
|
|
WSwap(tmp,8);
|
|
Exp=((tmp[0]<<1)&0xfe)+(tmp[1]>>7);
|
|
Exp+=894; /* =1023-192 */
|
|
tmp[1]&=0x7f;
|
|
if ((tmp[7]&7)>4)
|
|
BEGIN
|
|
for (tmp[7]+=8,cont=tmp[7]<8,z=0; cont AND z>1; z--)
|
|
BEGIN
|
|
tmp[z]++; cont=(tmp[z]==0);
|
|
END
|
|
if (cont)
|
|
BEGIN
|
|
tmp[1]++; if (tmp[1]>127) Exp++;
|
|
END
|
|
END
|
|
dest[7]=(tmp[0]&0x80)+((Exp>>4)&0x7f);
|
|
dest[6]=((Exp&0x0f)<<4)+((tmp[1]>>3)&0x0f);
|
|
for (z=5; z>=0; z--)
|
|
dest[z]=((tmp[6-z]&7)<<5)|((tmp[7-z]>>3)&0x1f);
|
|
if (NeedsBig) QSwap(dest,8);
|
|
#endif
|
|
END
|
|
|
|
void Double_2_ieee10(Double inp, Byte *dest, Boolean NeedsBig)
|
|
BEGIN
|
|
Byte Buffer[8];
|
|
Byte Sign;
|
|
Word Exponent;
|
|
int z;
|
|
|
|
#ifdef IEEEFLOAT
|
|
Boolean Denormal;
|
|
|
|
memcpy(Buffer,&inp,8); if (BigEndian) QSwap(Buffer,8);
|
|
Sign=(Buffer[7]&0x80);
|
|
Exponent=(Buffer[6]>>4)+(((Word) Buffer[7]&0x7f)<<4);
|
|
Denormal=(Exponent==0);
|
|
if (Exponent==2047) Exponent=32767;
|
|
else Exponent+=(16383-1023);
|
|
Buffer[6]&=0x0f; if (NOT Denormal) Buffer[6]|=0x10;
|
|
for (z=7; z>=2; z--)
|
|
dest[z]=((Buffer[z-1]&0x1f)<<3)|((Buffer[z-2]&0xe0)>>5);
|
|
dest[1]=(Buffer[0]&0x1f)<<3;
|
|
dest[0]=0;
|
|
#endif
|
|
#ifdef VAXFLOAT
|
|
memcpy(Buffer,&inp,8); WSwap(Buffer,8);
|
|
Sign=(*Buffer)&0x80;
|
|
Exponent=((*Buffer)<<1)+((Buffer[1]&0x80)>>7);
|
|
Exponent+=(16383-129);
|
|
Buffer[1]|=0x80;
|
|
for (z=1; z<8; z++) dest[z]=Buffer[8-z];
|
|
dest[0]=0;
|
|
#endif
|
|
dest[9]=Sign|((Exponent>>8)&0x7f);
|
|
dest[8]=Exponent&0xff;
|
|
if (NeedsBig)
|
|
for (z=0; z<5; z++)
|
|
BEGIN
|
|
Sign=dest[z]; dest[z]=dest[9-z]; dest[9-z]=Sign;
|
|
END
|
|
END
|
|
|
|
|
|
Boolean Read2(FILE *file, void *Ptr)
|
|
BEGIN
|
|
if (fread(Ptr,1,2,file)!=2) return False;
|
|
if (BigEndian) WSwap(Ptr,2);
|
|
return True;
|
|
END
|
|
|
|
Boolean Read4(FILE *file, void *Ptr)
|
|
BEGIN
|
|
if (fread(Ptr,1,4,file)!=4) return False;
|
|
if (BigEndian) DSwap(Ptr,4);
|
|
return True;
|
|
END
|
|
|
|
Boolean Read8(FILE *file, void *Ptr)
|
|
BEGIN
|
|
if (fread(Ptr,1,8,file)!=8) return False;
|
|
if (BigEndian) QSwap(Ptr,8);
|
|
return True;
|
|
END
|
|
|
|
|
|
|
|
Boolean Write2(FILE *file, void *Ptr)
|
|
BEGIN
|
|
Boolean OK;
|
|
|
|
if (BigEndian) WSwap(Ptr,2);
|
|
OK=(fwrite(Ptr,1,2,file)==2);
|
|
if (BigEndian) WSwap(Ptr,2);
|
|
return OK;
|
|
END
|
|
|
|
Boolean Write4(FILE *file, void *Ptr)
|
|
BEGIN
|
|
Boolean OK;
|
|
|
|
if (BigEndian) DSwap(Ptr,4);
|
|
OK=(fwrite(Ptr,1,4,file)==4);
|
|
if (BigEndian) DSwap(Ptr,4);
|
|
return OK;
|
|
END
|
|
|
|
Boolean Write8(FILE *file, void *Ptr)
|
|
BEGIN
|
|
Boolean OK;
|
|
|
|
if (BigEndian) QSwap(Ptr,8);
|
|
OK=(fwrite(Ptr,1,8,file)==8);
|
|
if (BigEndian) QSwap(Ptr,8);
|
|
return OK;
|
|
END
|
|
|
|
|
|
static void CheckSingle(int Is, int Should, char *Name)
|
|
BEGIN
|
|
if (Is!=Should)
|
|
BEGIN
|
|
fprintf(stderr,"Configuration error: Sizeof(%s) is %d, should be %d\n",
|
|
Name,Is,Should);
|
|
exit(255);
|
|
END
|
|
END
|
|
|
|
static void CheckDataTypes(void)
|
|
BEGIN
|
|
if (sizeof(int)<2)
|
|
BEGIN
|
|
fprintf(stderr,"Configuration error: Sizeof(int) is %d, should be >=2\n",
|
|
(int) sizeof(int));
|
|
exit(255);
|
|
END
|
|
CheckSingle(sizeof(Byte), 1,"Byte");
|
|
CheckSingle(sizeof(ShortInt),1,"ShortInt");
|
|
#ifdef HAS16
|
|
CheckSingle(sizeof(Word), 2,"Word");
|
|
CheckSingle(sizeof(Integer), 2,"Integer");
|
|
#endif
|
|
CheckSingle(sizeof(LongInt), 4,"LongInt");
|
|
CheckSingle(sizeof(LongWord),4,"LongWord");
|
|
#ifdef HAS64
|
|
CheckSingle(sizeof(QuadInt), 8,"QuadInt");
|
|
CheckSingle(sizeof(QuadWord),8,"QuadWord");
|
|
#endif
|
|
CheckSingle(sizeof(Single), 4,"Single");
|
|
CheckSingle(sizeof(Double), 8,"Double");
|
|
END
|
|
|
|
|
|
static char *AssignSingle(int size)
|
|
BEGIN
|
|
if (size==sizeof(short)) return "%d";
|
|
else if (size==sizeof(int)) return "%d";
|
|
else if (size==sizeof(long)) return "%ld";
|
|
#ifndef NOLONGLONG
|
|
else if (size==sizeof(long long)) return "%lld";
|
|
#endif
|
|
else
|
|
BEGIN
|
|
fprintf(stderr,
|
|
"Configuration error: cannot assign format string for integer of size %d\n",size);
|
|
exit(255);
|
|
return "";
|
|
END
|
|
END
|
|
|
|
static void AssignFormats(void)
|
|
BEGIN
|
|
#ifdef HAS16
|
|
IntegerFormat=Integ16Format=AssignSingle(2);
|
|
#endif
|
|
LongIntFormat=Integ32Format=AssignSingle(4);
|
|
#ifdef HAS64
|
|
QuadIntFormat=Integ64Format=AssignSingle(8);
|
|
#endif
|
|
LargeIntFormat=AssignSingle(sizeof(LargeInt));
|
|
END
|
|
|
|
char *Dec32BlankString(LongInt number, int Stellen)
|
|
BEGIN
|
|
char Format[10];
|
|
static char Erg[255];
|
|
|
|
sprintf(Format,"%%%d%s",Stellen,LongIntFormat+1);
|
|
sprintf(Erg,Format,number);
|
|
|
|
return Erg;
|
|
END
|
|
|
|
|
|
void endian_init(void)
|
|
BEGIN
|
|
union
|
|
{
|
|
unsigned char field[sizeof(int)];
|
|
int test;
|
|
} TwoFace;
|
|
|
|
CheckDataTypes(); AssignFormats();
|
|
|
|
memset(TwoFace.field,0,sizeof(int));
|
|
TwoFace.field[0]=1;
|
|
BigEndian=((TwoFace.test)!=1);
|
|
/*if (BigEndian)
|
|
BEGIN
|
|
fprintf(stderr,"Warning: Big endian machine!\n");
|
|
fprintf(stderr,"AS is so far not adapted for big-endian-machines!\n");
|
|
END*/
|
|
END
|
|
|
|
|