Index: trunk/SophyaExt/FitsIOServer/fitshdtable.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 2880)
+++ trunk/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 2889)
@@ -10,6 +10,5 @@
 #include "fitsblkrw.h"
 #include "fitshandler.h"
-
-// #include "fitshdtable.h"
+#include "swfitsdtable.h"
 
 DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
@@ -18,5 +17,7 @@
   if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
   string key = "SOPCLSNM"; 
-  if (is.KeyValue(key) == "SOPHYA::DataTable")  return 2;
+  string clsnm = is.KeyValue(key);
+  if ( (clsnm == "SOPHYA::DataTable") || (clsnm == "SOPHYA::SwFitsDataTable") )
+    return 2;
   else return 1;
 }
@@ -30,8 +31,13 @@
 
   DataTable* dt = dynamic_cast< DataTable *> (dobj);
-  if (dt == NULL) 
-    throw FitsIOException("FitsHandler<DataTable>::Write() Not a DataTable object");
-  
+  SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
+
   int tbltyp = os.GetDef_TableType();
+  if ( swfdt && (tbltyp == ASCII_TBL) )
+    throw FitsIOException("FitsHandler<DataTable>::Write() ASCII_TBL not supported for SwFitsDataTable");
+
+  // On ne reecrit pas la definition d'une SwFitsDataTable dans son fichier de swap
+  if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) && swfdt->NRows() )  return;
+
   string strcoltag;
   long strwidth = os.GetDef_StrColWidth(); 
@@ -102,4 +108,7 @@
   string extname = os.NextExtensionName();
   os.CreateTable(os.GetDef_TableType(), extname, colnames, tform, tunit);
+
+  // On n'ecrit pas les donnees d'une table SwFitsDataTable ds son fichier de swap 
+  if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) )  return;
 
   // Ecriture des donnees des colonnes
@@ -117,15 +126,15 @@
 	icol++;
 	FitsBlockRW<int_4>::WriteColumnData(os, icol, l+1, 1, 
-					    dt->mICols[sk].GetCstSegment(iseg), sz);
+					    dobj->mIColsP[sk]->GetCstSegment(iseg), sz);
 	break;
       case BaseDataTable::LongField :
 	icol++;
 	FitsBlockRW<int_8>::WriteColumnData(os, icol, l+1, 1, 
-					    dt->mLCols[sk].GetCstSegment(iseg), sz);
+					    dobj->mLColsP[sk]->GetCstSegment(iseg), sz);
 	break;
       case BaseDataTable::FloatField :
 	icol++;
 	FitsBlockRW<r_4>::WriteColumnData(os, icol, l+1, 1, 
-					  dt->mFCols[sk].GetCstSegment(iseg), sz);
+					  dobj->mFColsP[sk]->GetCstSegment(iseg), sz);
 	break;
       case BaseDataTable::DoubleField :
@@ -133,5 +142,5 @@
 	icol++;
 	FitsBlockRW<r_8>::WriteColumnData(os, icol, l+1, 1, 
-					  dt->mDCols[sk].GetCstSegment(iseg), sz);
+					  dobj->mDColsP[sk]->GetCstSegment(iseg), sz);
 	break;
       case BaseDataTable::ComplexField :
@@ -139,5 +148,5 @@
 	  icol++;
 	  FitsBlockRW< complex<r_4> >::WriteColumnData(os, icol, l+1, 1, 
-						       dt->mYCols[sk].GetCstSegment(iseg), sz);
+						       dobj->mYColsP[sk]->GetCstSegment(iseg), sz);
 	}
 	break;
@@ -146,5 +155,5 @@
 	  icol++;
 	  FitsBlockRW< complex<r_8> >::WriteColumnData(os, icol, l+1, 1, 
-						       dt->mZCols[sk].GetCstSegment(iseg), sz);
+						       dobj->mZColsP[sk]->GetCstSegment(iseg), sz);
 	}
 	break;
@@ -152,5 +161,5 @@
 	icol++;
 	FitsBlockRW<std::string>::WriteColumnData(os, icol, l+1, 1, 
-						  dt->mSCols[sk].GetCstSegment(iseg), sz);
+						  dobj->mSColsP[sk]->GetCstSegment(iseg), sz);
 	break;
       default:
