00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include "pup.h"
00018
00020
00021
00022 static const unsigned char machInfo_magic[4]={0x10,0xea,0xbd,0xf9};
00023
00024
00025 CmiBool PUP::machineInfo::valid(void) const
00026 {
00027 for (int i=0;i<4;i++)
00028 if (magic[i]!=machInfo_magic[i])
00029 return CmiFalse;
00030 return CmiTrue;
00031 }
00032
00033
00034 CmiBool PUP::machineInfo::needsConversion(void) const
00035 {
00036 const machineInfo &m=current();
00037 if (intFormat==m.intFormat && floatFormat==m.floatFormat &&
00038 intBytes[0]==m.intBytes[0] && intBytes[1]==m.intBytes[1] &&
00039 intBytes[2]==m.intBytes[2] && intBytes[3]==m.intBytes[3] &&
00040 floatBytes==m.floatBytes && doubleBytes==m.doubleBytes &&
00041 boolBytes==m.boolBytes && pointerBytes==m.pointerBytes
00042 )
00043 return CmiFalse;
00044 else
00045 return CmiTrue;
00046 }
00047
00049 static int getIntFormat(void)
00050 {
00051 int test=0x1c;
00052 unsigned char *c=(unsigned char *)&test;
00053 if (c[sizeof(int)-1]==0x1c)
00054
00055 return 0;
00056 if (c[0]==0x1c)
00057
00058 return 1;
00059 return 99;
00060 }
00061
00062
00063
00064
00065 int getFloatFormat(void)
00066 {
00067 float ftest=-9.5;
00068 double dtest=-9.5;
00069
00070
00071 unsigned char *c;
00072 if (sizeof(double)==8) c=(unsigned char *)&dtest;
00073 else if (sizeof(float)==8) c=(unsigned char *)&ftest;
00074 else return 98;
00075
00076 if (c[0]==0xc0 && c[1]==0x23 && c[2]==0x00 && c[3]==0x00)
00077 return 0;
00078 if (c[4]==0x00 && c[5]==0x00 && c[6]==0x23 && c[7]==0xc0)
00079 return 1;
00080 if (c[0]==0xC0 && c[1]==0x04 && c[2]==0x98 && c[3]==0x00)
00081 return 50;
00082 return 99;
00083 }
00084
00085 const PUP::machineInfo &PUP::machineInfo::current(void)
00086 {
00087 static machineInfo *m=NULL;
00088 if (m==NULL)
00089 {
00090 m=new machineInfo();
00091 for (int i=0;i<4;i++)
00092 m->magic[i]=machInfo_magic[i];
00093 m->version=0;
00094 m->intBytes[0]=sizeof(char);
00095 m->intBytes[1]=sizeof(short);
00096 m->intBytes[2]=sizeof(int);
00097 m->intBytes[3]=sizeof(long);
00098 m->intFormat=getIntFormat();
00099 m->floatBytes=sizeof(float);
00100 m->doubleBytes=sizeof(double);
00101 m->floatFormat=getFloatFormat();
00102 m->boolBytes=sizeof(CmiBool);
00103 m->pointerBytes=sizeof(void*);
00104 m->padding[0]=0;
00105 }
00106 return *m;
00107 }
00108
00110 typedef unsigned char myByte;
00111
00112
00113 static void cvt_null(int N,const myByte *in,myByte *out,int nElem) {}
00114
00115
00116 static void cvt_swap(int N,const myByte *in,myByte *out,int nElem)
00117 {
00118 int i;
00119 for (i=0;i<nElem;i++)
00120 {
00121 const myByte *s=&in[N*i];
00122 myByte t,*d=&out[N*i];
00123 for (int j=N/2-1;j>=0;j--)
00124 {t=s[j];d[j]=s[N-j-1];d[N-j-1]=t;}
00125 }
00126 }
00127
00128
00129
00130 static void cvt_bool(int N,const myByte *in,myByte *out,int nElem)
00131 {
00132 int i;for (i=nElem-1;i>=0;i--)
00133 {
00134 const myByte *s=&in[N*i];
00135 CmiBool ret=CmiFalse;
00136 int j;for (j=0;j<N;j++)
00137 if (s[j]!=0)
00138 ret=CmiTrue;
00139 ((CmiBool *)(out))[i]=ret;
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00154 #define def_cvtFunc(bigName,bigIdx,nameT,rT,uT) \
00155 static void cvt##bigName##_to##nameT(int N,const myByte *in,myByte *out,int nElem) \
00156 { \
00157 int i;for (i=0;i<nElem;i++)\
00158 {\
00159 const myByte *s=&in[N*i];\
00160 rT ret=0;\
00161 int j;\
00162 for (j=0;j<N-1;j++) \
00163 ret|=((uT)s[bigIdx])<<(8*j);\
00164 ret|=((rT)s[bigIdx])<<(8*j);\
00165 ((rT *)(out))[i]=ret;\
00166 }\
00167 }
00168 #define def_cvtBig_toT(T) def_cvtFunc(Big,N-j-1,T ,T ,unsigned T)
00169 #define def_cvtBig_touT(T) def_cvtFunc(Big,N-j-1,u##T ,unsigned T,unsigned T)
00170 #define def_cvtLil_toT(T) def_cvtFunc(Lil,j ,T ,T ,unsigned T)
00171 #define def_cvtLil_touT(T) def_cvtFunc(Lil,j ,u##T ,unsigned T,unsigned T)
00172
00173 #define def_cvtTypes(cvtNT) \
00174 cvtNT(char) cvtNT(short) cvtNT(int) cvtNT(long)
00175
00176 def_cvtTypes(def_cvtLil_toT)
00177 def_cvtTypes(def_cvtLil_touT)
00178 def_cvtTypes(def_cvtBig_toT)
00179 def_cvtTypes(def_cvtBig_touT)
00180
00181
00183 #define arr_cvtBig_toT(T) cvtBig_to##T
00184 #define arr_cvtBig_touT(T) cvtBig_tou##T
00185 #define arr_cvtLil_toT(T) cvtLil_to##T
00186 #define arr_cvtLil_touT(T) cvtLil_tou##T
00187
00188 #define arr_cvtTypes(cvtNT) \
00189 {cvtNT(char), cvtNT(short), cvtNT(int), cvtNT(long)}
00190
00191 typedef void (*dataConverterFn)(int N,const myByte *in,myByte *out,int nElem);
00192
00193 const static dataConverterFn cvt_intTable
00194 [2]
00195 [2]
00196 [4]
00197 ={
00198 { arr_cvtTypes(arr_cvtBig_toT),
00199 arr_cvtTypes(arr_cvtBig_touT) },
00200 { arr_cvtTypes(arr_cvtLil_toT),
00201 arr_cvtTypes(arr_cvtLil_touT) }
00202 };
00203
00204
00205
00206
00207 void PUP::xlater::setConverterInt(const machineInfo &src,const machineInfo &cur,
00208 int isUnsigned,int intType,dataType dest)
00209 {
00210 if (src.intFormat==cur.intFormat && src.intBytes[intType]==cur.intBytes[intType])
00211 convertFn[dest]=cvt_null;
00212 else
00213 convertFn[dest]=cvt_intTable[src.intFormat][isUnsigned][intType];
00214 convertSize[dest]=src.intBytes[intType];
00215 }
00216
00217
00218 static dataConverterFn converterFloat(
00219 const PUP::machineInfo &src,const PUP::machineInfo &cur,
00220 int srcSize,int curSize)
00221 {
00222 if (src.floatFormat==cur.floatFormat && srcSize==curSize)
00223 return cvt_null;
00224 else {
00225 if ((src.floatFormat==1 && cur.floatFormat==0)
00226 ||(src.floatFormat==0 && cur.floatFormat==1))
00227 {
00228 if (srcSize==4 && curSize==4)
00229 return cvt_swap;
00230 else if (srcSize==8 && curSize==8)
00231 return cvt_swap;
00232 }
00233 }
00234 fprintf(stderr,__FILE__" Non-convertible float sizes %d and %d\n",srcSize,curSize);
00235 abort();
00236 return NULL;
00237 }
00238
00239
00240 PUP::xlater::xlater(const PUP::machineInfo &src,PUP::er &fromData)
00241 :wrap_er(fromData)
00242 {
00243 const machineInfo &cur=PUP::machineInfo::current();
00244 if (src.intFormat>1) abort();
00245
00246 setConverterInt(src,cur,0,0,Tchar);
00247 setConverterInt(src,cur,0,1,Tshort);
00248 setConverterInt(src,cur,0,2,Tint);
00249 setConverterInt(src,cur,0,3,Tlong);
00250 setConverterInt(src,cur,1,0,Tuchar);
00251 setConverterInt(src,cur,1,1,Tushort);
00252 setConverterInt(src,cur,1,2,Tuint);
00253 setConverterInt(src,cur,1,3,Tulong);
00254 if (src.intFormat==cur.intFormat)
00255 convertFn[Tlonglong]=convertFn[Tulonglong]=cvt_null;
00256 else
00257 convertFn[Tlonglong]=convertFn[Tulonglong]=cvt_swap;
00258 convertFn[Tfloat]=converterFloat(src,cur,src.floatBytes,cur.floatBytes);
00259 convertFn[Tdouble]=converterFloat(src,cur,src.doubleBytes,cur.doubleBytes);
00260 convertFn[Tlongdouble]=cvt_null;
00261
00262 if (src.boolBytes!=cur.boolBytes)
00263 convertFn[Tbool]=cvt_bool;
00264 else
00265 convertFn[Tbool]=cvt_null;
00266
00267 convertFn[Tbyte]=cvt_null;
00268 setConverterInt(src,cur,0,2,Tsync);
00269 convertFn[Tpointer]=cvt_null;
00270
00271
00272 #ifdef CMK_PUP_LONG_LONG
00273 convertSize[Tlonglong]=convertSize[Tlonglong]=sizeof(CMK_PUP_LONG_LONG);
00274 #else
00275 convertSize[Tlonglong]=convertSize[Tlonglong]=8;
00276 #endif
00277 convertSize[Tfloat]=src.floatBytes;
00278 convertSize[Tdouble]=src.doubleBytes;
00279 #if CMK_LONG_DOUBLE_DEFINED
00280 convertSize[Tlongdouble]=sizeof(long double);
00281 #else
00282 convertSize[Tlongdouble]=12;
00283 #endif
00284 convertSize[Tbool]=src.boolBytes;
00285 convertSize[Tbyte]=1;
00286 convertSize[Tpointer]=src.pointerBytes;
00287 }
00288
00289
00290 void PUP::xlater::bytes(void *ptr,int n,size_t itemSize,dataType t)
00291 {
00292 if (convertSize[t]==itemSize)
00293 {
00294 p.bytes(ptr,n,itemSize,t);
00295 convertFn[t](itemSize,(const myByte *)ptr,(myByte *)ptr,n);
00296 }
00297 else
00298 {
00299 void *buf=(void *)malloc(convertSize[t]*n);
00300 p.bytes(buf,n,convertSize[t],t);
00301 convertFn[t](convertSize[t],(const myByte *)buf,(myByte *)ptr,n);
00302 free(buf);
00303 }
00304 }
00305