// -*- C++ -*- // // xntuple.cc // N. Regnault - 98-99 // Extended NTuples // #include #include "ppersist.h" #include "perrors.h" #include "xntuple.h" #define LENNAME 31 #define MAXLEN 128 #define BADVAL -1.e19 //++ // Class XNTuple // Lib Outils++ // include xntuple.h // // Classe de ntuples //-- //++ // Links Parents // PPersist // NTupleInterface //-- //++ // Links Voir aussi // NTuple //-- char* XNTuple::glob_swp = NULL ; long int XNTuple::NbNT = 0 ; #ifdef __MWERKS__ // mktemp() non connu sur Mac (?) - Dominique Yvon / R. Ansari char * mktemp(char * Filename); #endif NTBlk::NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz) : sw(0), // pas swappe swoff(-1), ddata(NULL), fdata(NULL), idata(NULL), sdata(NULL) { if(ndvar) ddata = new r_8[ndvar*sz] ; if(nfvar) fdata = new r_4[nfvar*sz] ; if(nivar) idata = new int_4[nivar*sz] ; if(nsvar) sdata = new char[nsvar*(strsz+1)*sz] ; } NTBlk::~NTBlk() { free() ; } void NTBlk::free() { if(ddata) delete[] ddata ; ddata = NULL ; if(fdata) delete[] fdata ; fdata = NULL ; if(idata) delete[] idata ; idata = NULL ; if(sdata) delete[] sdata ; sdata = NULL ; } // // relit bloc ds fichier swap // (seulement si bloc n'est plus en memoire) // void XNTuple::read_blk(NTBlk* blk) const { // deja en memoire ? if( !blk->sw ) return ; blk->free() ; // On va --> blk fseek(swf, blk->swoff, SEEK_SET) ; if(mD) { blk->ddata = new r_8[mD*mBlkSz] ; fread(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ; } if(mF) { blk->fdata = new r_4[mF*mBlkSz] ; fread(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ; } if(mI) { blk->idata = new int_4[mI*mBlkSz] ; fread(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ; } if(mS) { blk->sdata = new char[mS*(mStrSz+1)*mBlkSz] ; fread(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ; } } // // swappe le bloc present en memoire // depuis le + longtemps // void XNTuple::swap() const { // fichier de swap ouvert ? if(!swf) { swf_name = new char[swp.length()+64] ; strncpy(swf_name, swp.c_str(), swp.length()+1) ; strcat(swf_name, "NTupleXXXXXX") ; // swf_name = strdup("NTupleXXXXXX") ; mktemp(swf_name) ; swf = fopen(swf_name, "w+") ; if(!swf) throw IOExc("XNTuple::swap() - Error opening swap File"); } // bloc a swapper NTBlk* blk = sw.front() ; // bloc dans fichiers de swap ? // if( blk->swoff > 0 ) write_blk(blk) ; blk->free() ; blk->sw = 1 ; // on marque le bloc swappe sw.pop_front() ; // on le vire de la liste de swap mNSwBlk++ ; } // // unswap() // void XNTuple::get_blk(int i) const { if(i<0 || i>=mNBlk) return ; read_blk(ptr[i]) ; ptr[i]->sw = 0 ; sw.push_back(ptr[i]) ; mNSwBlk-- ; } // // ecrit le bloc en bout de fichier // (seulement si swoff < 0 ) // void XNTuple::write_blk(NTBlk* blk) const { // deja swappe ? if( blk->swoff >= 0 ) return ; fseek(swf, 0, SEEK_END) ; // position debut du bloc blk->swoff = ftell(swf) ; if(blk->ddata) fwrite(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ; if(blk->fdata) fwrite(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ; if(blk->idata) fwrite(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ; if(blk->sdata) fwrite(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ; } void XNTuple::add_blk() { // l'ancien bloc en ecriture peut maintenant // etre swappe (s'il existe) if(mBlk>=0) sw.push_back(ptr[mBlk]) ; // si pas de place, on swappe if( mNBlk+1 >= mMaxBlk ) swap() ; // nouveau bloc NTBlk* tmp = new NTBlk(mD, mF, mI, mS, mStrSz, mBlkSz) ; ptr.push_back(tmp) ; // mNBlk++ ; // mOff = 0 ; // mBlk++ ; } XNTuple::XNTuple() : mNEnt(0), mNBlk(0), mNSwBlk(0), mBlkSz(0), mBlk(-1), mOff(0), mMaxBlk(0), mStrSz(0), mD(0), mF(0), mI(0), mS(0), mVarD(NULL), mMin(NULL), mMax(NULL), mNVars(0), mNames(NULL), swf(NULL), swf_name(NULL), mInfo(NULL) { if(!glob_swp) SetSwapPath("/tmp/") ; swp = glob_swp ; NbNT++ ; } //++ // Titre Constructeurs //-- //++ // XNTuple(int ndvar, int nfvar, int nivar, int nsvar, char** vnames, - // int blk=512, int maxblk=100, int strsz=30) // Constructeur - Création d'un XNTuple de "ndvar" variables de type "r_8", - // "nfvar" de type "r_4", "nivar" de type "int" et "nsvar" de type - // "char*". //| * "blk" = taille blocs de données (en nombre d'entrées) //| * "maxblk" = nombre max de blocs présents en mémoire (non swappés) //| * "strsz" = taille des données de type char* // XNTuple(XNTuple const& nt) // Constructeur de copie. // XNTuple(string const& flnm) // Constructeur - lecture à partir d'un fichier PPersist. //-- XNTuple::XNTuple(int ndvar, int nfvar, int nivar, int nsvar, char** vnames, int blk, int maxblk, int strsz) : mNEnt(0), mNBlk(0), mNSwBlk(0), mBlkSz(blk), mBlk(-1), mOff(0), mMaxBlk(maxblk), mStrSz(strsz), mD(ndvar), mF(nfvar), mI(nivar), mS(nsvar), mVarD(NULL), mMin(NULL), mMax(NULL), mNVars(ndvar+nfvar+nivar+nsvar), mNames(NULL), swf(NULL), swf_name(NULL), mInfo(NULL) { if(!glob_swp) SetSwapPath("/tmp/") ; swp = glob_swp ; mVarD = new r_8[mNVars] ; mMin = new r_8[mD+mF+mI] ; int i; for(i = 0 ; i < (mD+mF+mI) ; i++) mMin[i] = 9E19 ; mMax = new r_8[mD+mF+mI] ; for(i = 0 ; i < (mD+mF+mI) ; i++) mMax[i] = -9E19 ; if(mNVars) mNames = new char[mNVars*(LENNAME+1)] ; memset(mNames, 0, mNVars*(LENNAME+1)); for(i = 0 ; i < mNVars ; i++) strncpy(mNames+i*(LENNAME+1), vnames[i], LENNAME); NbNT++ ; } XNTuple::XNTuple(string const& flnm) : mNEnt(0), mNBlk(0), mNSwBlk(0), mBlkSz(0), mBlk(-1), mOff(0), mMaxBlk(0), mStrSz(0), mD(0), mF(0), mI(0), mS(0), mVarD(NULL), mMin(NULL), mMax(NULL), mNVars(0), mNames(NULL), swf(NULL), swf_name(NULL), mInfo(NULL) { if(!glob_swp) SetSwapPath("/tmp/") ; swp = glob_swp ; PInPersist s(flnm); ObjFileIO fiont(this); fiont.Read(s); NbNT++ ; } XNTuple::XNTuple(XNTuple const& nt) : mNEnt(0), mNBlk(0), mNSwBlk(0), mBlkSz(0), mBlk(-1), mOff(0), mMaxBlk(0), mStrSz(0), mD(0), mF(0), mI(0), mS(0), mVarD(NULL), mMin(NULL), mMax(NULL), mNVars(0), mNames(NULL), swf(NULL), swf_name(NULL), mInfo(NULL) { if(!glob_swp) SetSwapPath("/tmp/") ; swp = glob_swp ; Copy(nt) ; NbNT++ ; } XNTuple::~XNTuple() { clean() ; NbNT-- ; if(NbNT==0) delete[] glob_swp ; } void XNTuple::clean() { // On libere tous les blocs for(int i = 0 ; i < mNBlk ; i++) if(!ptr[i]->sw) delete ptr[i] ; ptr.erase(ptr.begin(), ptr.end()) ; sw.erase(sw.begin(), sw.end()) ; // on ferme le fichier de swap if(swf) { fclose(swf) ; swf = NULL ; remove(swf_name) ; delete swf_name ; swf_name = NULL ; } // tout le monde remis a 0 mNEnt = 0 ; mNBlk = 0 ; mNSwBlk = 0 ; mBlkSz = 0 ; mBlk = -1 ; mOff = 0 ; mMaxBlk = 0 ; mStrSz = 0 ; mD = 0 ; mF = 0 ; mI = 0 ; mS = 0 ; mNVars = 0 ; if(mVarD) { delete[] mVarD ; mVarD = NULL ; } if(mMin) { delete[] mMin ; mMin = NULL ; } if(mMax) { delete[] mMax ; mMax = NULL ; } if(mNames) {delete[] mNames ; mNames = NULL ; } if (mInfo) delete mInfo; } //++ // Titre Méthodes //-- //++ // void Fill(r_8* d_data, r_4* f_data, int* i_data, char** s_data) // Remplissage d'une ligne dans le NTuple // void Show(ostream& os) const // Impression de la liste des variables avec min-max sur le flot "os" // void Show() const // Identique à "Show(cout)" // XNTuple& operator = (XNTuple const& nt) // Opérateur égal (=) , copie "nt" dans le premier NTuple //-- void XNTuple::Fill(r_8* d_data, r_4* f_data, int_4* i_data, char** s_data) { // place disponible dans bloc courant ? if( mOff==mBlkSz || mOff==0 ) { add_blk() ; mOff = 0 ; mNBlk++ ; mBlk++ ; } if( mD && !ptr[mBlk]->ddata || mF && !ptr[mBlk]->fdata || mI && !ptr[mBlk]->idata || mS && !ptr[mBlk]->sdata ) throw ParmError("XNTuple::Fill(...) Missing (NULL) argument "); r_8 x ; // copie variables et update mMin, mMax if(mD) { memcpy(ptr[mBlk]->ddata+mOff*mD, d_data, mD*sizeof(r_8)) ; for(int i = 0 ; i < mD ; i++) { x = d_data[i] ; if(xmMax[i]) mMax[i] = x ; } } if(mF) { memcpy(ptr[mBlk]->fdata+mOff*mF, f_data, mF*sizeof(r_4)) ; for(int i = 0 ; i < mF ; i++) { x = f_data[i] ; if(xmMax[i+mD]) mMax[i+mD] = x ; } } if(mI) { memcpy(ptr[mBlk]->idata+mOff*mI, i_data, mI*sizeof(int_4)) ; for(int i = 0 ; i < mI ; i++) { x = i_data[i] ; if(xmMax[i+mD+mF]) mMax[i+mD+mF] = x ; } } for(int i = 0 ; i < mS ; i++) memcpy(ptr[mBlk]->sdata+(mOff*mS+i)*(mStrSz+1), s_data[i], (strlen(s_data[i])+1)*sizeof(char)) ; mOff++ ; mNEnt++ ; } // // A quel index correspond mon nom ? // int XNTuple::IndexNom(char const* nom) const { int i ; for(i = 0 ; i < (mD+mF+mI+mS) ; i++) if( !strncmp( mNames+i*(LENNAME+1), nom, LENNAME+1) ) return i ; return -1 ; } string XNTuple::NomIndex(int k) const { if( k<0 || k>=mNVars ) return "" ; return mNames + k*(LENNAME+1) ; } // // // r_8 XNTuple::GetDVal(int i, int k) const { if( i<0 || i>=mNEnt || k<0 || k>=mD ) throw RangeCheckError("XNTuple::GetDVal() Invalid line/column index"); // Bloc ? int blk = (int)(i/mBlkSz) ; int off = i%mBlkSz ; // bloc swappe ? if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } return ptr[blk]->ddata[off*mD+k] ; } // // // r_4 XNTuple::GetFVal(int i, int k) const { if( i<0 || i>=mNEnt || k=(mD+mF) ) throw RangeCheckError("XNTuple::GetFVal() Invalid line/column index"); k -= mD ; // Bloc ? int blk = (int)(i/mBlkSz) ; int off = i%mBlkSz ; // bloc swappe ? if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } return ptr[blk]->fdata[off*mF+k] ; } // // // int_4 XNTuple::GetIVal(int i, int k) const { if( i<0 || i>=mNEnt || k<(mD+mF) || k>=(mD+mF+mI) ) throw RangeCheckError("XNTuple::GetIVal() Invalid line/column index"); k -= (mD+mF) ; // Bloc ? int blk = (int)(i/mBlkSz) ; int off = i%mBlkSz ; // bloc swappe ? if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } return ptr[blk]->idata[off*mI+k] ; } // // // string XNTuple::GetSVal(int i, int k) const { if( i<0 || i>=mNEnt || k<(mD+mF+mI) || k>=(mD+mF+mI+mS) ) throw RangeCheckError("XNTuple::GetSVal() Invalid line/column index"); k -= (mD+mF+mI) ; // Bloc ? int blk = (int)(i/mBlkSz) ; int off = i%mBlkSz ; // bloc swappe ? if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } // copie de la chaine // string ret = strdup(ptr[blk]->sdata + (off*mS+k)*(mStrSz+1)) ; // $CHECK$ EA fuite de memoire // attention, strdup fait un malloc et on ne fait jamais de free... // a quoi sert ce strdup ????????? string ret = ptr[blk]->sdata + (off*mS+k)*(mStrSz+1) ; // return ptr[blk]->sdata[k] ; return ret ; } // // Copie bloc a bloc, avec meme parametres // void XNTuple::Copy(XNTuple const& nt) { clean() ; // Parametres mNEnt = nt.mNEnt ; mBlkSz = nt.mBlkSz ; mOff = nt.mOff ; mMaxBlk = nt.mMaxBlk ; mStrSz = nt.mStrSz ; mD = nt.mD ; mF = nt.mF ; mI = nt.mI ; mS = nt.mS ; mNVars = nt.mNVars ; // noms if(mNVars) { mNames = new char[mNVars*(LENNAME+1)] ; mVarD = new r_8[mNVars]; memcpy(mNames, nt.mNames, mNVars*(LENNAME+1)*sizeof(char)) ; } // MinMax if(nt.mMin) { mMin = new r_8[(mD+mF+mI)] ; memcpy(mMin, nt.mMin, (mD+mF+mI)*sizeof(r_8)) ; } if(nt.mMax) { mMax = new r_8[(mD+mF+mI)] ; memcpy(mMax, nt.mMax, (mD+mF+mI)*sizeof(r_8)) ; } //dup blocs mNBlk = 0 ; mBlk = -1 ; for(int i = 0 ; i < nt.mNBlk ; i++) { add_blk() ; mBlk++ ; mNBlk++ ; // si nt.ptr[i] swappe, on le relit if(nt.ptr[i]->sw) nt.read_blk(nt.ptr[i]) ; if(mD) memcpy(ptr[i]->ddata, nt.ptr[i]->ddata, mD*mBlkSz*sizeof(r_8)) ; if(mF) memcpy(ptr[i]->fdata, nt.ptr[i]->fdata, mF*mBlkSz*sizeof(r_4)) ; if(mI) memcpy(ptr[i]->idata, nt.ptr[i]->idata, mF*mBlkSz*sizeof(int_4)) ; if(mS) memcpy(ptr[i]->sdata, nt.ptr[i]->sdata, mS*mBlkSz*sizeof(char)*(mStrSz+1)) ; if(nt.ptr[i]->sw) nt.ptr[i]->free() ; } // DVList Info block if(nt.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(nt.mInfo);} } //++ // DVList& Info() // Renvoie une référence sur l'objet DVList Associé //-- DVList& XNTuple::Info() { if (mInfo == NULL) mInfo = new DVList; return(*mInfo); } void XNTuple::Print(int num, int nmax) const { printf("XNTuple::Print() : \n") ; printf(" Entrees = %d, Blocs = %d, Bloc Size = %d\n", mNEnt, mNBlk, mBlkSz) ; int i,j; printf(" D_Vars = %d : ", mD) ; for(i = 0 ; i < mD ; i++) printf("%s ", NomIndex(i).c_str() ) ; printf("\n") ; printf(" F_Vars = %d : ", mF) ; for(i = 0 ; i < mF ; i++) printf("%s ", NomIndex(i+mD).c_str() ) ; printf("\n") ; printf(" I_Vars = %d : ", mI) ; for(i = 0 ; i < mI ; i++) printf("%s ", NomIndex(i+mD+mF).c_str() ) ; printf("\n") ; printf(" S_Vars = %d : ", mS) ; for(i = 0 ; i < mS ; i++) printf("%s ", NomIndex(i+mD+mF+mI).c_str() ) ; printf("\n") ; for(i = num ; i < num+nmax ; i++) { for(j = 0 ; j < mD ; j++) printf("%f ", GetDVal(i,j)) ; printf(" -- ") ; for(j = 0 ; j < mF ; j++) printf("%f ", GetFVal(i,j+mD)) ; printf(" -- ") ; for(j = 0 ; j < mI ; j++) printf("%d ", GetIVal(i,j+mD+mF)) ; printf(" -- ") ; for(j = 0 ; j < mS ; j++) printf("%s ", GetSVal(i,j+mD+mF+mI).c_str()) ; printf("\n") ; } } void XNTuple::Show(ostream& os) const { os << "XNTuple: NVar= " << mNVars << " NEnt= " << mNEnt << " (BlkSz,NBlk= " << mBlkSz << ", " << mNBlk << ")" << " (mNSwBlk= " << mNSwBlk << ")" << endl ; os << "(Sw File= " ; if(swf_name) os << swf_name ; os << ")" << endl ; char* buff = new char[80] ; sprintf(buff, "Variables : Type Min Max \n") ; os << buff ; r_8 min, max ; int i; for(i = 0 ; i < mD ; i++) { GetMinMax(i, min, max) ; sprintf(buff, " %-10s: D %12.6g %12.6g \n", NomIndex(i).c_str(), min, max) ; os << buff ; } for(i = 0 ; i < mF ; i++) { GetMinMax(i+mD, min, max) ; sprintf(buff, " %-10s: F %12.6g %12.6g \n", NomIndex(i+mD).c_str(), min, max) ; os << buff ; } for(i = 0 ; i < mI ; i++) { GetMinMax(i+mD+mF, min, max) ; sprintf(buff, " %-10s: I %12.6g %12.6g \n", NomIndex(i+mD+mF).c_str(), min, max) ; os << buff ; } for(i = 0 ; i < mS ; i++) { sprintf(buff, " %-10s: S ----- ----- \n", NomIndex(i+mD+mF+mI).c_str()) ; os << buff ; } delete[] buff ; } int XNTuple::FillFromASCIIFile(string const& fn, r_8 ddval, r_4 dfval, int dival, const char * dsval) // Remplit le ntuple a partir d'un fichier ASCII. // Renvoie le nombre de lignes ajoutees. { // a faire return(0); } void XNTuple::SetSwapPath(char* p) { if(!glob_swp) glob_swp = new char[MAXLEN+1] ; strncpy(glob_swp, p, MAXLEN) ; } // // // Interface NTuple // // uint_4 XNTuple::NbLines() const { return(NEntry()); } uint_4 XNTuple::NbColumns() const { return(NVar()); } r_8* XNTuple::GetLineD(int n) const { // memcpy() impossible // il faut faire des GetVal int i; for(i = 0 ; i < mD ; i++) mVarD[i] = GetDVal(n, i) ; for(i = 0 ; i < mF ; i++) mVarD[i+mD] = (r_8)GetFVal(n, i+mD) ; for(i = 0 ; i < mI ; i++) mVarD[i+mD+mF] = (r_8)GetIVal(n, i+mD+mF) ; for(i = 0 ; i < mS ; i++) mVarD[i+mD+mF+mI] = atof(GetSVal(n, i+mD+mF+mI).c_str()) ; return mVarD ; } r_8 XNTuple::GetCell(int n, int k) const { if( k<0 || k>=(mD+mF+mI+mS) ) return BADVAL ; if(k=(mD+mF+mI) ) return ; min = mMin[k] ; max = mMax[k] ; return ; } void XNTuple::GetMinMax(string const & nom, double& min, double& max) const { GetMinMax(IndexNom(nom.c_str()), min, max) ; } int XNTuple::ColumnIndex(string const& nom) const { return IndexNom(nom.c_str()) ; } string XNTuple::ColumnName(int k) const { return NomIndex(k) ; } string XNTuple::VarList_C(const char* nomx) const { string rets = "" ; rets += "/* r_8 type variables */ \n"; // variables r_8 int i; for(i = 0 ; i < mD ; i++) { if( i>0 && (i%5)==0 ) rets += ";" ; if( (i%5)==0 ) rets+="\ndouble " ; else rets += ", " ; rets += NomIndex(i) ; } if(mD) rets += ";" ; // variables r_4 rets += "/* r_4 type variables */ \n"; for(i = 0 ; i < mF ; i++) { if( i>0 && (i%5)==0 ) rets += ";" ; if( (i%5)==0 ) rets+="\ndouble " ; else rets += ", " ; rets += NomIndex(i+mD) ; } if(mF) rets += ";" ; // variables int rets += "/* int type variables */ \n"; for(i = 0 ; i < mI ; i++) { if( i>0 && (i%5)==0 ) rets += ";" ; if( (i%5)==0 ) rets+="\ndouble " ; else rets += ", " ; rets += NomIndex(i+mD+mF) ; } if(mI) rets += ";" ; // variables string rets += "/* string type variables */ \n"; for(i = 0 ; i < mS ; i++) { if( i>0 && (i%5)==0 ) rets += ";" ; if( (i%5)==0 ) rets+="\ndouble " ; else rets += ", " ; rets += NomIndex(i+mD+mF+mI) ; } rets += "; \n" ; if(nomx) { char buff[256] ; for(i = 0 ; i < mNVars ; i++) { sprintf(buff, "%s=%s[%d]; ", NomIndex(i).c_str(), nomx, i) ; rets+=buff ; if( (i%3 == 0) && (i>0) ) rets += "\n" ; } } return rets ; } string XNTuple::LineHeaderToString() const { char buff[32]; string rets=" Num "; for(int i=0; i::WriteSelf(POutPersist& ppout) const { if (dobj == NULL) return; // On ecrit 3 uint_4 .... // 0: Numero de version, 1 : non nul -> has info, 2 : reserve uint_4 itab[3]; itab[0] = 1; // Numero de version a 1 itab[1] = itab[2] = 0; if (dobj->mInfo) itab[1] = 1; ppout.Put(itab,3); if (dobj->mInfo) if (dobj->mInfo) ppout << (*(dobj->mInfo)); // variables internes ppout.PutI4(dobj->mNEnt) ; ppout.PutI4(dobj->mNBlk) ; ppout.PutI4(dobj->mBlkSz) ; ppout.PutI4(dobj->mBlk) ; ppout.PutI4(dobj->mOff) ; ppout.PutI4(dobj->mMaxBlk) ; ppout.PutI4(dobj->mStrSz) ; ppout.PutI4(dobj->mD) ; ppout.PutI4(dobj->mF) ; ppout.PutI4(dobj->mI) ; ppout.PutI4(dobj->mS) ; ppout.PutI4(dobj->mNVars) ; // Noms ppout.PutBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; // MinMax ppout.PutR8s(dobj->mMin, (dobj->mD+dobj->mF+dobj->mI)) ; ppout.PutR8s(dobj->mMax, (dobj->mD+dobj->mF+dobj->mI)) ; // Ecriture blocs N'ecrire que si datas existent for(int i = 0 ; i < dobj->mNBlk ; i++) { // si bloc swappe, on le relit en douce ... if( dobj->ptr[i]->sw ) dobj->read_blk(dobj->ptr[i]) ; ppout.PutR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; ppout.PutR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; ppout.PutI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; ppout.PutBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; if(dobj->ptr[i]->sw) dobj->ptr[i]->free() ; } } void ObjFileIO::ReadSelf(PInPersist& ppin) { if (dobj == NULL) dobj = new XNTuple; else dobj->clean() ; // On lit 3 uint_4 .... // 0: Numero de version, 1 : non nul -> has info, 2 : reserve uint_4 itab[3]; ppin.Get(itab,3); if (itab[1] != 0) { // Lecture eventuelle du DVList Info if (dobj->mInfo == NULL) dobj->mInfo = new DVList; ppin >> (*(dobj->mInfo)); } ppin.GetI4(dobj->mNEnt) ; ppin.GetI4(dobj->mNBlk) ; ppin.GetI4(dobj->mBlkSz) ; ppin.GetI4(dobj->mBlk) ; ppin.GetI4(dobj->mOff) ; ppin.GetI4(dobj->mMaxBlk) ; ppin.GetI4(dobj->mStrSz) ; ppin.GetI4(dobj->mD) ; ppin.GetI4(dobj->mF) ; ppin.GetI4(dobj->mI) ; ppin.GetI4(dobj->mS) ; ppin.GetI4(dobj->mNVars) ; // Noms dobj->mNames = new char[dobj->mNVars*(LENNAME+1)] ; dobj->mVarD = new r_8[dobj->mNVars]; ppin.GetBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; // MinMax dobj->mMin = new r_8[dobj->mD+dobj->mF+dobj->mI] ; ppin.GetR8s(dobj->mMin, dobj->mD+dobj->mF+dobj->mI) ; dobj->mMax = new r_8[dobj->mD+dobj->mF+dobj->mI] ; ppin.GetR8s(dobj->mMax, dobj->mD+dobj->mF+dobj->mI) ; // lecture Blocs int nblk = dobj->mNBlk ; dobj->mBlk = -1 ; dobj->mNBlk = 0 ; for(int i = 0 ; i < nblk ; i++) { dobj->add_blk() ; dobj->mBlk++ ; dobj->mNBlk++ ; ppin.GetR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; ppin.GetR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; ppin.GetI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; ppin.GetBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; } } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template ObjFileIO #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class ObjFileIO; #endif #ifdef __MWERKS__ // Bricolo Dominique Yvon pour faire marcher sur Mac #include #include static long mktempMemory=0; char * mktemp(char * Filename) { sprintf(Filename,"TempFile%8i",mktempMemory); mktempMemory++; return Filename; } #endif