@@ -159,6 +168,6 @@
     }
   }
-  // Ecriture de SegmentSize et autre elements de DVList
-  
+
+  // Ecriture de SegmentSize et autre elements de DVList  
   os.WriteHeaderRecords(dobj->Info());
   MuTyV mtv = dobj->SegmentSize();
@@ -178,4 +187,5 @@
     throw FitsIOException("FitsHandler<DataTable>::Read() Not a binary or ascii table HDU");
 
+  // Determination de la taille de segment 
   sa_size_t segsz = is.GetNbRows() / 16; // Taille de segment par defaut 
   if (segsz > 2048) segsz = 2048;
@@ -186,17 +196,5 @@
   if (segsz < 16) segsz = 16;
 
-  if (dobj == NULL) { // On cree la table si besoin 
-    dobj = new DataTable(segsz);
-  }
-  else { 
-    dobj->Clear();  // On efface la table sinon 
-    dobj->mSegSz = segsz;
-  }
-
-  // On gere les DataTable pour le moment ... 
-  DataTable* dt = dynamic_cast< DataTable *> (dobj);
-  if (dt == NULL) 
-    throw FitsIOException("FitsHandler<DataTable>::Read() Not a DataTable object");
-  
+  // Nb de lignes et de colonnes 
   vector<string> colnames;
   vector<int> coltypes;
@@ -204,4 +202,34 @@
   vector<long> colpos;
   is.GetColInfo(colnames, coltypes, repcnt, width);
+  long nbrows = is.GetNbRows();
+
+  if (dobj == NULL) { // On cree la table si besoin 
+    string key = "SOPCLSNM"; 
+    string clsnm = is.KeyValue(key);
+    if ( (clsnm == "SOPHYA::SwFitsDataTable") || (nbrows*colnames.size() < 10000000) )
+      dobj = new DataTable(segsz);
+    else dobj = new SwFitsDataTable(is, segsz, false);
+  }
+  else { 
+    dobj->Clear();  // On efface la table sinon 
+    dobj->mSegSz = segsz;
+  }
+
+  // Type reel de table
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
+
+  vector<int_8> swpos;
+  // Initialize the fits swap stream for SwFitsDataTable if necessary
+  if (swfdt)  {
+    if ( swfdt->FitsSwapFile().FitsPtr() != is.FitsPtr() )
+      swfdt->FitsSwapFile().ShareFitsPtr(is); 
+    int_8 swp = 1;
+    
+    while (swp < nbrows) {
+      swpos.push_back(swp); swp += segsz;
+    }
+  }
+
   // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment 
   for(sa_size_t k=0; k<colnames.size(); k++) { 
@@ -211,5 +239,7 @@
     case TUSHORT :
     case TINT :
-      dt->AddIntegerColumn(colnames[k]);
+      if (swfdt) 
+	swfdt->AddColRd(BaseDataTable::IntegerField, colnames[k], k+1, &swpos);
+      else dobj->AddIntegerColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
@@ -219,26 +249,38 @@
 #ifdef TLONGLONG
     case TLONGLONG :
-#endif      
-      dt->AddLongColumn(colnames[k]);
+#endif 
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::LongField, colnames[k], k+1, &swpos);     
+      else dobj->AddLongColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
     case TFLOAT :
-      dt->AddFloatColumn(colnames[k]);
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::FloatField, colnames[k], k+1, &swpos);     
+      else dobj->AddFloatColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
     case TDOUBLE :
-      dt->AddDoubleColumn(colnames[k]);
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::DoubleField, colnames[k], k+1, &swpos);     
+      else dobj->AddDoubleColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
     case TCOMPLEX :
-      dt->AddComplexColumn(colnames[k]);
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::ComplexField, colnames[k], k+1, &swpos);     
+      else dobj->AddComplexColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
     case TDBLCOMPLEX :
-      dt->AddDoubleComplexColumn(colnames[k]);
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::DoubleComplexField, colnames[k], k+1, &swpos);     
+      else dobj->AddDoubleComplexColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
     case TSTRING :
-      dt->AddStringColumn(colnames[k]);
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::StringField, colnames[k], k+1, &swpos);     
+      else dobj->AddStringColumn(colnames[k]);
       colpos.push_back(k+1);
       break;
