00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <ctype.h>
00019 #include <errno.h>
00020 #include <fcntl.h>
00021
00022 #include "converse.h"
00023 #include "pup.h"
00024 #include "ckhashtable.h"
00025
00026 #if defined(_WIN32)
00027 #include <io.h>
00028
00029 int pwrite(int fd, const void *buf, size_t nbytes, __int64 offset)
00030 {
00031 __int64 ret = _lseek(fd, offset, SEEK_SET);
00032
00033 if (ret == -1) {
00034 return(-1);
00035 }
00036 return(_write(fd, buf, nbytes));
00037 }
00038 #define NO_UNISTD_NEEDED
00039 #endif
00040
00041 #if defined(__PGIC__)
00042
00043
00044
00045 extern "C" {
00046
00047 extern ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
00048 }
00049 #define NO_UNISTD_NEEDED
00050 #endif
00051
00052 #if !defined(NO_UNISTD_NEEDED)
00053 #include <unistd.h>
00054 #endif
00055
00056 PUP::er::~er() {}
00057
00058 void PUP::er::operator()(able& a)
00059 {a.pup(*this);}
00060
00061 void PUP::er::comment(const char *message)
00062 { }
00063
00064 const char * PUP::er::typeString() const
00065 {
00066 if (isSizing()) return "sizing";
00067 else if (isPacking()) return "packing";
00068 else if (isUnpacking()) return "unpacking";
00069 return "unknown";
00070 }
00071
00072 void PUP::er::synchronize(unsigned int m)
00073 { }
00074
00075
00076
00077
00078
00079 #ifdef CK_CHECK_PUP
00080 static int bannerDisplayed=0;
00081 static void showBanner(void) {
00082 bannerDisplayed=1;
00083 fprintf(stderr,"CK_CHECK_PUP pup routine checking enabled\n");
00084 CmiPrintf("CK_CHECK_PUP pup routine checking enabled\n");
00085 }
00086
00087 class pupCheckRec {
00088 unsigned char magic[4];
00089 unsigned char type;
00090 unsigned char length[8];
00091 enum {pupMagic=0xf36c5a21,typeMask=0x75};
00092 int getMagic(void) const {return (magic[3]<<24)+(magic[2]<<16)+(magic[1]<<8)+magic[0];}
00093 void setMagic(int v) {for (int i=0;i<4;i++) magic[i]=(v>>(8*i));}
00094 PUP::dataType getType(void) const {return (PUP::dataType)(type^typeMask);}
00095 void setType(PUP::dataType v) {type=v^typeMask;}
00096 size_t getLength(void) const {
00097 size_t v = 0;
00098 for (int i=0;i<8;i++) v += (length[i]<<(8*i));
00099 return v;
00100 }
00101 void setLength(size_t v) {for (int i=0;i<8;i++) length[i]=(v>>(8*i));}
00102
00103
00104
00105
00106 void compare(const char *kind,const char *why,int packed,int unpacked) const
00107 {
00108 if (packed==unpacked) return;
00109
00110 fprintf(stderr,"CK_CHECK_PUP error!\nPacked %s (%d, or %08x) does "
00111 "not equal unpacked value (%d, or %08x)!\nThis means %s\n",
00112 kind,packed,packed,unpacked,unpacked,why);
00113 CmiPrintf("CK_CHECK_PUP error! Run with debugger for more info.\n");
00114
00115 abort();
00116 }
00117 public:
00118 void write(PUP::dataType t,size_t n) {
00119 if (!bannerDisplayed) showBanner();
00120 setMagic(pupMagic);
00121 type=t^typeMask;
00122 setLength(n);
00123 }
00124 void check(PUP::dataType t,size_t n) const {
00125 compare("magic number",
00126 "you unpacked more than you packed, or the values were corrupted during transport",
00127 getMagic(),pupMagic);
00128 compare("data type",
00129 "the pack and unpack paths do not match up",
00130 getType(),t);
00131 compare("length",
00132 "you may have forgotten to pup the array length",
00133 getLength(),n);
00134 }
00135 };
00136 #endif
00137
00138
00139 void PUP::sizer::bytes(void * ,size_t n,size_t itemSize,dataType )
00140 {
00141 #ifdef CK_CHECK_PUP
00142 nBytes+=sizeof(pupCheckRec);
00143 #endif
00144 nBytes+=n*itemSize;
00145 }
00146
00147
00148 void PUP::toMem::bytes(void *p,size_t n,size_t itemSize,dataType t)
00149 {
00150 #ifdef CK_CHECK_PUP
00151 ((pupCheckRec *)buf)->write(t,n);
00152 buf+=sizeof(pupCheckRec);
00153 #endif
00154 n*=itemSize;
00155 memcpy((void *)buf,p,n);
00156 buf+=n;
00157 }
00158 void PUP::fromMem::bytes(void *p,size_t n,size_t itemSize,dataType t)
00159 {
00160 #ifdef CK_CHECK_PUP
00161 ((pupCheckRec *)buf)->check(t,n);
00162 buf+=sizeof(pupCheckRec);
00163 #endif
00164 n*=itemSize;
00165 memcpy(p,(const void *)buf,n);
00166 buf+=n;
00167 }
00168
00169 extern "C" {
00170
00171 int CmiOpen(const char *pathname, int flags, int mode)
00172 {
00173 int fd = -1;
00174 while (1) {
00175 #if defined(_WIN32)
00176 fd = _open(pathname, flags, mode);
00177 #else
00178 fd = open(pathname, flags, mode);
00179 #endif
00180 if (fd == -1 && errno==EINTR) {
00181 CmiError("Warning: CmiOpen retrying on %s\n", pathname);
00182 continue;
00183 }
00184 else
00185 break;
00186 }
00187 return fd;
00188 }
00189
00190
00191 size_t CmiFwrite(const void *ptr, size_t size, size_t nmemb, FILE *f)
00192 {
00193 size_t nwritten = 0;
00194 const char *buf = (const char *)ptr;
00195 double firsttime = 0;
00196 while (nwritten < nmemb) {
00197 size_t ncur = fwrite(buf+nwritten*size,size,nmemb-nwritten,f);
00198 if (ncur <= 0) {
00199 if (errno == EINTR)
00200 CmiError("Warning: CmiFwrite retrying ...\n");
00201 else if(errno == ENOMEM)
00202 {
00203 #ifndef CMK_BIGSIM_CHARM
00204 if(firsttime == 0) firsttime = CmiWallTimer();
00205 if(CmiWallTimer()-firsttime > 300)
00206 break;
00207 #endif
00208 }
00209 else
00210 break;
00211 }
00212 else
00213 nwritten += ncur;
00214 }
00215 #ifndef CMK_BIGSIM_CHARM
00216 if(firsttime != 0)
00217 CmiError("Warning: CmiFwrite retried for %lf ...\n", CmiWallTimer() - firsttime);
00218 #endif
00219
00220 return nwritten;
00221 }
00222
00223 CmiInt8 CmiPwrite(int fd, const char *buf, size_t bytes, size_t offset)
00224 {
00225 size_t origBytes = bytes;
00226 while (bytes > 0) {
00227 CmiInt8 ret = pwrite(fd, buf, bytes, offset);
00228 if (ret < 0) {
00229 if (errno == EINTR) {
00230 continue;
00231 } else {
00232 return ret;
00233 }
00234 }
00235 bytes -= ret;
00236 buf += ret;
00237 offset += ret;
00238 }
00239 return origBytes;
00240 }
00241
00242 size_t CmiFread(void *ptr, size_t size, size_t nmemb, FILE *f)
00243 {
00244 size_t nread = 0;
00245 char *buf = (char *)ptr;
00246 while (nread < nmemb) {
00247 size_t ncur = fread(buf + nread*size, size, nmemb-nread, f);
00248 if (ncur <= 0) {
00249 if (errno == EINTR)
00250 CmiError("Warning: CmiFread retrying ...\n");
00251 else
00252 break;
00253 }
00254 else
00255 nread += ncur;
00256 }
00257 return nread;
00258 }
00259
00260 FILE *CmiFopen(const char *path, const char *mode)
00261 {
00262 FILE *fp = NULL;
00263 while (1) {
00264 fp = fopen(path, mode);
00265 if (fp == 0 && errno==EINTR) {
00266 CmiError("Warning: CmiFopen retrying on %s\n", path);
00267 continue;
00268 }
00269 else
00270 break;
00271 }
00272 return fp;
00273 }
00274
00275
00276 int CmiFclose(FILE *fp)
00277 {
00278 int status = 0;
00279 while (1) {
00280 status = fflush(fp);
00281 if (status != 0 && errno==EINTR) {
00282 CmiError("Warning: CmiFclose flush retrying ...\n");
00283 continue;
00284 }
00285 else
00286 break;
00287 }
00288 if (status != 0) return status;
00289 while (1) {
00290 status = fclose(fp);
00291 if (status != 0 && errno==EINTR) {
00292 CmiError("Warning: CmiFclose retrying ...\n");
00293 continue;
00294 }
00295 else
00296 break;
00297 }
00298 return status;
00299 }
00300
00301 }
00302
00303
00304 void PUP::toDisk::bytes(void *p,size_t n,size_t itemSize,dataType )
00305 {
00306 if(CmiFwrite(p,itemSize,n,F) != n)
00307 {
00308 error = true;
00309 }
00310 }
00311 void PUP::fromDisk::bytes(void *p,size_t n,size_t itemSize,dataType )
00312 { CmiFread(p,itemSize,n,F);}
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 PUP::seekBlock::seekBlock(PUP::er &Np,int nSections)
00331 :nSec(nSections),p(Np)
00332 {
00333 if (nSections<0 || nSections>maxSections)
00334 CmiAbort("Invalid # of sections passed to PUP::seekBlock!");
00335 p.impl_startSeek(*this);
00336 if (p.isPacking())
00337 {
00338 secTabOff=p.impl_tell(*this);
00339 for (int i=0;i<=nSec;i++) secTab[i]=-1;
00340 }
00341 p(secTab,nSec+1);
00342 hasEnded=false;
00343 }
00344 PUP::seekBlock::~seekBlock()
00345 {
00346 if (!hasEnded)
00347 endBlock();
00348 }
00349
00350 void PUP::seekBlock::seek(int toSection)
00351 {
00352 if (toSection<0 || toSection>=nSec)
00353 CmiAbort("Invalid section # passed to PUP::seekBlock::seek!");
00354 if (p.isPacking())
00355 secTab[toSection]=p.impl_tell(*this);
00356 else if (p.isUnpacking())
00357 p.impl_seek(*this,secTab[toSection]);
00358
00359 }
00360
00361 void PUP::seekBlock::endBlock(void)
00362 {
00363 if (p.isPacking()) {
00364
00365 secTab[nSec]=p.impl_tell(*this);
00366 p.impl_seek(*this,secTabOff);
00367 p(secTab,nSec+1);
00368 }
00369
00370 p.impl_seek(*this,secTab[nSec]);
00371 p.impl_endSeek(*this);
00372 hasEnded=true;
00373 }
00374
00376
00377
00378
00379 void PUP::er::impl_startSeek(PUP::seekBlock &s)
00380 {}
00381 size_t PUP::er::impl_tell(seekBlock &s)
00382 {return 0;}
00383 void PUP::er::impl_seek(seekBlock &s,size_t off)
00384 {}
00385 void PUP::er::impl_endSeek(seekBlock &s)
00386 {}
00387
00388
00389
00390 void PUP::mem::impl_startSeek(seekBlock &s)
00391 {s.data.ptr=buf;}
00392 size_t PUP::mem::impl_tell(seekBlock &s)
00393 {return buf-s.data.ptr;}
00394 void PUP::mem::impl_seek(seekBlock &s,size_t off)
00395 {buf=s.data.ptr+off;}
00396
00397
00398 void PUP::disk::impl_startSeek(seekBlock &s)
00399 {s.data.loff=ftell(F);}
00400 size_t PUP::disk::impl_tell(seekBlock &s)
00401 {return (int)(ftell(F)-s.data.loff);}
00402 void PUP::disk::impl_seek(seekBlock &s,size_t off)
00403 {fseek(F,s.data.loff+off,0);}
00404
00405
00406 void PUP::wrap_er::impl_startSeek(seekBlock &s)
00407 {p.impl_startSeek(s);}
00408 size_t PUP::wrap_er::impl_tell(seekBlock &s)
00409 {return p.impl_tell(s);}
00410 void PUP::wrap_er::impl_seek(seekBlock &s,size_t off)
00411 {p.impl_seek(s,off);}
00412 void PUP::wrap_er::impl_endSeek(seekBlock &s)
00413 {p.impl_endSeek(s);}
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static PUP::able::PUP_ID null_PUP_ID(0);
00432
00433 PUP::able *PUP::able::clone(void) const {
00434
00435 PUP::able *ret=get_constructor(get_PUP_ID()) ();
00436
00437
00438 PUP::able *mthis=(PUP::able *)this;
00439 size_t size;
00440 { PUP::sizer ps; mthis->pup(ps); size=ps.size(); }
00441 void *buf=malloc(size);
00442 { PUP::toMem pt(buf); mthis->pup(pt); }
00443
00444
00445 { PUP::fromMem pf(buf); ret->pup(pf); }
00446 free(buf);
00447
00448 return ret;
00449 }
00450
00451
00452 PUP::able::~able() {}
00453 void PUP::able::pup(PUP::er &p) {}
00454
00455
00456
00457 void PUP::able::PUP_ID::setName(const char *name)
00458 {
00459 int i,o,n=strlen(name);
00460 unsigned int t[len]={0};
00461 for (o=0;o<n;o++)
00462 for (i=0;i<len;i++) {
00463 unsigned char c=name[o];
00464 unsigned int shift1=(((o+2)*(i+1)*5+4)%13);
00465 unsigned int shift2=(((o+2)*(i+1)*3+2)%11)+13;
00466 t[i]+=(c<<shift1)+(c<<shift2);
00467 }
00468 for (i=0;i<len;i++)
00469 hash[i]=(unsigned char)(t[i]%20117 + t[i]%1217 + t[i]%157);
00470 }
00471
00472
00473 class PUP_regEntry {
00474 public:
00475 PUP::able::PUP_ID id;
00476 const char *name;
00477 PUP::able::constructor_function ctor;
00478 PUP_regEntry(const char *Nname,
00479 const PUP::able::PUP_ID &Nid,PUP::able::constructor_function Nctor)
00480 :id(Nid),name(Nname),ctor(Nctor) {}
00481 PUP_regEntry(int zero) {
00482 name=NULL;
00483 }
00484 };
00485
00486 typedef CkHashtableTslow<PUP::able::PUP_ID,PUP_regEntry> PUP_registry;
00487
00488
00489 static PUP_registry *PUP_getRegistry(void) {
00490 static PUP_registry *reg = NULL;
00491 if (reg==NULL)
00492 reg=new PUP_registry();
00493 return reg;
00494 }
00495
00496 const PUP_regEntry *PUP_getRegEntry(const PUP::able::PUP_ID &id)
00497 {
00498 const PUP_regEntry *cur=(const PUP_regEntry *)(
00499 PUP_getRegistry()->CkHashtable::get((const void *)&id) );
00500 if (cur==NULL)
00501 CmiAbort("Unrecognized PUP::able::PUP_ID. is there an unregistered module?");
00502 return cur;
00503 }
00504
00505 PUP::able::PUP_ID PUP::able::register_constructor
00506 (const char *className,constructor_function fn)
00507 {
00508 PUP::able::PUP_ID id(className);
00509 PUP_getRegistry()->put(id)=PUP_regEntry(className,id,fn);
00510 return id;
00511 }
00512
00513 PUP::able::constructor_function PUP::able::get_constructor
00514 (const PUP::able::PUP_ID &id)
00515 {
00516 return PUP_getRegEntry(id)->ctor;
00517 }
00518
00519
00520 void PUP::er::object(able** a)
00521 {
00522 const PUP_regEntry *r=NULL;
00523 if (isUnpacking())
00524 {
00525 PUP::able::PUP_ID id;
00526 id.pup(*this);
00527 if (id==null_PUP_ID) {*a=NULL; return;}
00528 r=PUP_getRegEntry(id);
00529
00530 *a=(r->ctor)();
00531
00532 } else {
00533 if (*a==NULL) {
00534 null_PUP_ID.pup(*this);
00535 return;
00536 } else {
00537 const PUP::able::PUP_ID &id=(*a)->get_PUP_ID();
00538 id.pup(*this);
00539 r=PUP_getRegEntry(id);
00540 }
00541 }
00542 syncComment(PUP::sync_begin_object,r->name);
00543 (*a)->pup(*this);
00544 syncComment(PUP::sync_end_object);
00545 }
00546
00547
00548
00549 char *PUP::toTextUtil::beginLine(void) {
00550
00551 for (int i=0;i<level;i++) cur[i]='\t';
00552 cur[level]=0;
00553 return cur+level;
00554 }
00555 void PUP::toTextUtil::endLine(void) {
00556 cur=advance(cur);
00557 }
00558 void PUP::toTextUtil::beginEnv(const char *type,int n)
00559 {
00560 char *o=beginLine();
00561 sprintf(o,"begin "); o+=strlen(o);
00562 sprintf(o,type,n); o+=strlen(o);
00563 sprintf(o," {\n");
00564 endLine();
00565 level++;
00566 }
00567 void PUP::toTextUtil::endEnv(const char *type)
00568 {
00569 level--;
00570 sprintf(beginLine(),"} end %s;\n",type);
00571 endLine();
00572 }
00573 PUP::toTextUtil::toTextUtil(unsigned int inType,char *buf)
00574 :er(inType)
00575 {
00576 cur=buf;
00577 level=0;
00578 }
00579
00580 void PUP::toTextUtil::comment(const char *message)
00581 {
00582 sprintf(beginLine(),"//%s\n",message); endLine();
00583 }
00584
00585 void PUP::toTextUtil::synchronize(unsigned int m)
00586 {
00587 sprintf(beginLine(),"sync=0x%08x\n",m); endLine();
00588 #if 0
00589 char *o=beginLine();
00590 sprintf(o,"sync=");o+=strlen(o);
00591 const char *consonants="bcdfgjklmprstvxz";
00592 const char *vowels="aeou";
00593 for (int firstBit=0;firstBit<32;firstBit+=6) {
00594 sprintf(o,"%c%c%c", consonants[0xf&(m>>firstBit)],
00595 vowels[0x3&(m>>(firstBit+4))],
00596 (firstBit==30)?';':'-');
00597 o+=strlen(o);
00598 }
00599 sprintf(o,"\n"); endLine();
00600 #endif
00601 }
00602
00603 void PUP::toTextUtil::bytes(void *p,size_t n,size_t itemSize,dataType t) {
00604 if (t==Tchar)
00605 {
00606 char *o=beginLine();
00607 sprintf(o,"string=");o+=strlen(o);
00608 *o++='\"';
00609
00610 const char *c=(const char *)p;
00611 for (size_t i=0;i<n;i++) {
00612 if (c[i]=='\n') {
00613 sprintf(o,"\\n");o+=strlen(o);
00614 } else if (iscntrl(c[i])) {
00615 sprintf(o,"\\x%02X",(unsigned char)c[i]);o+=strlen(o);
00616 } else if (c[i]=='\\' || c[i]=='\"') {
00617 sprintf(o,"\\%c",c[i]);o+=strlen(o);
00618 } else
00619 *o++=c[i];
00620 }
00621
00622 sprintf(o,"\";\n");o+=strlen(o);
00623 endLine();
00624 } else if (t==Tbyte || t==Tuchar)
00625 {
00626 beginEnv("byte %d",n);
00627 const unsigned char *c=(const unsigned char *)p;
00628 char *o=beginLine();
00629 for (size_t i=0;i<n;i++) {
00630 sprintf(o,"%02X ",c[i]);o+=strlen(o);
00631 if (i%25==24 && (i+1!=n))
00632 {
00633 sprintf(o,"\n"); o+=strlen(o);
00634 endLine(); o=beginLine();
00635 }
00636 }
00637 sprintf(o,"\n");
00638 endLine();
00639 endEnv("byte");
00640 }
00641 else
00642 {
00643 if (n!=1) beginEnv("array %d",n);
00644 for (size_t i=0;i<n;i++) {
00645 char *o=beginLine();
00646 switch(t) {
00647 case Tshort: sprintf(o,"short=%d;\n",((short *)p)[i]); break;
00648 case Tushort: sprintf(o,"ushort=%u;\n",((unsigned short *)p)[i]); break;
00649 case Tint: sprintf(o,"int=%d;\n",((int *)p)[i]); break;
00650 case Tuint: sprintf(o,"uint=%u;\n",((unsigned int *)p)[i]); break;
00651 case Tlong: sprintf(o,"long=%ld;\n",((long *)p)[i]); break;
00652 case Tulong: sprintf(o,"ulong=%lu;\n",((unsigned long *)p)[i]); break;
00653 case Tfloat: sprintf(o,"float=%.7g;\n",((float *)p)[i]); break;
00654 case Tdouble: sprintf(o,"double=%.15g;\n",((double *)p)[i]); break;
00655 case Tbool: sprintf(o,"bool=%s;\n",((bool *)p)[i]?"true":"false"); break;
00656 #if CMK_LONG_DOUBLE_DEFINED
00657 case Tlongdouble: sprintf(o,"longdouble=%Lg;\n",((long double *)p)[i]);break;
00658 #endif
00659 #ifdef CMK_PUP_LONG_LONG
00660 case Tlonglong: sprintf(o,"longlong=%lld;\n",((CMK_PUP_LONG_LONG *)p)[i]);break;
00661 case Tulonglong: sprintf(o,"ulonglong=%llu;\n",((unsigned CMK_PUP_LONG_LONG *)p)[i]);break;
00662 #endif
00663 case Tpointer: sprintf(o,"pointer=%p;\n",((void **)p)[i]); break;
00664 default: CmiAbort("Unrecognized pup type code!");
00665 }
00666 endLine();
00667 }
00668 if (n!=1) endEnv("array");
00669 }
00670 }
00671 void PUP::toTextUtil::object(able** a) {
00672 beginEnv("object");
00673 er::object(a);
00674 endEnv("object");
00675 }
00676
00677
00678
00679 char *PUP::sizerText::advance(char *cur) {
00680 charCount+=strlen(cur);
00681 return line;
00682 }
00683
00684 PUP::sizerText::sizerText(void)
00685 :toTextUtil(IS_SIZING+IS_COMMENTS,line),charCount(0) { }
00686
00687
00688 char *PUP::toText::advance(char *cur) {
00689 charCount+=strlen(cur);
00690 return buf+charCount;
00691 }
00692
00693 PUP::toText::toText(char *outBuf)
00694 :toTextUtil(IS_PACKING+IS_COMMENTS,outBuf),buf(outBuf),charCount(0) { }
00695
00696
00697 void PUP::toTextFile::bytes(void *p,size_t n,size_t itemSize,dataType t)
00698 {
00699 for (size_t i=0;i<n;i++)
00700 switch(t) {
00701 case Tchar: fprintf(f," '%c'",((char *)p)[i]); break;
00702 case Tuchar:
00703 case Tbyte: fprintf(f," %02X",((unsigned char *)p)[i]); break;
00704 case Tshort: fprintf(f," %d",((short *)p)[i]); break;
00705 case Tushort: fprintf(f," %u",((unsigned short *)p)[i]); break;
00706 case Tint: fprintf(f," %d",((int *)p)[i]); break;
00707 case Tuint: fprintf(f," %u",((unsigned int *)p)[i]); break;
00708 case Tlong: fprintf(f," %ld",((long *)p)[i]); break;
00709 case Tulong: fprintf(f," %lu",((unsigned long *)p)[i]); break;
00710 case Tfloat: fprintf(f," %.7g",((float *)p)[i]); break;
00711 case Tdouble: fprintf(f," %.15g",((double *)p)[i]); break;
00712 case Tbool: fprintf(f," %s",((bool *)p)[i]?"true":"false"); break;
00713 #if CMK_LONG_DOUBLE_DEFINED
00714 case Tlongdouble: fprintf(f," %Lg",((long double *)p)[i]);break;
00715 #endif
00716 #ifdef CMK_PUP_LONG_LONG
00717 case Tlonglong: fprintf(f," %lld",((CMK_PUP_LONG_LONG *)p)[i]);break;
00718 case Tulonglong: fprintf(f," %llu",((unsigned CMK_PUP_LONG_LONG *)p)[i]);break;
00719 #endif
00720 case Tpointer: fprintf(f," %p",((void **)p)[i]); break;
00721 default: CmiAbort("Unrecognized pup type code!");
00722 };
00723 fprintf(f,"\n");
00724 }
00725 void PUP::toTextFile::comment(const char *message)
00726 {
00727 fprintf(f,"! %s\n",message);
00728 }
00729
00730 void PUP::fromTextFile::parseError(const char *what) {
00731
00732 long cur = ftell(f);
00733 int lineno=0;
00734 rewind(f);
00735 while (!feof(f)) {
00736 char c;
00737 if (fscanf(f,"%c",&c) != 1) {
00738 CmiAbort("PUP> reading text from file failed!");
00739 }
00740 if (c=='\n') lineno++;
00741 if (ftell(f) > cur) break;
00742 }
00743 fprintf(stderr,"Parse error during pup from text file: %s at line: %d\n",what, lineno);
00744 CmiAbort("Parse error during pup from text file!\n");
00745 }
00746 int PUP::fromTextFile::readInt(const char *fmt) {
00747 int ret=0;
00748 if (1!=fscanf(f,fmt,&ret)) {
00749 if (feof(f)) return 0;
00750 else parseError("could not match integer");
00751 }
00752 return ret;
00753 }
00754 unsigned int PUP::fromTextFile::readUint(const char *fmt) {
00755 unsigned int ret=0;
00756 if (1!=fscanf(f,fmt,&ret)) {
00757 if (feof(f)) return 0u;
00758 else parseError("could not match unsigned integer");
00759 }
00760 return ret;
00761 }
00762 CMK_TYPEDEF_INT8 PUP::fromTextFile::readLongInt(const char *fmt) {
00763 CMK_TYPEDEF_INT8 ret=0;
00764 if (1!=fscanf(f,fmt,&ret)) {
00765 if (feof(f)) return 0u;
00766 else parseError("could not match large integer");
00767 }
00768 return ret;
00769 }
00770 double PUP::fromTextFile::readDouble(void) {
00771 double ret=0;
00772 if (1!=fscanf(f,"%lg",&ret)) {
00773 if (feof(f)) return 0.0;
00774 else parseError("could not match double");
00775 }
00776 return ret;
00777 }
00778 void PUP::fromTextFile::bytes(void *p,size_t n,size_t itemSize,dataType t)
00779 {
00780 for (size_t i=0;i<n;i++)
00781 switch(t) {
00782 case Tchar:
00783 if (1!=fscanf(f," '%c'",&((char *)p)[i]))
00784 parseError("Could not match character");
00785 break;
00786 case Tuchar:
00787 case Tbyte: ((unsigned char *)p)[i]=(unsigned char)readInt("%02X"); break;
00788 case Tshort:((short *)p)[i]=(short)readInt(); break;
00789 case Tushort: ((unsigned short *)p)[i]=(unsigned short)readUint(); break;
00790 case Tint: ((int *)p)[i]=readInt(); break;
00791 case Tuint: ((unsigned int *)p)[i]=readUint(); break;
00792 case Tlong: ((long *)p)[i]=readInt(); break;
00793 case Tulong:((unsigned long *)p)[i]=readUint(); break;
00794 case Tfloat: ((float *)p)[i]=(float)readDouble(); break;
00795 case Tdouble:((double *)p)[i]=readDouble(); break;
00796 #if CMK_LONG_DOUBLE_DEFINED
00797 case Tlongdouble: {
00798 long double ret=0;
00799 if (1!=fscanf(f,"%Lg",&ret)) parseError("could not match long double");
00800 ((long double *)p)[i]=ret;
00801 } break;
00802 #endif
00803 #ifdef CMK_PUP_LONG_LONG
00804 case Tlonglong: {
00805 CMK_PUP_LONG_LONG ret=0;
00806 if (1!=fscanf(f,"%lld",&ret)) parseError("could not match long long");
00807 ((CMK_PUP_LONG_LONG *)p)[i]=ret;
00808 } break;
00809 case Tulonglong: {
00810 unsigned CMK_PUP_LONG_LONG ret=0;
00811 if (1!=fscanf(f,"%llu",&ret)) parseError("could not match unsigned long long");
00812 ((unsigned CMK_PUP_LONG_LONG *)p)[i]=ret;
00813 } break;
00814 #endif
00815 case Tbool: {
00816 char tmp[20];
00817 if (1!=fscanf(f," %19s",tmp)) parseError("could not read boolean string");
00818 bool val=false;
00819 if (0==strcmp(tmp,"true")) val=true;
00820 else if (0==strcmp(tmp,"false")) val=false;
00821 else parseError("could not recognize boolean string");
00822 ((bool *)p)[i]=val;
00823 }
00824 break;
00825 case Tpointer: {
00826 void *ret=0;
00827 if (1!=fscanf(f,"%p",&ret)) parseError("could not match pointer");
00828 ((void **)p)[i]=ret;
00829 } break;
00830 default: CmiAbort("Unrecognized pup type code!");
00831 };
00832 }
00833 void PUP::fromTextFile::comment(const char *message)
00834 {
00835 char c;
00836
00837 while (isspace(c=fgetc(f))) {}
00838
00839 if (c!='!') return;
00840
00841 char *commentBuf=(char *)CmiTmpAlloc(1024);
00842 if (fgets(commentBuf,1024,f) == NULL) {
00843 CmiAbort("PUP> skipping over comment in text file failed!");
00844 }
00845 CmiTmpFree(commentBuf);
00846 }
00847
00848
00849
00850
00851
00852
00853