Index: /trunk/SophyaExt/FitsIOServer/fitsarrhand.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsarrhand.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsarrhand.h	(revision 2820)
@@ -0,0 +1,95 @@
+#ifndef FITSARRHAND_H
+#define FITSARRHAND_H
+
+#include "machdefs.h"
+#include <string>
+#include "tarray.h"
+
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for array objects
+*/
+
+template <class T>
+class FitsArrayHandler : public FitsHandlerInterface {
+public :
+  FitsArrayHandler() { dobj=NULL; ownobj=true; }
+  FitsArrayHandler(TArray< T > & obj) { dobj = &obj; ownobj=false; }
+  virtual   ~FitsArrayHandler() { if (ownobj && dobj) delete dobj; }
+  virtual   AnyDataObj* DataObj() { return(dobj); }
+
+  virtual   bool        CheckHandling(AnyDataObj & o) 
+  {  
+    TArray<T> * po = dynamic_cast< TArray<T> * >(& o); 
+    if (po == NULL) return false;
+    else return true;
+  }
+  virtual   void        SetDataObj(AnyDataObj & o) 
+  {  
+    TArray<T> * po = dynamic_cast< TArray<T> * >(& o); 
+    if (po == NULL)  {
+      string msg = "FitsHandler<T>::SetDataObj() Wrong object type: " ;
+      msg += typeid(o).name(); 
+      throw TypeMismatchExc(msg);    
+    }
+    if (ownobj && dobj) delete dobj;  dobj = po; ownobj = false; 
+  }
+
+  virtual FitsHandlerInterface* Clone() 
+    { return new FitsArrayHandler< T >(); }
+
+  inline operator T&() { return(*dobj); }
+
+  //----- Ecriture
+  virtual void     Write(FitsInOutFile& os)
+    {
+      if ( dobj == NULL) 
+	throw NullPtrError("FitsArrayHandler<T>::Write() dobj=NULL ");
+      long naxes[BASEARRAY_MAXNDIMS] = {0,0,0,0,0};
+      for(int_4 id=0; id<dobj->NbDimensions(); id++) 
+	naxes[id] = dobj->Size(id);
+      T x;
+      os.CreateImageHDU(FitsTypes::ImageType(x), dobj->NbDimensions(), naxes);
+      os.WriteHeaderRecords(dobj->Info());
+      FitsBlockRW<T>::WriteImageData(os, dobj->Data(), dobj->Size());
+    }
+
+  //----- Lecture
+  virtual void     Read(FitsInOutFile& is)
+    {
+      if ( dobj == NULL) 
+	throw NullPtrError("FitsArrayHandler<T>::Read() dobj=NULL ");
+      long naxes[BASEARRAY_MAXNDIMS];
+      int naxis=BASEARRAY_MAXNDIMS;
+      is.GetImageHDUInfo(naxis, naxes);
+      sa_size_t sz[BASEARRAY_MAXNDIMS];
+      if (naxis > BASEARRAY_MAXNDIMS) naxis = BASEARRAY_MAXNDIMS;
+      for(int_4 id=0; id<naxis; id++) sz[id] = naxes[id];
+      dobj->SetSize(naxis, sz, 1, false);
+      FitsBlockRW<T>::ReadImageData(is, dobj->Data(), dobj->Size());
+      is.GetHeaderRecords(dobj->Info());
+    }
+
+protected :
+  TArray<T>  * dobj;
+  bool ownobj;       // True si dobj obtenu par new
+};
+
+
+template <class T>
+inline FitsInOutFile& operator << (FitsInOutFile& os, TArray<T> const & obj)
+{ FitsArrayHandler<T> fio(const_cast< TArray<T> &>(obj));  fio.Write(os);  return os; }
+
+template <class T>
+inline FitsInOutFile& operator >> (FitsInOutFile& is, TArray<T> & obj)
+{ FitsArrayHandler<T> fio(obj); fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
+
Index: /trunk/SophyaExt/FitsIOServer/fitsblkrw.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsblkrw.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsblkrw.h	(revision 2820)
@@ -0,0 +1,118 @@
+#ifndef FITSBLKRW_H
+#define FITSBLKRW_H
+
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Template class with static methods for handling bloc data 
+  read from / write to fits files
+*/
+
+template <class T>
+class FitsBlockRW {
+public:
+//! Write image HDU data to a fits file 
+static void WriteImageData(FitsInOutFile& fios, const T * d, size_t sz, 
+			   long * fpixel=NULL)
+{
+  int status = 0;
+  long fpix[5] = {1,1,1,1,1};
+  if (fpixel == NULL) fpixel = fpix;
+  T * ncd = const_cast<T *>(d);
+  fits_write_pix(fios.FitsPtr(), FitsTypes::DataType(d[0]), fpixel,
+		 sz, ncd, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::WriteImageData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+}
+
+//! Read image HDU data from a fits file 
+static void ReadImageData(FitsInOutFile& fios,  T * d, size_t sz, 
+			  long * fpixel=NULL)
+{
+  int status = 0;
+  long fpix[5] = {1,1,1,1,1};
+  if (fpixel == NULL) fpixel = fpix;
+  int anynul = 0;
+  fits_read_pix(fios.FitsPtr(), FitsTypes::DataType(d[0]), fpixel,
+		 sz, NULL, d, &anynul, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::ReadImageData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+
+}
+
+
+/*! 
+  Write binary/ascii HDU data to a fits file. 
+  See cfitsio function fits_write_col() for more detail.
+  \param colnum : table column number (starting from 1)
+  \param firstrow : the write operation starting row (starting from 1)
+  \param firstelem : the firstelem (for vector type columns)
+  \param d : pointer to data to be written
+  \param sz : number of data elements to be written
+*/
+static void WriteColumnData(FitsInOutFile& fios, int colnum, long firstrow,
+			    long firstelem, const T * d, size_t sz)
+{
+  int status = 0;
+  T * ncd = const_cast<T *>(d);
+  fits_write_col(fios.FitsPtr(), FitsTypes::DataType(d[0]), colnum,
+		 firstrow, firstelem, sz, ncd, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::WriteColumnData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+  return;
+}
+
+/*! 
+  Read binary/ascii HDU data from a fits file. 
+  See cfitsio function fits_read_col() for more detail.
+  \param colnum : table column number (starting from 1)
+  \param firstrow : the read operation starting point (row) (starting from 1)
+  \param firstelem : the firstelem (for vector type columns)
+  \param d : pointer to data to be written
+  \param sz : number of data elements to be read
+*/
+static void ReadColumnData(FitsInOutFile& fios, int colnum, long firstrow,
+			    long firstelem, T * d, size_t sz)
+{
+  int status = 0;
+  int anynul = 0;
+  fits_read_col(fios.FitsPtr(), FitsTypes::DataType(d[0]), colnum,
+		 firstrow, firstelem, sz, NULL, d, &anynul, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::ReadColumnData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+  return;
+}
+
+
+};
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaExt/FitsIOServer/fitshandler.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitshandler.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitshandler.h	(revision 2820)
@@ -0,0 +1,83 @@
+#ifndef FITSHANDLER_H
+#define FITSHANDLER_H
+
+#include "machdefs.h"
+#include <string>
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Interface definition for classes handling object storage retrieval in FITS Format 
+*/
+class FitsHandlerInterface {
+
+public:
+
+  virtual ~FitsHandlerInterface() {}
+  //! Return the real data object
+  virtual AnyDataObj* DataObj() = 0;       // Retourne l'objet reel 
+  //! Return true if I/O for object \b o can be handled
+  virtual bool        CheckHandling(AnyDataObj & o) = 0;
+  //! Read/write operation will use the object o
+  virtual void        SetDataObj(AnyDataObj & o) = 0;
+
+  //! Clone (duplicate) the handler class
+  virtual FitsHandlerInterface* Clone() = 0;
+
+  //! Perform the actual write operation to the output fits file
+  virtual void        Write(FitsInOutFile& os) = 0;
+  //! Perform the actual read operation from input fits file
+  virtual void        Read(FitsInOutFile& is) = 0;  
+};
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Generic implementation of FitsHandlerInterface 
+*/
+template <class T>
+class FitsHandler : public FitsHandlerInterface {
+
+public :
+	    FitsHandler() { dobj=NULL; ownobj=true; }
+	    FitsHandler(T & obj) { dobj = &obj; ownobj=false; }
+  virtual   ~FitsHandler() { if (ownobj && dobj) delete dobj; }
+
+  virtual   AnyDataObj* DataObj() { return(dobj); }
+  virtual   bool        CheckHandling(AnyDataObj & o) 
+  {  
+    T * po = dynamic_cast< T * >(& o); 
+    if (po == NULL) return false;
+    else return true;
+  }
+  virtual   void        SetDataObj(AnyDataObj & o) 
+  {  
+    T * po = dynamic_cast< T * >(& o); 
+    if (po == NULL)  {
+      string msg = "FitsHandler<T>::SetDataObj() Wrong object type: " ;
+      msg += typeid(o).name(); 
+      throw TypeMismatchExc(msg);    
+    }
+    if (ownobj && dobj) delete dobj;  dobj = po; ownobj = false; 
+  }
+    
+  virtual FitsHandlerInterface* Clone() 
+    { return new FitsHandler<T>() ; }
+
+  inline operator T&() { return(*dobj); }
+
+  virtual void        Read(FitsInOutFile& is);
+  virtual void        Write(FitsInOutFile& os);
+
+protected :
+  T * dobj;
+  bool ownobj;       // True si dobj obtenu par new
+};
+
+
+
+} // Fin du namespace
+
+#endif
+
Index: /trunk/SophyaExt/FitsIOServer/fitshdtable.cc
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 2820)
@@ -0,0 +1,227 @@
+#include "machdefs.h"
+#include "sopnamsp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "datatable.h"
+#include "fitsblkrw.h"
+#include "fitshandler.h"
+
+// #include "fitshdtable.h"
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<BaseDataTable>::Write(FitsInOutFile& os)
+{
+  
+  if (dobj == NULL)   
+    throw NullPtrError("FitsHandler<DataTable>::Write() NULL dobj pointer ");
+
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  if (dt == NULL) 
+    throw FitsIOException("FitsHandler<DataTable>::Write() Not a DataTable object");
+  
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+    colnames.push_back(dobj->GetColumName(k));
+    tunit.push_back("");
+    switch ( dobj->GetColumType(k) ) {
+    case BaseDataTable::IntegerField :
+      if (tbltyp == ASCII_TBL) tform.push_back("I9");
+      else tform.push_back("J");
+      break;
+    case BaseDataTable::LongField :
+      if (tbltyp == ASCII_TBL) tform.push_back("I12");
+      else tform.push_back("K");
+      break;
+    case BaseDataTable::FloatField :
+      if (tbltyp == ASCII_TBL) tform.push_back("E12.5");
+      else tform.push_back("E");
+      break;
+    case BaseDataTable::DoubleField :
+      if (tbltyp == ASCII_TBL) tform.push_back("D15.8");
+      else tform.push_back("D");
+      break;
+    case BaseDataTable::StringField :
+      cout << "FitsHandler<BaseDataTable>::Write() / Warning StringField not yet supported " << endl;
+      break;
+    default:
+      throw IOExc("FitsHandler<BaseDataTable>::Write() unknown column type ");
+      break;
+    }
+  }
+
+  // On cree la table  
+  string extname = "";
+  os.CreateTable(os.GetDef_TableType(), extname, colnames, tform, tunit);
+
+  // Ecriture des donnees des colonnes
+  for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) { 
+    sa_size_t icol = 0;
+    sa_size_t sz = dobj->SegmentSize();
+    sa_size_t iseg = l/sz;
+    if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
+    for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+      sa_size_t sk = dobj->mNames[k].ser;
+      switch ( dobj->GetColumType(k) ) {
+      case BaseDataTable::IntegerField :
+	icol++;
+	FitsBlockRW<int_4>::WriteColumnData(os, icol, l+1, 1, 
+					    dt->mICols[sk].GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::LongField :
+	icol++;
+	FitsBlockRW<int_8>::WriteColumnData(os, icol, l+1, 1, 
+					    dt->mLCols[sk].GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::FloatField :
+	icol++;
+	FitsBlockRW<r_4>::WriteColumnData(os, icol, l+1, 1, 
+					  dt->mFCols[sk].GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::DoubleField :
+	icol++;
+	FitsBlockRW<r_8>::WriteColumnData(os, icol, l+1, 1, 
+					  dt->mDCols[sk].GetCstSegment(iseg), sz);
+	break;
+	// case BaseDataTable::StringField :
+      default:
+	break;
+      }
+    }
+  }
+  // Ecriture de SegmentSize et autre elements de DVList
+  
+  os.WriteHeaderRecords(dobj->Info());
+  MuTyV mtv = dobj->SegmentSize();
+  os.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
+}
+
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<BaseDataTable>::Read(FitsInOutFile& is)
+{
+ 
+  int hdutyp = is.CurrentHDUType();
+  if ( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<DataTable>::Read() Not a binary or ascii table HDU");
+
+  sa_size_t segsz = is.GetNbRows() / 16; // Taille de segment par defaut 
+  if (segsz > 2048) segsz = 2048;
+  string key = "SEGMSIZE";
+  string ssegsz = is.KeyValue(key);
+  if (ssegsz.length() > 0)  segsz = atoi(ssegsz.c_str());
+  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");
+  
+  vector<string> colnames;
+  vector<int> coltypes;
+  vector<long> repcnt, width;
+  vector<long> colpos;
+  is.GetColInfo(colnames, coltypes, repcnt, width);
+  // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment 
+  for(sa_size_t k=0; k<colnames.size(); k++) { 
+    switch ( coltypes[k] ) {
+    case TBYTE :
+    case TSHORT :
+    case TUSHORT :
+    case TINT :
+      dt->AddIntegerColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TUINT:
+    case TLONG :
+    case TULONG :
+#ifdef TLONGLONG
+    case TLONGLONG :
+#endif      
+      dt->AddLongColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TFLOAT :
+      dt->AddFloatColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TDOUBLE :
+      dt->AddDoubleColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    default:
+      cout << "FitsHandler<BaseDataTable>::Read() NOT handled field type " 
+	   << coltypes[k] << endl;
+      break;
+    }
+  }
+
+  // ------- Mise a jour des champs Nb d'entrees, nb segments ...
+  dobj->mNEnt = is.GetNbRows();
+  while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
+    dobj->Extend();
+  //  cout << " DBG2 -- dobj->mNSeg = " << dobj->NbSegments() << " SegSize=" 
+  //   << dobj->SegmentSize() << " NEntry=" << dobj->NEntry() << endl;
+
+  // Lecture des donnees des colonnes
+  for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) { 
+    sa_size_t icol = 0;
+    sa_size_t sz = dobj->SegmentSize();
+    sa_size_t iseg = l/sz;
+    if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
+    for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+      sa_size_t sk = dobj->mNames[k].ser;
+      icol = colpos[k];
+      //      cout << " DBG-3 , k=" << k << " icol=" << icol << endl;
+      switch ( dobj->GetColumType(k) ) {
+      case BaseDataTable::IntegerField :
+	FitsBlockRW<int_4>::ReadColumnData(is, icol, l+1, 1, 
+					    dt->mICols[sk].GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::LongField :
+	FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1, 
+					   dt->mLCols[sk].GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::FloatField :
+	FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1, 
+					 dt->mFCols[sk].GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::DoubleField :
+	FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1, 
+					 dt->mDCols[sk].GetSegment(iseg), sz);
+	break;
+	// case BaseDataTable::StringField :
+      default:
+	break;
+      }
+    }
+  }
+
+  // Mise a jour nombre d'entree 
+  // Lecture DVList   
+  is.GetHeaderRecords(dobj->Info());
+}
+
+
+int toto()
+{
+  DataTable xx;
+  FitsInOutFile fio("dtoto.fits", FitsInOutFile::Fits_Create);
+  FitsHandler<BaseDataTable> fh(xx);
+  //  fio << xx;
+}
+
+
Index: /trunk/SophyaExt/FitsIOServer/fitshdtable.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitshdtable.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitshdtable.h	(revision 2820)
@@ -0,0 +1,29 @@
+#ifndef FITSARRHAND_H
+#define FITSARRHAND_H
+
+#include "machdefs.h"
+#include <string>
+#include "datatable.h"
+
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for DataTable objects
+*/
+
+
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, BaseDataTable const & obj)
+{ FitsHandler<BaseDataTable> fio(const_cast<BaseDataTable &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, BaseDataTable & obj)
+  { FitsHandler<BaseDataTable> fio(obj); fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
+
Index: /trunk/SophyaExt/FitsIOServer/fitsinoutfile.cc
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsinoutfile.cc	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsinoutfile.cc	(revision 2820)
@@ -0,0 +1,514 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "segdatablock.h"
+#include "fitsinoutfile.h"
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+
+/*! 
+  \class SOPHYA::FitsInOutFile
+  \ingroup FitsIOServer
+  \brief  Wrapper class for cfitsio library functions 
+*/
+
+/*-- Methode --*/
+//! Default constructor - The file should be opened subsequently using Open
+FitsInOutFile::FitsInOutFile()
+{
+  fptr_ = NULL;
+  SetDef_BinTable();
+}
+
+/*-- Methode --*/
+//! Constructor with specification of file name and access mode
+FitsInOutFile::FitsInOutFile(string const & name, FitsIOMode mode)
+{
+  //  cout << " DBG - FitsInOutFile(string name= " << name << ")" << endl;
+  fptr_ = NULL;
+  SetDef_BinTable();
+  Open(name.c_str(), mode);
+}
+
+/*-- Methode --*/
+//! Constructor with specification of file name and access mode
+FitsInOutFile::FitsInOutFile(const char * name, FitsIOMode mode)
+{
+  //  cout << " DBG - FitsInOutFile(char* name= " << name << ")" << endl;
+  fptr_ = NULL;
+  SetDef_BinTable();
+  Open(name, mode);
+}
+
+/* -- Fonction utilitaire pour verifier fichier ouvert (pointeur non null) -- */
+static inline void CheckFitsPtr(fitsfile* fptr) {
+  if (fptr == NULL) throw  FitsIOException("FitsInOutFile/Error - NULL fitsfile pointer ");
+  return;
+}
+/* -- Fonction utilitaire pour verifier le code d'erreur fitsio -- */
+static inline bool FitsCheckStatus(int st, char * emsg = NULL) {
+  if (st) {
+    fits_report_error(stderr, st);
+    if (emsg) {
+      char buff[FLEN_ERRMSG];
+      fits_get_errstatus(st, buff);
+      string msg = emsg;
+      msg += buff;
+      throw FitsIOException(msg);
+    }
+    else return true;
+  }
+  else return false;
+}
+
+/*-- Methode --*/
+//! Destructor - Closes the fits file (if opened)
+FitsInOutFile::~FitsInOutFile()
+{
+  Close();
+}
+
+/*-- Methode --*/
+//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file) 
+void FitsInOutFile::Open(const char* name, FitsIOMode mode)
+{
+  if (fptr_ != NULL) 
+    throw  FitsIOException("FitsInOutFile::Open() /Error - file already opened ");
+  int status = 0;
+  fptr_ = NULL;
+  switch ( mode ) {
+  case Fits_RO :
+    fits_open_file(&fptr_, name, READONLY, &status);
+    break;
+  case Fits_RW :
+    fits_open_file(&fptr_, name, READWRITE, &status);
+    break;
+  case Fits_Create :
+    fits_create_file(&fptr_, name, &status);
+    break;
+  }
+  FitsCheckStatus(status, "FitsInOutFile::Open() Error: ");
+  fname_ = name;
+  mode_ = mode;
+  return;
+}
+
+/*-- Methode --*/
+//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file) 
+void FitsInOutFile::Close()
+{
+  if (fptr_ == NULL) return;
+  int status = 0;
+  if (mode_ == Fits_Create) {
+    status = 0;
+    int hdutyp;
+    fits_movabs_hdu(FitsPtr() , 1, &hdutyp, &status);
+    status = 0;
+    float sfv = 2.0;
+    fits_write_key(FitsPtr(), TFLOAT, "SOPHYAFV", &sfv, 
+		   "SOPHYA FitsIOServer module version", &status);
+    fits_write_date(FitsPtr(), &status);
+    status = 0;
+    fits_write_comment(FitsPtr(), "------------- SOPHYA  (http://www.sophya.org) -------------", &status);
+    fits_write_comment(FitsPtr(), " (C) LAL/IN2P3-CNRS Orsay , (C) DAPNIA/CEA Saclay (FRANCE)", &status);
+    fits_write_comment(FitsPtr(), "-----------------------------------------------------------", &status);
+  }
+  MoveAbsToHDU(1);
+  status = 0;
+  if (fptr_) fits_close_file(fptr_, &status);
+  if (status) {
+    cerr << " FitsInOutFile::Close - Error closing fits file !" << endl;
+    fits_report_error(stderr, status);
+  }
+}
+
+
+/*-- Methode --*/
+float FitsInOutFile::cfitsioVersion() 
+{
+  float ver;
+  fits_get_version(&ver);
+  return ver;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::NbHDUs()  const
+{
+  int status = 0;
+  int nbhdu = 0;
+  fits_get_num_hdus(FitsPtr() , &nbhdu, &status);
+  FitsCheckStatus(status, "FitsInOutFile::NbHDUs() Error: ");
+  return nbhdu;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::CurrentHDU()  const
+{
+  int status = 0;
+  int curhdu = 0;
+  fits_get_hdu_num(FitsPtr() , &curhdu);
+  return curhdu;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::CurrentHDUType()  const
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::CurrentHDUType() Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+string FitsInOutFile::CurrentHDUTypeStr()  const
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
+  if ( FitsCheckStatus(status, "FitsInOutFile::CurrentHDUTypeStr() Error: ") ) 
+    return "Unknown";
+  else { 
+    if (hdutyp == IMAGE_HDU) return "IMAGE_HDU";
+    else if (hdutyp == BINARY_TBL) return "BINARY_TBL";
+    else if (hdutyp == ASCII_TBL) return "ASCII_TBL";
+    else return "Unknown";
+  }
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveAbsToHDU(int hdunum)
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_movabs_hdu(FitsPtr() , hdunum, &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::MoveAbsToHDU Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveRelToHDU(int hdunum)
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_movrel_hdu(FitsPtr() , hdunum, &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::MoveRelToHDU Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveToNextHDU()
+{
+  if (CurrentHDU() < NbHDUs()) 
+    return MoveRelToHDU(1);
+  else return -1;
+}
+
+/*-- Methode --*/
+void FitsInOutFile::CreateImageHDU(int bitpix, int naxis, long* naxes)
+{
+  int status = 0;
+  fits_create_img(fptr_, bitpix, naxis, naxes, &status);
+  FitsCheckStatus(status,"FitsInOutFile::CreateImageHDU() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+ /*!
+   See cfitsio function fits_get_img_param() for more information 
+   naxis : input=max naxes dimension / out=image dimension 
+   Rc : return the image type (bitpix) 
+ */
+int FitsInOutFile::GetImageHDUInfo(int& naxis, long* naxes) const
+{
+  int status = 0;
+  int maxdim = naxis;
+  int bitpix = 0;
+  fits_get_img_param(fptr_, maxdim, &bitpix, &naxis, naxes, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetImageHDUInfo() Error: ");
+  return bitpix;
+}
+
+/*-- Methode --*/
+long FitsInOutFile::GetNbRows()  const
+{
+  int status = 0;
+  long nbrow = 0;
+  fits_get_num_rows(FitsPtr() , &nbrow, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetNbRows() Error: " );
+  return nbrow;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::GetNbCols()  const
+{
+  int status = 0;
+  int nbcol = 0;
+  fits_get_num_cols(FitsPtr() , &nbcol, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetNbCols() Error: ");
+  return nbcol;
+}
+
+/*-- Methode --*/
+/*!
+  Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
+  \param extname : extension name. NextExtensionName() will be used if extname == NULL or extname == "".
+  \param ncols : Number of columns
+  \param ttype : Column names 
+  \param tform : Column data types J / V / K / E / D ...
+  \param tunit : Column units
+*/
+void FitsInOutFile::CreateTable(int tbltyp, const char * extname, int ncols, 
+				char * ttype[], char * tform[], 
+				char * tunit[], long ininr)
+{
+  int status = 0;
+
+  char * extn;
+  if ( (extname != NULL) && (extname[0] != '\0') )  extn = const_cast<char *>(extname);
+  else extn = const_cast<char *>(next_extname_.c_str());
+
+  fits_create_tbl(FitsPtr(), tbltyp, ininr, ncols, ttype, 
+		  tform, tunit, extn, &status);
+  next_extname_ = "";
+  FitsCheckStatus(status, "FitsInOutFile::CreateTable() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+/*!
+  Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
+  number of columns specified by colnames.size()
+  \param extname : extension name
+  \param colnames : Column names 
+  \param tform : Column data types J / V / K / E / D ...
+  \param tunit : Column units
+*/
+void FitsInOutFile::CreateTable(int tbltyp, const string & extname, 
+				  const vector<string> & colnames, 
+				  const vector<string> & tform, 
+				  const vector<string> & tunit, 
+				  long ininr)
+{
+  if ( (colnames.size() != tform.size() ) || 
+       (colnames.size() != tunit.size() ) )
+    throw SzMismatchError("FitsInOutFile::CreateTable(): different sizes for colnames,tform,tunit");
+  
+  // On utilise les SegDataBlock<T> pour eviter d'avoir a gerer les new/delete
+  // en plus avec les exceptions ...
+  size_t kk;
+  int ncols = colnames.size();
+
+  SegDataBlock<const char *> colnm(colnames.size(), 1);
+  for(kk=0; kk<colnames.size(); kk++) colnm[kk] = colnames[kk].c_str();
+  SegDataBlock<const char *> tfm(tform.size(), 1);
+  for(kk=0; kk<tform.size(); kk++) tfm[kk] = tform[kk].c_str();
+  SegDataBlock<const char *> tun(tunit.size(), 1);
+  for(kk=0; kk<tunit.size(); kk++) tun[kk] = tunit[kk].c_str();
+       
+  CreateTable(tbltyp, const_cast<char *>(extname.c_str()), ncols, 
+	      const_cast<char **>(colnm.GetSegment(0)), 
+	      const_cast<char **>(tfm.GetSegment(0)), 
+	      const_cast<char **>(tun.GetSegment(0)), 
+	      ininr);
+}
+
+/*-- Methode --*/
+/*!
+  Return number of columns in table (See fits_get_colname and fits_get_coltype for more information)
+  \param colnames : Column names
+  \param coltypes : Column data types ( TSTRING / TSHORT / TFLOAT / ... )
+  \param repcnt : Repeat count (for columns with vector data)
+  \param width : The width (in bytes) of a single element in a column 
+  
+*/
+long FitsInOutFile::GetColInfo(vector<string> & colnames, 
+				 vector<int> & coltypes,
+				 vector<long> & repcnt,
+				 vector<long> & width)
+{
+
+  int status = 0;
+
+  colnames.clear();
+  coltypes.clear();
+  width.clear();
+  repcnt.clear();
+
+  int colnum, typecode;
+  long repeat, colw;
+  int ncols = 0;
+  char colname[128];  // longueur max d'un nom de colonne
+
+  while (status != COL_NOT_FOUND) {
+    fits_get_colname(FitsPtr(), CASEINSEN, "*", colname, &colnum, &status);
+    if (status == COL_NOT_FOUND)  break;
+    if (status != COL_NOT_UNIQUE) {
+      char buff[32];
+      fits_get_errstatus(status, buff);
+      string msg = "FitsInOutFile::GetColInfo() Error(1): " ;
+      msg += buff;
+      throw FitsIOException(msg);
+    }
+    int sta2 = 0;
+    fits_get_coltype(FitsPtr(), colnum, &typecode, &repeat, &colw, &sta2);
+    FitsCheckStatus(sta2, "FitsInOutFile::GetColInfo() Error(2): ");
+
+    colnames.push_back(colname);
+    coltypes.push_back(typecode);
+    repcnt.push_back(repeat);
+    width.push_back(colw);
+  }
+  return colnames.size();
+}
+
+/*-- Methode --*/
+void FitsInOutFile::InsertColumn(int numcol, const char* colname, const char* fmt)
+{
+  int status = 0;
+  fits_insert_col(FitsPtr(), numcol, const_cast<char *>(colname), 
+		  const_cast<char *>(fmt), &status);
+  FitsCheckStatus(status, "FitsInOutFile::AddColumn() Error: ");
+
+  return;
+}
+
+/*-- Methode --*/
+string FitsInOutFile::KeyValue(string const & key)
+{
+  int status = 0;
+  char value[FLEN_VALUE], comm[FLEN_COMMENT];
+  fits_read_key(FitsPtr(), TSTRING, const_cast<char *>(key.c_str()), value, comm, &status);
+  FitsCheckStatus(status, "FitsInOutFile::KeyValue() Error: ");
+  return value;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::GetHeaderRecords(DVList& dvl)
+{
+  int status = 0;
+  int nkeys = 0;
+  fits_get_hdrspace(FitsPtr(), &nkeys, NULL, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(1): ");
+ 
+  char record[FLEN_CARD], value[FLEN_VALUE], comm[FLEN_COMMENT];
+  string comment;
+  int nok = 0;
+  for(int kk=1; kk<=nkeys; kk++) {
+    status = 0;
+    fits_read_record(FitsPtr(), kk, record, &status);
+    FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(2): ");
+    int kclas = fits_get_keyclass(record);
+    if ( (kclas ==  TYP_STRUC_KEY) || (kclas == TYP_NULL_KEY) ) continue;
+    int len = 0;
+    status = 0;
+    fits_get_keyname(record, value, &len, &status);
+    if (status) continue;
+    string keyname = value;
+    status = 0;
+    fits_parse_value(record, value, comm, &status);
+    if (status) continue;
+    if (kclas == TYP_COMM_KEY) {
+      if (comment.length() > 0) comment += '\n';
+      comment += value;
+      continue;
+    } 
+    char ktyp;
+    status = 0;
+    fits_get_keytype(value, &ktyp, &status);
+    if (status) continue;
+    switch (ktyp) {
+    case 'C' :
+    case 'L' :   // Il faudra traiter le cas des nb complexes
+    case 'X' :   // idem pour les valeurs logiques
+     dvl.SetS(keyname, value);
+      break;
+    case 'I' :
+      dvl.SetI(keyname, atoi(value));
+      break;
+    case 'F' :
+      dvl.SetD(keyname, atof(value));
+      break;
+    }
+    if (strlen(comm) > 0) {
+      string scom = comm;
+      dvl.SetComment(keyname, scom);
+    }
+    nok++;
+  }
+  if (comment.length() > 0)  dvl.Comment() = comment; 
+  return nok;
+}
+
+/*-- Methode --*/
+void FitsInOutFile::WriteKey(const char * kname, MuTyV const & mtv, 
+			     const char *comment)
+{
+  CheckFitsPtr(FitsPtr()); 
+  char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], sval[FLEN_VALUE];
+  long lval;
+  double dval;
+  string s;
+  
+  keyname[0] = '\0';
+  strncpy(keyname, kname, FLEN_KEYWORD); keyname[FLEN_KEYWORD-1] = '\0';
+  comm[0] = '\0';
+  if (comm != NULL) 
+    strncpy(comm, comment, FLEN_COMMENT); comm[FLEN_COMMENT-1] = '\0';
+  int status = 0;
+  switch (mtv.Type()) {
+  case MuTyV::MTVInteger :
+    lval = mtv.GetIntPart();
+    fits_write_key(FitsPtr(), TLONG, keyname, &lval, comm, &status);
+    break;
+  case MuTyV::MTVFloat : 
+    dval = mtv.GetRealPart();
+    fits_write_key(FitsPtr(), TDOUBLE, keyname, &dval, comm, &status);
+    break;
+  case MuTyV::MTVString : 
+    strncpy(sval, mtv.GetStringPointer()->c_str(), FLEN_VALUE);  
+    keyname[FLEN_VALUE-1] = '\0';
+    fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
+    break;
+  default :
+    s = (string)mtv;
+    strncpy(sval, s.c_str(), FLEN_VALUE);  
+    keyname[FLEN_VALUE-1] = '\0';
+    fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
+    break;
+  }
+  FitsCheckStatus(status, "FitsInOutFile::WriteKey() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::WriteHeaderRecords(DVList & dvl)
+{
+
+  CheckFitsPtr(FitsPtr()); 
+  int status = 0;
+  DVList::ValList::const_iterator it;
+  for(it = dvl.Begin(); it != dvl.End(); it++)  
+    WriteKey( (*it).first, (*it).second.elval, (*it).second.elcomm);
+  // Ecriture commentaires
+  return 0;
+
+}
+
+/*-- Methode --*/
+void FitsInOutFile::Print(ostream& os, int lev) const
+{
+  string mode;
+  if (mode_ == Fits_Create)  mode = "Create";
+  else if (mode_ == Fits_RO)  mode = "ReadOnly";
+  else mode = "ReadWrite";
+  os << " FitsInOutFile(FileName= " << fname_  << " Mode=" 
+     << mode  << ") fitsioVers= " << cfitsioVersion() << endl;
+  os << " TotalNumberHDU= " << NbHDUs() << " CurrentHDU: Num= " 
+     << CurrentHDU() << " Type= " << CurrentHDUTypeStr() << endl;
+
+  return;
+}
+
+
Index: /trunk/SophyaExt/FitsIOServer/fitsinoutfile.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsinoutfile.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsinoutfile.h	(revision 2820)
@@ -0,0 +1,195 @@
+#ifndef FITSINOUTFILE_H
+#define FITSINOUTFILE_H
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "dvlist.h"
+#include "FitsIO/fitsio.h" 
+#include <complex> 
+
+
+
+namespace SOPHYA {
+
+  class FitsInOutFile;
+  //class FitsInStream;
+  //class FitsOutStream;
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Exception class used by  FITS file wrapper classes in FitsIOserver module
+*/
+class FitsIOException : public IOExc {
+  public:
+  explicit FitsIOException(const char * m) : IOExc(m) {}
+  explicit FitsIOException(const string& m) : IOExc(m) {}
+};
+
+
+/*! 
+  \ingroup FitsIOServer
+  \brief  for converting c/c++ types to FITS data types 
+*/
+class FitsTypes {
+public:
+ // Conversion de type en constante de type image FITS (XXX_IMG)
+ static int ImageType(uint_1 d) { return BYTE_IMG; }
+ static int ImageType(int_2  d) { return SHORT_IMG; }
+ static int ImageType(int_4  d) { return LONG_IMG; }
+ static int ImageType(r_4  d)   { return FLOAT_IMG; }
+ static int ImageType(r_8  d)   { return DOUBLE_IMG; }
+
+ // Conversion de type en constante datatype FITS 
+ static int DataType(uint_1 d) { return TBYTE; }
+ static int DataType(int_2  d) { return TSHORT; }
+ static int DataType(uint_2 d) { return TUSHORT; }
+
+ static int DataType(const int_4  d) 
+   { return (sizeof(long)==4) ? TLONG: TINT; }
+ static int DataType(const uint_4 d) 
+   { return (sizeof(long)==4) ? TULONG: TUINT; }
+
+#ifdef TLONGLONG
+ static int DataType(int_8 d) { return TLONGLONG; }
+#else 
+ static int DataType(int_8 d) 
+   { throw FitsIOException("FitsDataTypes: Unsupported data type int_8"); }
+#endif
+
+ static int DataType(r_4  d)   { return TFLOAT; }
+ static int DataType(r_8  d)   { return TDOUBLE; }
+
+ static int DataType(complex<r_4>  d)   { return TCOMPLEX; }
+ static int DataType(complex<r_8>  d)   { return TDBLCOMPLEX; }
+
+ // Conversion entre type FITS et chaine - exemple TFLOAT -> r_4 
+ static string ImageTypeToTypeString(int ityp);
+ static string DataTypeToTypeString(int ityp);
+};
+
+/*! 
+  \ingroup FitsIOServer
+  \brief  Wrapper class for cfitsio library functions
+*/
+class FitsInOutFile {
+public :
+  //! File access mode (ReadOnly, ReadWrite, Create)
+ enum FitsIOMode { Fits_RO, Fits_RW, Fits_Create };
+
+                   FitsInOutFile(); 
+                   FitsInOutFile(string const & name, FitsIOMode mode);
+                   FitsInOutFile(const char* name, FitsIOMode mode);
+ virtual           ~FitsInOutFile();
+
+
+ void              Open(const char* name, FitsIOMode mode);
+  void             Close();
+
+ inline fitsfile*  FitsPtr() const { return fptr_; }
+ static float      cfitsioVersion();
+
+ //---- Header manipulation methods
+ //! Return total number of HDU's in file
+ int               NbHDUs() const;
+ //! Return current HDU number - starting from 1 , not zero
+ int               CurrentHDU() const;
+ //! Return current HDU Type as IMAGE_HDU or BINARY_TBL or ASCII_TBL 
+ int               CurrentHDUType() const;
+ //! Return current HDU Type as a string IMAGE_HDU or BINARY_TBL or ASCII_TBL 
+ string            CurrentHDUTypeStr() const;
+ 
+ //! Move to HDU specified by hdnum - Returns the newly opened HDU type
+ int               MoveAbsToHDU(int hdunum);
+ //! Move to HDU specified by relhdu , relative to the current HDU - Returns the newly opened HDU type
+ int               MoveRelToHDU(int relhdu);
+ //! Move to the next HDU specified by relhdu. Returns the newly opened HDU type (<0 at EOF)
+ int               MoveToNextHDU();
+
+ //---- IMAGE_HDU manipulation methods
+ //! Creates a new HDU of type image (see fits_create_img)
+ void              CreateImageHDU(int bitpix, int naxis, long* naxes);
+ //! Get information about the current image HDU. - return the image type TBYTE,TINT ...
+ int               GetImageHDUInfo(int& naxis, long* naxes) const;
+
+ //---- BINARY_TBL or ASCII_TBL 
+ //! Return number of rows in a table HDU
+ long              GetNbRows() const;
+ //! Return number of columns in a table HDU
+ int               GetNbCols() const;
+ //! Creation of a new table - tbltyp = BINARY_TBL or ASCII_TBL
+ void              CreateTable(int tbltyp, const char * extname, int ncols, 
+			       char * colnames[], char * tform[], 
+			       char * tunit[], long ininr=0);
+ //! Creation of a new table - tbltyp = BINARY_TBL or ASCII_TBL
+ void              CreateTable(int tbltyp, const string & extname, 
+			       const vector<string> & colnames, 
+			       const vector<string> & tform, 
+			       const vector<string> & tunit, 
+			       long ininr=0);
+ //! Return number of columns, names, types and repeat count
+ long              GetColInfo(vector<string> & colnames, 
+			      vector<int> & coltypes,
+			      vector<long> & repcnt,
+			      vector<long> & width);
+
+ //! Defines the extension name for the next table creation 
+ inline void        SetNextExtensionName(string const & extname)
+   { next_extname_ = extname; }
+ //! Defines the extension name for the next table creation 
+ inline void        SetNextExtensionName(const char * extname)
+   { next_extname_ = extname; }
+ //! Return the default extension name 
+ inline string      NextExtensionName() const
+   { return next_extname_; }
+
+ //! Defines default table type for created tables as BINARY_TBL
+ inline void        SetDef_BinTable() { def_tbltype = BINARY_TBL; }
+ //! Defines default table type for created tables as ASCII_TBL
+ inline void        SetDef_AscTable() { def_tbltype = ASCII_TBL; }
+ //! Return default table type
+ inline int         GetDef_TableType() { return def_tbltype; }
+
+ //! Insert (add) a new column
+ void              InsertColumn(int numcol, const char* colname, const char* fmt);
+ //! Insert (add) a new column
+ inline void       InsertColumn(int numcol, const string& colname, const char* fmt)
+   { InsertColumn(numcol, colname.c_str(), fmt); }
+
+
+ // Manipulation des informations de l'entete 
+ //! Returns a given keyword value
+  string           KeyValue(string const & key);
+ //! Read header records and appends the information to dvl
+ int               GetHeaderRecords(DVList& dvl);
+ //! Appends a keyword to FITS header
+ void	           WriteKey(const char * kname, MuTyV const & val, 
+			    const char *comm=NULL);
+ inline void	   WriteKey(string const & kname, MuTyV const & val, string const & comm) 
+   { WriteKey(kname.c_str(), val, comm.c_str()); }
+ //! Write dvl information to fits header 
+ int               WriteHeaderRecords(DVList & dvl);
+
+ //! Prints information about the fits file on standard output stream (cout)
+ inline  void      Print(int lev=0) const  { Print(cout, lev); }  
+ //! Prints information about the fits file on stream os
+ virtual void      Print(ostream& os, int lev=0)  const;
+
+protected:
+ fitsfile *fptr_;     //  pointer to the FITS file, defined in fitsio.h 
+ string fname_;       //  File name as passed to creator
+ FitsIOMode mode_;    
+
+ // Default extension name 
+ string next_extname_;
+ // Default table type 
+ int def_tbltype;
+};
+
+/*! Prints FITS file information on stream \b s ( fio.Print(s) ) */
+
+inline ostream& operator << (ostream& s, FitsInOutFile const & fio)
+  {  fio.Print(s);  return(s);  }
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaExt/FitsIOServer/fitsmanager.cc
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsmanager.cc	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsmanager.cc	(revision 2820)
@@ -0,0 +1,86 @@
+#include "machdefs.h"
+#include "sopnamsp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "fitsmanager.h"
+#include "fitshandler.h"
+
+struct hand_list_el {
+  FitsHandlerInterface * fhi;
+  string clname;
+};
+
+typedef list<hand_list_el> HandlerList;
+
+static HandlerList * hlistp = NULL;
+
+static inline void ChkHLP() 
+{
+  if (hlistp = NULL) hlistp = new HandlerList;
+}
+
+int FitsManager::RegisterHandler(FitsHandlerInterface * fhi, string & clname)
+{
+  if (fhi == NULL)
+    throw NullPtrError("FitsManager::RegisterHandler() fhi=NULL ");
+  HandlerList::iterator it;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    if (typeid(*((*it).fhi)) == typeid(*fhi)) 
+      throw DuplicateIdExc("FitsManager::RegisterHandler() Already registered handler");
+  }
+  hand_list_el hle;
+  hle.fhi = fhi;
+  hle.clname = clname;
+  hlistp->push_back(hle);
+  return hlistp->size();
+}
+
+int FitsManager::ListHandlers()
+{
+  int kk=0;
+  cout << "---- FitsManager::ListHandlers()  NbHandlers= " << hlistp->size()
+       << endl;
+  HandlerList::iterator it;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    kk++;
+    cout << kk << "- " << (*it).clname << " : " 
+	 << typeid(*((*it).fhi)).name() << endl;
+  }
+  return hlistp->size();
+}
+
+FitsHandlerInterface* FitsManager::FindHandler(AnyDataObj & o)
+{
+  FitsHandlerInterface * fhi = NULL;
+  HandlerList::iterator it;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) 
+    if ( (*it).fhi->CheckHandling(o) ) {
+      fhi = (*it).fhi; break;
+    }
+  if (fhi == NULL) {
+    string msg = "FitsManager::FindHandler() Handler not found for ";
+    msg += typeid(o).name();
+    throw NotFoundExc(msg);
+  }
+  else return fhi;
+}
+
+void FitsManager::Write(FitsInOutFile& os, AnyDataObj & o)
+{
+  FitsHandlerInterface * fhi2 = FindHandler(o)->Clone();
+  fhi2->SetDataObj(o);
+  fhi2->Write(os);
+  return;
+}
+
+void FitsManager::Read(FitsInOutFile& os, AnyDataObj & o)
+{
+  FitsHandlerInterface * fhi2 = FindHandler(o)->Clone();
+  fhi2->SetDataObj(o);
+  fhi2->Read(os);
+  return;
+}
Index: /trunk/SophyaExt/FitsIOServer/fitsmanager.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fitsmanager.h	(revision 2820)
+++ /trunk/SophyaExt/FitsIOServer/fitsmanager.h	(revision 2820)
@@ -0,0 +1,30 @@
+#ifndef FITSMANAGER_H
+#define FITSMANAGER_H
+
+#include "machdefs.h"
+#include <string>
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+class FitsHandlerInterface;
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Top level FITS I/O operations and handler management.
+*/
+class FitsManager {
+ public:
+  static int  RegisterHandler(FitsHandlerInterface * fhi, string & clname);
+  static int  ListHandlers();
+  static void Write(FitsInOutFile& os, AnyDataObj & o);
+  static void Read(FitsInOutFile& os, AnyDataObj & o);
+  //  static FitsHandlerInterface * Read(FitsInOutFile& os);
+ protected:
+  static FitsHandlerInterface* FindHandler(AnyDataObj & o);
+};
+
+} // Fin du namespace
+
+#endif
+