@@ -252,4 +294,10 @@
   // ------- Mise a jour des champs Nb d'entrees, nb segments ...
   dobj->mNEnt = is.GetNbRows();
+  // Lecture DVList  (=entete FITS) 
+  is.GetHeaderRecords(dobj->Info());
+
+  // On ne doit pas lire les donnees de la table pour un SwFitsDataTable
+  if (swfdt)  return;
+
   while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
     dobj->Extend();
@@ -270,30 +318,30 @@
       case BaseDataTable::IntegerField :
 	FitsBlockRW<int_4>::ReadColumnData(is, icol, l+1, 1, 
-					    dt->mICols[sk].GetSegment(iseg), sz);
+					    dobj->mIColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::LongField :
 	FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1, 
-					   dt->mLCols[sk].GetSegment(iseg), sz);
+					   dobj->mLColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::FloatField :
 	FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1, 
-					 dt->mFCols[sk].GetSegment(iseg), sz);
+					 dobj->mFColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::DoubleField :
       case BaseDataTable::DateTimeField :
 	FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1, 
-					 dt->mDCols[sk].GetSegment(iseg), sz);
+					 dobj->mDColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::ComplexField :
 	FitsBlockRW< complex<r_4> >::ReadColumnData(is, icol, l+1, 1, 
-						    dt->mYCols[sk].GetSegment(iseg), sz);
+						    dobj->mYColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::DoubleComplexField :
 	FitsBlockRW< complex<r_8> >::ReadColumnData(is, icol, l+1, 1, 
-						    dt->mZCols[sk].GetSegment(iseg), sz);
+						    dobj->mZColsP[sk]->GetSegment(iseg), sz);
 	break;
       case BaseDataTable::StringField :
 	FitsBlockRW<std::string>::ReadColumnData(is, icol, l+1, 1, 
-						 dt->mSCols[sk].GetSegment(iseg), sz);
+						 dobj->mSColsP[sk]->GetSegment(iseg), sz);
 	break;
       default:
@@ -303,7 +351,4 @@
   }
 
-  // Mise a jour nombre d'entree 
-  // Lecture DVList   
-  is.GetHeaderRecords(dobj->Info());
 }
 
Index: trunk/SophyaExt/FitsIOServer/swfitsdtable.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/swfitsdtable.cc	(revision 2880)
+++ trunk/SophyaExt/FitsIOServer/swfitsdtable.cc	(revision 2889)
@@ -1,3 +1,4 @@
 #include "swfitsdtable.h"
+#include "fitshdtable.h"
 #include "sopnamsp.h"
 #include "pexceptions.h"
@@ -19,4 +20,7 @@
    - It is not possible to make a complete (deep) copy of a SwFitsDataTable
    Copy constructor and equal operator shares the data.
+   - The min/max values for column data are not updated when reading from a fits file.
+   In this case, the Show() method (or ostream& << operator) will compute min/max 
+   values. This operation will take some time for large tables.
 
    \sa SOPHYA::MuTyV
@@ -26,11 +30,11 @@
 
    \code
