Index: trunk/SophyaExt/FitsIOServer/fitshdtable.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 2864)
+++ 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());
 }
 
