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 bool PUP::machineInfo::valid(void) const
00026 {
00027 for (int i=0;i<4;i++)
00028 if (magic[i]!=machInfo_magic[i])
00029 return false;
00030 return true;
00031 }
00032
00033
00034 bool 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 false;
00044 else
00045 return true;
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=1;
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 #if CMK_HAS_INT16
00099 m->intBytes[4]=sizeof(CmiInt16);
00100 #else
00101 m->intBytes[4]=0;
00102 #endif
00103 m->intFormat=getIntFormat();
00104 m->floatBytes=sizeof(float);
00105 m->doubleBytes=sizeof(double);
00106 m->floatFormat=getFloatFormat();
00107 m->boolBytes=sizeof(bool);
00108 m->pointerBytes=sizeof(void*);
00109
00110 }
00111 return *m;
00112 }
00113
00115 typedef unsigned char myByte;
00116
00117
00118 static void cvt_null(int N,const myByte *in,myByte *out,size_t nElem) {}
00119
00120
00121 static void cvt_swap(int N,const myByte *in,myByte *out,size_t nElem)
00122 {
00123 size_t i;
00124 for (i=0;i<nElem;i++)
00125 {
00126 const myByte *s=&in[N*i];
00127 myByte t,*d=&out[N*i];
00128 for (int j=N/2-1;j>=0;j--)
00129 {t=s[j];d[j]=s[N-j-1];d[N-j-1]=t;}
00130 }
00131 }
00132
00133
00134
00135 static void cvt_bool(int N,const myByte *in,myByte *out,size_t nElem)
00136 {
00137 size_t i;
00138 for (i=nElem;i>1;i--)
00139 {
00140 const myByte *s=&in[N*(i-1)];
00141 bool ret=false;
00142 int j;
00143 for (j=0;j<N;j++)
00144 if (s[j]!=0)
00145 ret=true;
00146 ((bool *)(out))[i-1]=ret;
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00161 #define def_cvtFunc(bigName,bigIdx,nameT,rT,uT) \
00162 static void cvt##bigName##_to##nameT(int N,const myByte *in,myByte *out,size_t nElem) \
00163 { \
00164 size_t i;for (i=0;i<nElem;i++)\
00165 {\
00166 const myByte *s=&in[N*i];\
00167 rT ret=0;\
00168 int j;\
00169 for (j=0;j<N-1;j++) \
00170 ret|=((uT)s[bigIdx])<<(8*j);\
00171 ret|=((rT)s[bigIdx])<<(8*j);\
00172 ((rT *)(out))[i]=ret;\
00173 }\
00174 }
00175 #define def_cvtBig_toT(T) def_cvtFunc(Big,N-j-1,T ,T ,unsigned T)
00176 #define def_cvtBig_touT(T) def_cvtFunc(Big,N-j-1,u##T ,unsigned T,unsigned T)
00177 #define def_cvtLil_toT(T) def_cvtFunc(Lil,j ,T ,T ,unsigned T)
00178 #define def_cvtLil_touT(T) def_cvtFunc(Lil,j ,u##T ,unsigned T,unsigned T)
00179
00180 #define def_cvtTypes(cvtNT) \
00181 cvtNT(char) cvtNT(short) cvtNT(int) cvtNT(long)
00182
00183 def_cvtTypes(def_cvtLil_toT)
00184 def_cvtTypes(def_cvtLil_touT)
00185 def_cvtTypes(def_cvtBig_toT)
00186 def_cvtTypes(def_cvtBig_touT)
00187
00188
00190 #define arr_cvtBig_toT(T) cvtBig_to##T
00191 #define arr_cvtBig_touT(T) cvtBig_tou##T
00192 #define arr_cvtLil_toT(T) cvtLil_to##T
00193 #define arr_cvtLil_touT(T) cvtLil_tou##T
00194
00195 #define arr_cvtTypes(cvtNT) \
00196 {cvtNT(char), cvtNT(short), cvtNT(int), cvtNT(long)}
00197
00198 typedef void (*dataConverterFn)(int N,const myByte *in,myByte *out,size_t nElem);
00199
00200 const static dataConverterFn cvt_intTable
00201 [2]
00202 [2]
00203 [4]
00204 ={
00205 { arr_cvtTypes(arr_cvtBig_toT),
00206 arr_cvtTypes(arr_cvtBig_touT) },
00207 { arr_cvtTypes(arr_cvtLil_toT),
00208 arr_cvtTypes(arr_cvtLil_touT) }
00209 };
00210
00211
00212
00213
00214 void PUP::xlater::setConverterInt(const machineInfo &src,const machineInfo &cur,
00215 int isUnsigned,int intType,dataType dest)
00216 {
00217 if (src.intFormat==cur.intFormat && src.intBytes[intType]==cur.intBytes[intType])
00218 convertFn[dest]=cvt_null;
00219 else
00220 convertFn[dest]=cvt_intTable[src.intFormat][isUnsigned][intType];
00221 convertSize[dest]=src.intBytes[intType];
00222 }
00223
00224
00225 static dataConverterFn converterFloat(
00226 const PUP::machineInfo &src,const PUP::machineInfo &cur,
00227 int srcSize,int curSize)
00228 {
00229 if (src.floatFormat==cur.floatFormat && srcSize==curSize)
00230 return cvt_null;
00231 else {
00232 if ((src.floatFormat==1 && cur.floatFormat==0)
00233 ||(src.floatFormat==0 && cur.floatFormat==1))
00234 {
00235 if (srcSize==4 && curSize==4)
00236 return cvt_swap;
00237 else if (srcSize==8 && curSize==8)
00238 return cvt_swap;
00239 }
00240 }
00241 fprintf(stderr,__FILE__" Non-convertible float sizes %d and %d\n",srcSize,curSize);
00242 abort();
00243 return NULL;
00244 }
00245
00246
00247 PUP::xlater::xlater(const PUP::machineInfo &src,PUP::er &fromData)
00248 :wrap_er(fromData)
00249 {
00250 const machineInfo &cur=PUP::machineInfo::current();
00251 if (src.intFormat>1) abort();
00252
00253 setConverterInt(src,cur,0,0,Tchar);
00254 setConverterInt(src,cur,0,1,Tshort);
00255 setConverterInt(src,cur,0,2,Tint);
00256 setConverterInt(src,cur,0,3,Tlong);
00257 setConverterInt(src,cur,1,0,Tuchar);
00258 setConverterInt(src,cur,1,1,Tushort);
00259 setConverterInt(src,cur,1,2,Tuint);
00260 setConverterInt(src,cur,1,3,Tulong);
00261 if (src.intFormat==cur.intFormat)
00262 convertFn[Tlonglong]=convertFn[Tulonglong]=cvt_null;
00263 else
00264 convertFn[Tlonglong]=convertFn[Tulonglong]=cvt_swap;
00265 #if CMK_HAS_INT16
00266 setConverterInt(src,cur,0,4,Tint128);
00267 setConverterInt(src,cur,1,4,Tuint128);
00268 #endif
00269 convertFn[Tfloat]=converterFloat(src,cur,src.floatBytes,cur.floatBytes);
00270 convertFn[Tdouble]=converterFloat(src,cur,src.doubleBytes,cur.doubleBytes);
00271 convertFn[Tlongdouble]=cvt_null;
00272
00273 if (src.boolBytes!=cur.boolBytes)
00274 convertFn[Tbool]=cvt_bool;
00275 else
00276 convertFn[Tbool]=cvt_null;
00277
00278 convertFn[Tbyte]=cvt_null;
00279 setConverterInt(src,cur,0,2,Tsync);
00280 convertFn[Tpointer]=cvt_null;
00281
00282
00283 #ifdef CMK_PUP_LONG_LONG
00284 convertSize[Tlonglong]=convertSize[Tlonglong]=sizeof(CMK_PUP_LONG_LONG);
00285 #else
00286 convertSize[Tlonglong]=convertSize[Tlonglong]=8;
00287 #endif
00288 convertSize[Tfloat]=src.floatBytes;
00289 convertSize[Tdouble]=src.doubleBytes;
00290 #if CMK_LONG_DOUBLE_DEFINED
00291 convertSize[Tlongdouble]=sizeof(long double);
00292 #else
00293 convertSize[Tlongdouble]=12;
00294 #endif
00295 convertSize[Tbool]=src.boolBytes;
00296 convertSize[Tbyte]=1;
00297 convertSize[Tpointer]=src.pointerBytes;
00298 }
00299
00300
00301 void PUP::xlater::bytes(void *ptr,size_t n,size_t itemSize,dataType t)
00302 {
00303 if (convertSize[t]==itemSize)
00304 {
00305 p.bytes(ptr,n,itemSize,t);
00306 convertFn[t](itemSize,(const myByte *)ptr,(myByte *)ptr,n);
00307 }
00308 else
00309 {
00310 void *buf=(void *)malloc(convertSize[t]*n);
00311 p.bytes(buf,n,convertSize[t],t);
00312 convertFn[t](convertSize[t],(const myByte *)buf,(myByte *)ptr,n);
00313 free(buf);
00314 }
00315 }
00316