-   #include "swppfdtable.h"
+   #include "swfitsdtable.h"
    // ...
    {
    // ---- Creation of the table
    // Create the swap stream 
-   POutPersist so("myswtable.ppf");
-   SwFitsDataTable dt(so, 64);
+   FitsInOutFile so("myswtable.fits", FitsInOutFile::Fits_Create);
+   SwFitsDataTable dt(so, 16);
    // define table columns
    dt.AddFloatColumn("X0_f");
@@ -38,5 +42,5 @@
    dt.AddDoubleColumn("X0X0pX1X1_d");
    // Fill the table
-   MuTyV x[5];
+   r_8 x[5];
    for(int i=0; i<63; i++) {
      x[0] = (i%9)-4.;  x[1] = (i/9)-3.;  x[2] = x[0]*x[0]+x[1]*x[1];
@@ -45,14 +49,15 @@
    // Printing table info
    cout << dt ;
-   // Swap out all data and write the table structure to the PPF stream 
-   so << dt ;
-   // ....
+   // The destructor will Swap out  data still in memory 
    }
    {
    // ---- Accessing information from a previously created table
    SwFitsDataTable dt;
-   PInPersist si("myswtable.ppf");
+   FitsInOutFile si("myswtable.fits", FitsInOutFile::Fits_ReadOnly);
+   // Position the fits file on the first extension (BinTable)
+   si.MoveAbsToHDU(2);  
+   // Reading in the table (initialisation) 
    si >> dt;
-   // Printing table info
+   // Printing table info 
    cout << dt ;   
    }
@@ -72,4 +77,8 @@
     mSwF(os) , mFgCreate(fgcreate)
 {
+  if (!fgcreate) {   // Lecture de la table 
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Read(os);
+  }
 }
 //! copy constructor - shares the data
@@ -83,5 +92,13 @@
 SwFitsDataTable::~SwFitsDataTable()
 {
-  if (mFgCreate) SwapOutAll();
+  if (mFgCreate) { 
+    SwapOutAll();
+    // Ecriture de SegmentSize et autre elements de DVList  
+    mSwF.WriteHeaderRecords(Info());
+    MuTyV mtv = SegmentSize();
+    mSwF.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
+    mtv = "SOPHYA::SwFitsDataTable";
+    mSwF.WriteKey("SOPCLSNM",mtv," Object class name "); 
+  }
 }
 
@@ -213,13 +230,4 @@
   mSCols.clear();
 
-  /*
-  mISwapper.clear();
-  mLSwapper.clear();
-  mFSwapper.clear();
-  mDSwapper.clear();
-  mYSwapper.clear();
-  mZSwapper.clear();
-  mSSwapper.clear();
-  */
 }
 
