// -*- C++ -*- // // xntuple.cc // N. Regnault - 98-99 // Extended NTuples // #include #include "sopnamsp.h" #include "ppersist.h" #include "perrors.h" #include "xntuple.h" #ifdef OS_MACOSX #include #endif #define LENNAME 31 #define MAXLEN 128 #define BADVAL -1.e19 /*! \class SOPHYA::XNTuple \ingroup HiStats NTuple class (a Table or 2-D data set) with the possibility of having columns with int, float or string type content. In addition, this class can handle large data sets, using swap space on disk. \sa SOPHYA::BaseDataTable SOPHYA::DataTable SOPHYA::SwPPFDataTable \deprecated This class is being deprecated. Use classes derived from SOPHYA::BaseDataTable whenever possible \code #include "xntuple.h" // ... char * names[4] = {"X", "X2", "XInt","XStr"}; // XNTuple (Table) creation with 4 columns, of integer, // double(2) and string type XNTuple xnt(2,0,1,1, names); // Filling the NTuple r_8 xd[2]; int_4 xi[2]; char xss[2][32]; char * xs[2] = {xss[0], xss[1]} ; for(int i=0; i<50; i++) { xi[0] = i; xd[0] = i+0.5; xd[1] = xd[0]*xd[0]; sprintf(xs[0],"X=%g", xd[0]); xnt.Fill(xd, NULL, xi, xs); } // Printing table info cout << xnt ; // Saving object into a PPF file POutPersist po("xnt.ppf"); po << xnt ; \endcode */ //++ // 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() ; 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. //-- //! Constructor with specification colum types and names /*! \param ndvar : Number of columns with type double (r_8) \param nfvar : Number of columns with type float (r_4) \param nivar : Number of columns with type integer (int_4) \param nsvar : Number of columns with type string \param vnames : Column names (in the order r_8 r_4 int_4 string) (colum names are limited to 31 characters) \param blk : data block size (in number of table lines) \param maxblk : Maximum number of data block in memory \param strsz : string length (for string type columns) */ 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() ; 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++ ; } //! Constructor with table initialized from a PPF file 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() ; swp = glob_swp ; PInPersist s(flnm); ObjFileIO fiont(this); fiont.Read(s); NbNT++ ; } //! Copy constructor - Copies the table definition and associated data 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() ; swp = glob_swp ; Copy(nt) ; NbNT++ ; } XNTuple::~XNTuple() { clean() ; NbNT-- ; if(NbNT==0) {delete[] glob_swp ; glob_swp = NULL;} } //! Clear the data table definition and deletes the associated data 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 //-- //! Appends an entry (line) to the table /*! \param d_data : double (r_8) line elements \param f_data : float (r_4) line elements \param i_data : integer (int_4) line elements \param s_data : string line elements */ 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é //-- //! Returns the associated DVList object 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") ; } } //! Prints table definition and number of entries 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 ; } //! NOT YET IMPLEMENTED ! - Fills table from an ascii file 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); } //! Defines swap file path for XNTuple objects (Default=$TMPDIR or /tmp/) void XNTuple::SetSwapPath(char* p) { if (p == NULL) { p = getenv("TMPDIR"); if (p == NULL) p = "/tmp/"; } if(!glob_swp) glob_swp = new char[MAXLEN+2] ; strncpy(glob_swp,p,MAXLEN); if(glob_swp[strlen(glob_swp)] != '/') strcat(glob_swp,"/"); } // // // Interface NTuple // // sa_size_t XNTuple::NbLines() const { return(NEntry()); } sa_size_t XNTuple::NbColumns() const { return(NVar()); } r_8* XNTuple::GetLineD(sa_size_t 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(sa_size_t n, sa_size_t 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) ; } sa_size_t XNTuple::ColumnIndex(string const& nom) const { return IndexNom(nom.c_str()) ; } string XNTuple::ColumnName(sa_size_t 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) ; } if(mS) 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 \ingroup HiStats Persistence (serialisation) handler for class XNTuple */ DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void ObjFileIO::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() ; } } DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ 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 SOPHYA::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