@@ -232,5 +240,5 @@
 sa_size_t SwFitsDataTable::AddColumn(FieldType ft, string const & cnom)
 {
-  return AddColRd(ft, cnom, NULL);
+  return AddColRd(ft, cnom, -1, NULL);
 }
 /*! 
@@ -240,5 +248,5 @@
 */
 sa_size_t SwFitsDataTable::AddColRd(FieldType ft, string const & cnom, 
-				    vector<int_8> const * swpos)
+				    int colidx, vector<int_8> const * swpos)
 {
   if (NEntry() > 0) 
@@ -247,9 +255,11 @@
   sa_size_t ser; 
   sa_size_t idx = NVar(); 
+  if (colidx < 1) colidx = idx+1; 
+
   switch (ft) {
   case IntegerField :
   {
     ser = mICols.size();
-    FITSDataSwapper<int_4> ISwapper(mSwF, idx+1);
+    FITSDataSwapper<int_4> ISwapper(mSwF, colidx);
     if (swpos)
       mICols.push_back(SwSegDataBlock<int_4>(ISwapper, *swpos, mSegSz));
@@ -265,5 +275,5 @@
   {
     ser = mLCols.size();
-    FITSDataSwapper<int_8> LSwapper(mSwF, idx+1);
+    FITSDataSwapper<int_8> LSwapper(mSwF, colidx);
     if (swpos)    
       mLCols.push_back(SwSegDataBlock<int_8>(LSwapper, *swpos, mSegSz));
@@ -279,5 +289,5 @@
   {
     ser = mFCols.size();
-    FITSDataSwapper<r_4> FSwapper(mSwF, idx+1);
+    FITSDataSwapper<r_4> FSwapper(mSwF, colidx);
     if (swpos)    
       mFCols.push_back(SwSegDataBlock<r_4>(FSwapper, *swpos, mSegSz));
@@ -294,5 +304,5 @@
   {
     ser = mDCols.size();
-    FITSDataSwapper<r_8> DSwapper(mSwF, idx+1);
+    FITSDataSwapper<r_8> DSwapper(mSwF, colidx);
     if (swpos)    
       mDCols.push_back(SwSegDataBlock<r_8>(DSwapper, *swpos, mSegSz));
@@ -308,5 +318,5 @@
   {
     ser = mYCols.size();
-    FITSDataSwapper< complex<r_4> > YSwapper(mSwF, idx+1);
+    FITSDataSwapper< complex<r_4> > YSwapper(mSwF, colidx);
     if (swpos)    
       mYCols.push_back(SwSegDataBlock< complex<r_4> >(YSwapper, *swpos, mSegSz));
@@ -322,5 +332,5 @@
   {
     ser = mZCols.size();
-    FITSDataSwapper< complex<r_8> > ZSwapper(mSwF, idx+1);
+    FITSDataSwapper< complex<r_8> > ZSwapper(mSwF, colidx);
     if (swpos)    
       mZCols.push_back(SwSegDataBlock< complex<r_8> >(ZSwapper, *swpos, mSegSz));
@@ -336,5 +346,5 @@
   {
     ser = mSCols.size();
-    FITSDataSwapper< string > SSwapper(mSwF, idx+1);
+    FITSDataSwapper< string > SSwapper(mSwF, colidx);
     if (swpos)    
       mSCols.push_back(SwSegDataBlock< string >(SSwapper, *swpos, mSegSz));
@@ -368,8 +378,12 @@
 /*! 
   The min/max values for each column is updated, in addition 
-  to the actions performed by the base class AddLine()
-*/
-sa_size_t SwFitsDataTable::AddLine(const r_8* data)
-{
+  to the actions performed by the base class AddRow()
+*/
+sa_size_t SwFitsDataTable::AddRow(const r_8* data)
+{
+  if (NRows() == 0) {  // On cree la definition de la table FITS au premier appel
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Write(mSwF);
+  }
   // On est oblige de calculer les min-max lors du remplissage
   // On ne peut pas en effet 'relire' le swap pendant l'ecriture
@@ -380,14 +394,18 @@
     mMinMaxNEnt[k]++;
   }
-  return BaseDataTable::AddLine(data);
-}
-
-//! Adds a line (or row to the table) with input data as an array of MuTyV
+  return BaseDataTable::AddRow(data);
+}
+
+//! Adds a row (or line to the table) with input data as an array of MuTyV
 /*! 
   The min/max values for each column is updated, in addition 
-  to the actions performed by the base class AddLine()
-*/
-sa_size_t SwFitsDataTable::AddLine(const MuTyV * data)
-{
+  to the actions performed by the base class AddRow()
+*/
+sa_size_t SwFitsDataTable::AddRow(const MuTyV * data)
+{
+  if (NRows() == 0) {  // On cree la definition de la table FITS au premier appel
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Write(mSwF);
+  }
   // On est oblige de calculer les min-max lors du remplissage
   // On ne peut pas en effet 'relire' le swap pendant l'ecriture
@@ -398,5 +416,5 @@
     mMinMaxNEnt[k]++;
   }
-  return BaseDataTable::AddLine(data);
-}
-
+  return BaseDataTable::AddRow(data);
+}
+
Index: trunk/SophyaExt/FitsIOServer/swfitsdtable.h
===================================================================
--- trunk/SophyaExt/FitsIOServer/swfitsdtable.h	(revision 2880)
+++ trunk/SophyaExt/FitsIOServer/swfitsdtable.h	(revision 2889)
@@ -26,11 +26,16 @@
 
   // Filling data structures (adding lines)
-  virtual sa_size_t AddLine(const r_8* data);
-  virtual sa_size_t AddLine(const MuTyV * data);
+  virtual sa_size_t AddRow(const r_8* data);
+  virtual sa_size_t AddRow(const MuTyV * data);
 
-  //! Equal (copy) operator - Copies the structure and shares the data \b a   
+   //! Equal (copy) operator - Copies the data and the structure from \b a   
+  inline  SwFitsDataTable& operator = (BaseDataTable const& a) 
+  { CopyMerge(a, true) ; return *this ; } 
+ //! Equal (copy) operator - Copies the structure and shares the data \b a   
   inline SwFitsDataTable& operator = (SwFitsDataTable const& a) 
   { Clear(); Share(a); return *this ; } 
 
+  //! Acces the FitsInOutFile swap stream
+  inline FitsInOutFile& FitsSwapFile() { return mSwF; } 
   
   //! Reset(Clear) the table content and structure
@@ -47,5 +52,6 @@
   void Share(SwFitsDataTable const & a);
   // Methode pour utilisation par FitsHandler<BaseDataTable>
-  sa_size_t AddColRd(FieldType ft, string const & cnom, vector<int_8> const * swpos=NULL);
+  sa_size_t AddColRd(FieldType ft, string const & cnom, int colidx=-1, 
+		     vector<int_8> const * swpos=NULL);
 
 
