Index: /trunk/SophyaLib/BaseTools/Makefile
===================================================================
--- /trunk/SophyaLib/BaseTools/Makefile	(revision 2659)
+++ /trunk/SophyaLib/BaseTools/Makefile	(revision 2660)
@@ -3,7 +3,7 @@
 all: $(LIB)libBaseTools.a
 clean:
-	rm -f $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)ppfbinstream.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)gnumd5.o $(OBJ)srandgen.o
+	rm -f $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)ppfbinstream.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)timestamp.o $(OBJ)gnumd5.o $(OBJ)srandgen.o
 	rm -f $(LIB)libBaseTools.a
-$(LIB)libBaseTools.a : $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)gnumd5.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)ppfbinstream.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)srandgen.o
+$(LIB)libBaseTools.a : $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)gnumd5.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)ppfbinstream.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)srandgen.o $(OBJ)timestamp.o
 	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
 ifeq ($(CXX),cxx)
@@ -11,32 +11,38 @@
 endif 
  
-$(OBJ)datatype.o: datatype.cc datatype.h \
- $(INC)machdefs.h
-$(OBJ)dvlist.o: dvlist.cc $(INC)machdefs.h dvlist.h \
- objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
- ppfbinstream.h rawstream.h ppfnametag.h mutyv.h \
- $(INC)strutil.h
-$(OBJ)fiondblock.o: fiondblock.cc $(INC)machdefs.h \
- pexceptions.h datatype.h fiondblock.h ppersist.h gnumd5.h \
- ppfbinstream.h rawstream.h ppfnametag.h ndatablock.h anydataobj.h
-$(OBJ)mutyv.o: mutyv.cc mutyv.h $(INC)machdefs.h
-$(OBJ)ndatablock.o: ndatablock.cc $(INC)machdefs.h \
- pexceptions.h ndatablock.h anydataobj.h
-$(OBJ)pexceptions.o: pexceptions.cc pexceptions.h \
- $(INC)machdefs.h
-$(OBJ)ppersist.o: ppersist.cc $(INC)machdefs.h \
- pexceptions.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
- ppfnametag.h anydataobj.h
-$(OBJ)ppfbinstream.o: ppfbinstream.cc \
- $(INC)machdefs.h ppfbinstream.h rawstream.h \
- pexceptions.h
-$(OBJ)rawstream.o: rawstream.cc rawstream.h \
- $(INC)machdefs.h pexceptions.h
-$(OBJ)sophyainit.o: sophyainit.cc $(INC)machdefs.h \
- sophyainit.h pexceptions.h ppersist.h gnumd5.h ppfbinstream.h \
- rawstream.h ppfnametag.h fiondblock.h ndatablock.h anydataobj.h \
- dvlist.h objfio.h mutyv.h sversion.h
+$(OBJ)datatype.o: datatype.cc sopnamsp.h datatype.h \
+  $(INC)machdefs.h
+$(OBJ)dvlist.o: dvlist.cc sopnamsp.h $(INC)machdefs.h \
+  dvlist.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h mutyv.h \
+  $(INC)strutil.h
+$(OBJ)fiondblock.o: fiondblock.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h datatype.h \
+  fiondblock.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h anydataobj.h
+$(OBJ)mutyv.o: mutyv.cc sopnamsp.h mutyv.h \
+  $(INC)machdefs.h
+$(OBJ)ndatablock.o: ndatablock.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h ndatablock.h \
+  anydataobj.h
+$(OBJ)pexceptions.o: pexceptions.cc sopnamsp.h pexceptions.h \
+  $(INC)machdefs.h
+$(OBJ)ppersist.o: ppersist.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h ppersist.h \
+  gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h anydataobj.h
+$(OBJ)ppfbinstream.o: ppfbinstream.cc sopnamsp.h \
+  $(INC)machdefs.h ppfbinstream.h rawstream.h \
+  pexceptions.h
+$(OBJ)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
+  $(INC)machdefs.h pexceptions.h
+$(OBJ)sophyainit.o: sophyainit.cc sopnamsp.h \
+  $(INC)machdefs.h sophyainit.h pexceptions.h \
+  ppersist.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  fiondblock.h ndatablock.h anydataobj.h dvlist.h objfio.h mutyv.h \
+  fiosegdb.h segdatablock.h ppftpointerio.h ppfwrapstlv.h sversion.h
+$(OBJ)timestamp.o: timestamp.cc sopnamsp.h \
+  $(INC)machdefs.h timestamp.h pexceptions.h
 $(OBJ)gnumd5.o: gnumd5.c $(INC)machdefs.h bithelp.h \
- gnumd5.h
+  gnumd5.h
 $(OBJ)srandgen.o: srandgen.c $(INC)machdefs.h \
- srandgen.h smathconst.h
+  srandgen.h smathconst.h
Index: /trunk/SophyaLib/BaseTools/fiosegdb.h
===================================================================
--- /trunk/SophyaLib/BaseTools/fiosegdb.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/fiosegdb.h	(revision 2660)
@@ -0,0 +1,154 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour la gestion de persistance PPF des SegDataBlock 
+//                         R. Ansari - Avril 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef FIOSEGDATABLOCK_H
+#define FIOSEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "ppersist.h"
+#include "segdatablock.h"
+#include "ppftpointerio.h"
+#include <typeinfo> 
+
+namespace SOPHYA {
+
+/*!
+   \class SOPHYA::FIO_SegDataBlock
+   \ingroup BaseTools
+   Class implementing PPF persistence (PPersist handler) for segmented data structures
+   (class SegDataBlock).
+*/
+   
+template <class T>
+class FIO_SegDataBlock : public  PPersist , AnyDataObj {
+public:
+  FIO_SegDataBlock()
+  {
+    dobj = NULL ;
+    ownobj=true;    
+  }
+
+  //   FIO_SegDataBlock(string const & filename);
+  FIO_SegDataBlock(SegDataBlock<T> & obj)
+  {
+    dobj = &obj;
+    ownobj = false;
+  }
+
+  FIO_SegDataBlock(SegDataBlock<T> * obj)
+  {
+    if (obj == NULL)  
+      throw ParmError("FIO_SegDataBlock<T>::FIO_SegDataBlock(* obj) obj=NULL (ppfwrapstlv.h)");
+    dobj = obj;
+    ownobj = false;
+  }
+  virtual ~FIO_SegDataBlock()
+  {
+    if (ownobj && dobj)    delete dobj;
+  }
+  virtual AnyDataObj* DataObj() { return dobj; }
+  virtual void        SetDataObj(AnyDataObj & o)
+  {
+    SegDataBlock<T> * po = dynamic_cast< SegDataBlock<T> * >(&o);
+    if (po == NULL) {
+      char buff[160];
+      sprintf(buff,"FIO_SegDataBlock<%s>::SetDataObj(%s) - Object type  error ! ",
+	      typeid(T).name(), typeid(o).name());
+      throw TypeMismatchExc(PExcLongMessage(buff));    
+    }
+    if (ownobj && dobj) delete dobj;
+    dobj = po; ownobj = false;
+  } 
+
+  inline operator SegDataBlock<T>()  { return(*dobj); }
+
+  // Les methodes suivantes implementent les fonctionalites necessaires
+  // au  partage de reference ds les fichiers PPF 
+  uint_8 getMemOId() const
+  {
+    return ( (dobj) ? dobj->DRefId() : 0 );
+  }
+  void ShareDataReference(PPersist & pp)
+  {
+    FIO_SegDataBlock<T> *ppo = dynamic_cast< FIO_SegDataBlock<T> * >(&pp);
+    if (ppo == NULL) throw TypeMismatchExc("FIO_SegDataBlock<T>::ShareDataReference() - Type Mismatch Error");
+    if (ppo->dobj) {
+      if (dobj) dobj->Share(*(ppo->dobj));
+      else { dobj = new SegDataBlock<T>(*(ppo->dobj)); ownobj = true; } 
+    }
+  }
+  PPersist* CloneSharedReference()
+  {
+    FIO_SegDataBlock<T> * ppo = new FIO_SegDataBlock<T>;
+    ppo->dobj = new SegDataBlock<T>(*(dobj));
+    ppo->ownobj = true;
+    return(ppo); 
+  }
+
+protected :
+  virtual void       ReadSelf(PInPersist& is)
+  {
+    // On lit les 4 premiers uint_8
+    // 0: Numero de version   , 3 : reserve 
+    // 1: SegmentSize  2: NbSegments  
+    uint_8 itab[4];
+    is.Get(itab, 4);
+    if (dobj == NULL) {
+      dobj = new SegDataBlock<T>(itab[1], itab[2]);
+      ownobj = true;
+    }
+    else dobj->SetSize(itab[1], itab[2]);
+    cout << *dobj ; 
+    // On lit les donnees par paquet ...
+    for(uint_8 k=0; k<itab[2]; k++) 
+      PPF_TPointer_IO<T>::Read(is, dobj->GetSegment(k), itab[1]);
+    // On lit la table des tags de positionnement ...
+    vector<int_8> postags;
+    is.GetPosTagTable(postags);
+  }         
+  virtual void       WriteSelf(POutPersist& os) const
+  {
+    if (dobj == NULL) 
+      throw ParmError("FIO_SegDataBlock<T>::WriteSelf() dobj=NULL (fiosegdb.h)");
+    // On ecrit les 4  uint_8
+    // 0: Numero de version   , 3 : reserve 
+    // 1: SegmentSize  2: NbSegments  
+    uint_8 itab[4];
+    itab[0] = 1;
+    itab[1] = dobj->SegmentSize();
+    itab[2] = dobj->NbSegments();
+    itab[3] = 0;
+    os.Put(itab, 4);
+    // On ecrit les donnees par paquets ...
+    vector<int_8> postags;
+    int_8 tag;
+    for(uint_8 k=0; k<itab[2]; k++) {
+      tag = os.WritePositionTag();
+      PPF_TPointer_IO<T>::Write(os, dobj->GetSegment(k), itab[1]);
+      postags.push_back(tag);
+    }
+    // On ecrit la table des tags de positionnement 
+    // au cas ou on voudrait l'utiliser en mode swap
+    os.PutPosTagTable(postags);
+  }
+
+  // Variables membres 
+  SegDataBlock<T> * dobj;  // Le vecteur de la STL 
+  bool ownobj;  // true -> objet cree par le wrapper 
+};
+
+/*! Writes the segmented data structure \b obj in the POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, SegDataBlock<T> & obj)
+{ FIO_SegDataBlock<T> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads in and initializes the segmented data structure \b obj  
+  from the PInPersist stream \b is */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, SegDataBlock<T> & obj)
+{ FIO_SegDataBlock<T> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaLib/BaseTools/objlist.list
===================================================================
--- /trunk/SophyaLib/BaseTools/objlist.list	(revision 2659)
+++ /trunk/SophyaLib/BaseTools/objlist.list	(revision 2660)
@@ -11,2 +11,3 @@
 sophyainit.o
 srandgen.o
+timestamp.o
Index: /trunk/SophyaLib/BaseTools/ppersist.h
===================================================================
--- /trunk/SophyaLib/BaseTools/ppersist.h	(revision 2659)
+++ /trunk/SophyaLib/BaseTools/ppersist.h	(revision 2660)
@@ -187,4 +187,6 @@
 // On utilise le macro RAWPERSISTIO pour declarer POutPersist << et PInPersist >> 
 // pour les types de base r_4 r_8 int_4 int_8 ...
+  RAWPERSISTIO(int_8,I8);
+  RAWPERSISTIO(uint_8,U8);
   RAWPERSISTIO(int_4,I4);
   RAWPERSISTIO(uint_4,U4);
Index: /trunk/SophyaLib/BaseTools/ppfbinstream.cc
===================================================================
--- /trunk/SophyaLib/BaseTools/ppfbinstream.cc	(revision 2659)
+++ /trunk/SophyaLib/BaseTools/ppfbinstream.cc	(revision 2660)
@@ -1007,5 +1007,11 @@
   char * buff;
   string str;
-  
+  // Pour indenter lors de l'impression 
+  #define _MXINDENT_ 10 
+  char * indents[_MXINDENT_+1] = {"","  ", "    ", "      ", "        ", "          ",
+				    "            ", "              ", "                ",
+				    "                  ", "                    "};
+  int idxindent = 0;
+  int idxind = 0;
   cout << "\n ---------------------------------------------------------- " << endl;
   cout << " PPFBinaryInputStream::AnalyseTags(Level= " << lev << ")" << endl; 
@@ -1041,10 +1047,12 @@
 
       case PPS_NULL :
-	if (lev > 1)  cout << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
+	if (lev > 1)  cout << indents[idxindent] 
+			   << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
 	break;
 
       case PPS_STRING :
 	GetRawI4(i4);
-	if (lev > 1)  cout << "<PPS_STRING> tag at position " << hex << cpos << dec 
+	if (lev > 1)  cout << indents[idxindent]
+			   << "<PPS_STRING> tag at position " << hex << cpos << dec 
 			   << " Length=" << i4 << endl;
 	s->seekg(i4,ios::cur);
@@ -1054,6 +1062,9 @@
 	GetRawU8(cid);
 	GetRawU8(oid);
-	cout << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid 
+	cout << indents[idxindent] 
+	     << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid 
 	     << "  ObjectId= " << oid << dec << endl;
+	idxind++;
+	idxindent = (idxind <= _MXINDENT_) ? idxind : _MXINDENT_;
 	break;
 
@@ -1061,15 +1072,18 @@
 	GetRawU8(oid);
 	GetRawI8(i8);
-	cout << "<PPS_REFERENCE> tag at position " << hex << cpos << "  ObjectId= " 
+	cout << indents[idxindent] 
+	     << "<PPS_REFERENCE> tag at position " << hex << cpos << "  ObjectId= " 
 	     << oid << "  OrigPos=" << i8 << dec << endl;
 	break;
 
       case PPS_NAMETAG_MARK :
-	cout << "<PPS_NAMETAG_MARK> tag at position " << hex << cpos << dec << endl; 
+	cout << indents[idxindent] 
+	     << "<PPS_NAMETAG_MARK> tag at position " << hex << cpos << dec << endl; 
 	break;
 
       case PPS_POSTAG_MARK :
 	GetRawI8(i8);	
-	cout << "<PPS_POSTAG_MARK> tag at position " << hex << cpos 
+	cout << indents[idxindent] 
+	     << "<PPS_POSTAG_MARK> tag at position " << hex << cpos 
 	     << " TPos=" << i8 << dec << endl; 
 	break;
@@ -1077,6 +1091,9 @@
       case PPS_ENDOBJECT :
 	GetRawU8(oid);
-	cout << "<PPS_ENDOBJECT> tag at position " << hex << cpos << "  ObjectId= " 
+	cout << indents[idxindent] 
+	     << "<PPS_ENDOBJECT> tag at position " << hex << cpos << "  ObjectId= " 
 	     << oid << dec << endl;
+	idxind--;
+	idxindent = (idxind >= 0) ? idxind : 0;
 	break;
 
@@ -1084,5 +1101,6 @@
 	GetRawI4(i4);
 	for(int kkt=0; kkt<i4; kkt++)  GetRawI8(i8);	
-	cout << "<PPS_POSTAG_TABLE> tag at position " << hex << cpos << dec << endl; 
+	cout << indents[idxindent]
+	     << "<PPS_POSTAG_TABLE> tag at position " << hex << cpos << dec << endl; 
 	break;
 
@@ -1095,9 +1113,11 @@
 	  buff[i4] = '\0';  str = buff;
 	  delete[] buff;
-	  cout << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec 
+	  cout << indents[idxindent]
+	       << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec 
 	       << " Name= " << str << endl; 
 	}
 	else {
-	  cout << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec << endl;
+	  cout << indents[idxindent]
+	       << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec << endl;
 	  int_8 stats[8];
 	  GetI8s(stats,8); 
@@ -1117,5 +1137,6 @@
       case PPS_EOF :
 	if (Version() < 3) GetRawI8(i8);	
-	cout << "<PPS_EOF> tag at position " << hex << cpos  
+	cout << indents[idxindent]
+	     << "<PPS_EOF> tag at position " << hex << cpos  
 	     << " TagPos=" << i8 << dec << endl;
 	eofok = true;
@@ -1148,5 +1169,6 @@
 
       case PPS_SIMPLE :
-	if (lev > 2)  cout << "<PPS_SIMPLE> tag at position " << hex << cpos << dec 
+	if (lev > 2)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE> tag at position " << hex << cpos << dec 
 			   << " DataType=" << dtype << endl;
 	s->seekg(dsizeskip, ios::cur);
@@ -1155,5 +1177,6 @@
       case PPS_SIMPLE_ARRAY4 :
 	GetRawI4(i4);
-	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec 
+	if (lev > 0)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec 
 			   << " DataType=" << dtype << " NElts= " << i4 << endl;
 	s->seekg(dsizeskip*(int_8)i4, ios::cur);
@@ -1162,5 +1185,6 @@
       case PPS_SIMPLE_ARRAY8 :
 	GetRawU8(ui8);
-	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec 
+	if (lev > 0)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec 
 			   << " DataType=" << dtype << " NElts= " << ui8 << endl;
 	s->seekg(dsizeskip*ui8, ios::cur);
Index: /trunk/SophyaLib/BaseTools/ppfswapper.h
===================================================================
--- /trunk/SophyaLib/BaseTools/ppfswapper.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/ppfswapper.h	(revision 2660)
@@ -0,0 +1,49 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees swapable
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef PPFSWAPPER_H
+#define PPFSWAPPER_H
+
+
+#include "machdefs.h"
+#include "swsegdb.h"
+#include "ppersist.h"
+#include "ppftpointerio.h"
+
+namespace SOPHYA {
+/*!
+  \class SOPHYA::PPFDataSwapper
+  \ingroup BaseTools
+  Implementation of SOPHYA::DataSwapperInterface interface on PPF streams 
+  (POutPersist , PInPersist) to be used with SOPHYA::SwSegDataBlock classes.
+*/
+
+template <class T> 
+class PPFDataSwapper : public DataSwapperInterface<T> {
+public:
+  PPFDataSwapper(POutPersist & os) { ppfos = &os; ppfis = NULL;}
+  PPFDataSwapper(PInPersist & is) { ppfos = NULL; ppfis = &is;}
+  PPFDataSwapper(PInPersist & is, POutPersist & os) { ppfos = &os; ppfis = &is;}
+  virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false)
+  {
+    if (ppfos == NULL) throw NotAvailableOperation("PPFDataSwapper<T>::WriteToSwap() - No POutPersist stream !");
+    int_8 tag = ppfos->WritePositionTag();
+    PPF_TPointer_IO<T>::Write(*ppfos, d, sz);
+    return tag;
+  }
+  virtual void  ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz)
+  {
+    if (ppfis == NULL) throw NotAvailableOperation("PPFDataSwapper<T>::ReadFromSwap() - No PInPersist stream !");
+    bool ok = ppfis->GotoPositionTag(swp);
+    PPF_TPointer_IO<T>::Read(*ppfis, d, sz);
+    return;
+  }
+protected:
+  POutPersist* ppfos;
+  PInPersist* ppfis;
+};
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaLib/BaseTools/ppftpointerio.h
===================================================================
--- /trunk/SophyaLib/BaseTools/ppftpointerio.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/ppftpointerio.h	(revision 2660)
@@ -0,0 +1,104 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Classe pour faciliter entree-sortie PPF pour des pointeurs
+//       R. Ansari -  Mars 2005
+
+#ifndef PPFTPOINTERIO_H_SEEN
+#define PPFTPOINTERIO_H_SEEN
+
+#include "ppersist.h"
+
+//----------------------------------------------------------------------
+namespace SOPHYA {
+
+/*!
+  \class SOPHYA::PPF_TPointer_IO
+  \ingroup BaseTools
+  A template utility class with static methods to ease handling of array 
+  I/O in PPF streams (POutPersist and PInPersist). It is not intented for
+  direct use in user programs, but for writing PPF persistence handler 
+  classes (PPersist). 
+  The C++ I/O operators POutPersist& << and PInPersist& >> should be defined for
+  new types and classes.
+*/
+
+template <class T>
+class PPF_TPointer_IO {
+public:
+  //! Writes the array pointed to by \b arr (size \b n) to POutPersist stream \b os
+  static void Write(POutPersist & os,  T  const * arr, size_t n)
+  {
+    for(size_t k=0; k<n; k++) os << arr[k];
+  }
+  //! Reads from the PInPersist \b is into array pointed to by \b arr (size \b n)
+  static void Read(PInPersist & is, T * arr, size_t n)
+  {
+    for(size_t k=0; k<n; k++) is >> arr[k];
+  }
+};
+// Specific implementation using table I/O in PPFBinaryIOStreams 
+void PPF_TPointer_IO<char>::Write(POutPersist & os, char const * arr, size_t n)
+  { os.PutBytes(arr,n); }
+void PPF_TPointer_IO<char>::Read(PInPersist & is, char * arr, size_t n)
+  { is.GetBytes(arr,n); }
+
+void PPF_TPointer_IO< int_1 >::Write(POutPersist & os, int_1 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_1 >::Read(PInPersist & is, int_1 * arr, size_t n)
+  { is.Get(arr,n); }
+void PPF_TPointer_IO< uint_1 >::Write(POutPersist & os, uint_1 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_1 >::Read(PInPersist & is, uint_1 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_2 >::Write(POutPersist & os, int_2 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_2 >::Read(PInPersist & is, int_2 * arr, size_t n)
+  { is.Get(arr,n); }
+void PPF_TPointer_IO< uint_2 >::Write(POutPersist & os, uint_2 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_2 >::Read(PInPersist & is, uint_2 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_4 >::Write(POutPersist & os, int_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_4 >::Read(PInPersist & is, int_4 * arr, size_t n)
+  { is.Get(arr,n); }
+void PPF_TPointer_IO< uint_4 >::Write(POutPersist & os, uint_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_4 >::Read(PInPersist & is, uint_4 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_8 >::Write(POutPersist & os,  int_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_8 >::Read(PInPersist & is, int_8 * arr, size_t n)
+  { is.Get(arr,n); }
+void PPF_TPointer_IO< uint_8 >::Write(POutPersist & os,  uint_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_8 >::Read(PInPersist & is, uint_8 * arr, size_t n)
+  { is.Get(arr,n); }
+
+
+void PPF_TPointer_IO< r_4 >::Write(POutPersist & os, r_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< r_4 >::Read(PInPersist & is, r_4 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< r_8 >::Write(POutPersist & os,  r_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< r_8 >::Read(PInPersist & is, r_8 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< complex<r_4> >::Write(POutPersist & os, complex<r_4> const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< complex<r_4> >::Read(PInPersist & is, complex<r_4> * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< complex<r_8> >::Write(POutPersist & os, complex<r_8> const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< complex<r_8> >::Read(PInPersist & is, complex<r_8> * arr, size_t n)
+  { is.Get(arr,n); }
+
+
+}  // namespace SOPHYA
+
+#endif   /* PPFTPOINTERIO_H_SEEN */
Index: /trunk/SophyaLib/BaseTools/ppfwrapstlv.h
===================================================================
--- /trunk/SophyaLib/BaseTools/ppfwrapstlv.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/ppfwrapstlv.h	(revision 2660)
@@ -0,0 +1,111 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour la permettre la persistance PPF des vecteurs STL
+//                         R. Ansari - Avril 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PPFWRAPSTLV_H
+#define PPFWRAPSTLV_H
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include "ppersist.h"
+#include "pexceptions.h"
+#include <vector>
+#include <iostream>
+
+namespace SOPHYA {
+
+/*!
+   \class SOPHYA::PPFWrapperSTLVector
+   \ingroup BaseTools
+   Class for managing PPF persistence of standard (STL) vectors.
+   Only the overloaded operators I/O operators on POutPersist
+   and PInPersist streams are intended to be used in user programs.
+   When applied to vectors of user defined types and classes (\b T), the 
+   c++ I/O operators POutPersist& << and PInPersist& >> should be 
+   defined for the type \b T and the resulting handler must be registered
+   using the macro \b PPRegister(PPFWrapperSTLVector<T>)
+*/
+   
+template <class T>
+class PPFWrapperSTLVector : public  PPersist , AnyDataObj {
+public:
+  PPFWrapperSTLVector()
+  {
+    dobj = new std::vector<T> ;
+    ownobj=true;    
+  }
+
+  //   PPFWrapperSTLVector(string const & filename);
+  PPFWrapperSTLVector(std::vector<T> & obj)
+  {
+    dobj = &obj;
+    ownobj = false;
+  }
+
+  PPFWrapperSTLVector(std::vector<T> * obj)
+  {
+    if (obj == NULL)  
+      throw ParmError("PPFWrapperSTLVector<T>::PPFWrapperSTLVector(* obj) obj=NULL (ppfwrapstlv.h)");
+    dobj = obj;
+    ownobj = false;
+  }
+  virtual ~PPFWrapperSTLVector()
+  {
+    if (ownobj && dobj) delete dobj;
+  }
+  virtual AnyDataObj* DataObj() { return this; }
+  virtual void        SetDataObj(AnyDataObj & o)
+  {
+    throw NotAvailableOperation("PPFWrapperSTLVector<T>::SetDataObj() Not permitted ! (ppfwrapstlv.h)");
+  }
+  inline operator std::vector<T>()  { return(*dobj); }
+
+protected :
+  virtual void       ReadSelf(PInPersist& is)
+  {
+    if (dobj == NULL) 
+      throw ParmError("PPFWrapperSTLVector<T>::ReadSelf() dobj=NULL (ppfwrapstlv.h)");
+    // On lit les 3 premiers uint_8
+    uint_8 itab[3];
+    is.Get(itab, 3);
+    // On efface le contenu du vecteur si necessaire - (on peut faire plus efficacement ...)
+    if ( dobj->size() > 0) dobj->erase(dobj->begin(), dobj->end());
+    T el;
+    for(uint_8 k=0; k<itab[1]; k++) { 
+      is >> el;
+      dobj->push_back(el);
+    }
+  }         
+  virtual void       WriteSelf(POutPersist& os) const
+  {
+    if (dobj == NULL) 
+      throw ParmError("PPFWrapperSTLVector<T>::WriteSelf() dobj=NULL (ppfwrapstlv.h)");
+    //  On ecrit 3 uint_8 
+    //  0 : Numero de version = 1 : Taille,  2  reserve a l
+    uint_8 itab[3];
+    itab[0] = 1;
+    itab[1] = dobj->size();
+    itab[2] = 0;
+    os.Put(itab, 3);
+    // On ecrit le vecteur de donnees 
+    for(uint_8 k=0; k<itab[1]; k++) os << (*dobj)[k];
+  }
+
+  // Variables membres 
+  std::vector<T> * dobj;  // Le vecteur de la STL 
+  bool ownobj;  // true -> objet cree par le wrapper 
+};
+
+/*! Writes the STL vector object in the POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, std::vector<T> & obj)
+{ PPFWrapperSTLVector<T> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads in and initializes the STL vector object from the PInPersist stream \b is */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, std::vector<T> & obj)
+{ PPFWrapperSTLVector<T> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaLib/BaseTools/segdatablock.h
===================================================================
--- /trunk/SophyaLib/BaseTools/segdatablock.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/segdatablock.h	(revision 2660)
@@ -0,0 +1,254 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees avec partage de references
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef SEGDATABLOCK_H
+#define SEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include <string.h> 
+#include <vector>
+#include <iostream>
+#include <iomanip>
+#include <typeinfo>
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+//// ---------------- Class SegDBInterface ------------------ //
+//// ----------------- Class SegDataBlock ------------------- //
+////////////////////////////////////////////////////////////////
+
+/*!
+   \class SOPHYA::SegDBInterface
+   \ingroup BaseTools
+   Interface definition for segmented data container (template class).
+*/
+template <class T>
+class SegDBInterface : public AnyDataObj {
+public:
+  virtual ~SegDBInterface() {}
+  //! Changes the data segment size and reallocates the memory segments
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0) = 0;
+  //! Alias for SetSize()
+  inline void  ReSize(size_t segsz, size_t nbseg=0) { SetSize(segsz, nbseg); }
+  //! Adds one segment to the data structure - returns the new number of segments.
+  virtual size_t Extend() = 0;
+  //! Return the segment size data structure
+  virtual  size_t SegmentSize() const = 0; 
+  //! Return the number of data segments
+  virtual size_t NbSegments() const = 0;
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return  SegmentSize()*NbSegments(); }
+  //! Return pointer to data segment \b k
+  virtual T* GetSegment(size_t k) = 0;         
+  virtual T const * GetSegment(size_t k) const = 0; 
+};
+
+// classe de container avec partage de reference
+//! Segmented data container with reference sharing
+/*!
+   \class SOPHYA::SegDataBlock
+   \ingroup BaseTools
+   Template class impementing segmented data container in memory with 
+   management of reference sharing. 
+*/
+template <class T>
+class SegDataBlock : public SegDBInterface<T> {
+
+public:
+
+  //! Default constructor - optional specification of segment size and number of segments
+  explicit SegDataBlock(size_t segsz=32, size_t nbseg=0)
+  {
+    mSRef = NULL;
+    SetSize(segsz, nbseg);
+  }
+  //! copy constructor - shares the data
+  SegDataBlock(const SegDataBlock<T>& a)
+  {
+    mSRef = a.mSRef;
+    mSRef->nref++;
+  }
+  //! copy constructor with specification of flags for data sharing and element value copy
+  SegDataBlock(const SegDataBlock<T>& a, bool share, bool cpval=true)
+  {
+    if (share) {
+      mSRef = a.mSRef;
+      mSRef->nref++;
+    }
+    else {
+      mSRef = NULL;
+      Clone(a, cpval);
+    }
+  }
+  //! copy constructor - shares the data if \b is a SegDataBlock, clones otherwise
+  SegDataBlock(const SegDBInterface<T>& a)
+  {
+    SegDataBlock<T> * sdb = dynamic_cast< SegDataBlock<T> *>(&a);
+    if (p != NULL) { 
+      mSRef = p->mSRef;
+      mSRef->nref++;
+    }
+    else Clone(a, true);
+  }
+  //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
+  virtual ~SegDataBlock()
+  {
+    //DEL    cout << " DEBUG-~SegDataBlock() " << hex << mSRef << dec << " NRef()= " << NRef() << endl;
+     Delete();
+  }
+
+
+  //! Adds one segment to the data structure - returns the pointer to the allocated segment.
+  virtual size_t Extend()
+  {
+    T * p = new T[mSRef->segsize];
+    mSRef->dseg.push_back(p);
+    return( mSRef->dseg.size());
+  }
+
+  //! Changes the data segment size and reallocates the memory segments
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0)
+  {
+    Delete();
+    mSRef = new SDREF;
+    mSRef->nref = 1;
+    mSRef->segsize = segsz;
+    mSRef->dsid = AnyDataObj::getUniqueId();
+    for(size_t k=0; k<nbseg; k++) Extend();
+  }
+//! Shares the data between two SegDataBlock objects
+  void Share(const SegDataBlock<T>& a)
+  {
+    Delete();
+    mSRef = a.mSRef;
+    mSRef->nref++;
+  }
+
+//! Makes a clone of the data structure and optionaly copie the data 
+  void Clone(const SegDBInterface<T> & a, bool cpval=true)
+  {
+    Delete();
+    mSRef = new SDREF;
+    mSRef->nref = 1;
+    mSRef->segsize = a.SegmentSize();
+    for(size_t k=0; k<a.NbSegments(); k++) {
+      Extend();
+      if (cpval) {
+	T * dst = GetSegment(k);
+	const T * src = a.GetSegment(k);
+	memcpy(dst, src, mSRef->segsize*sizeof(T));
+      }
+    }   
+  }
+
+
+  //! Return the segment size of the data structure
+  virtual size_t SegmentSize() const  { return mSRef->segsize; }
+  //! Return the number of data segments
+  virtual size_t NbSegments() const  { return mSRef->dseg.size(); }
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return mSRef->segsize*mSRef->dseg.size(); }
+
+  //! Return pointer to data segment \b k
+  virtual T* GetSegment(size_t k)              { return mSRef->dseg[k]; } 
+  virtual T const * GetSegment(size_t k) const { return mSRef->dseg[k]; } 
+
+  //! Return the segment index for  element \b i
+  inline size_t SegIndex(size_t i) {  return i/mSRef->segsize; }
+  //! Return the offset (in data segment)  for  element \b i
+  inline size_t EltOffset(size_t i) {  return i%mSRef->segsize; }
+
+  //! Return the \b i th element of the segmented data structure   
+  inline T& operator()(size_t i)       { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of  the data structure
+  inline T& operator()(size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of the segmented data structure   
+  inline T& operator[](size_t i)       { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of  the data structure
+  inline T& operator[](size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+
+
+  //! Return the number of references to the data structure
+  inline size_t NRef() const { return mSRef->nref; }
+
+  //! Equal operator. Set all element values to \b v 
+  SegDataBlock<T>& operator = (T const & v)
+  {
+    for(size_t k=0; k<NbSegments(); k++) {
+      T * p = mSRef->dseg[k];
+      for(size_t j=0; j<SegmentSize(); j++) p[j] = v;
+    }
+    return (*this);
+  }
+  //! Equal operator. Clones and copie values from \b a
+  inline SegDataBlock<T>& operator = (const SegDBInterface<T> & a)
+  {
+    Clone(a, true);
+    return (*this);
+  }
+
+  //! ASCII formatted output (print)
+  void Print(ostream& os, int lev=0, const char * sep=NULL) const
+  {
+    os << "SegDataBlock< " << typeid(T).name() << "> mSRef= " << hex << mSRef
+       << " NRef=" << dec << NRef() << " DSId= " <<  DRefId() << endl;
+    os << " ... SegSize= " << SegmentSize() << " NbSeg= " << NbSegments() 
+       << "  Size= " << Size() << endl;
+    if (sep == NULL) sep = "  ";
+    if (lev > 0) {  
+      for(size_t k=0; k<NbSegments(); k++) {
+	T * p = mSRef->dseg[k];
+	os << " ..... DataSeg[ " << k << " ] : " << hex << p << dec << endl;
+	if (lev > 1) 
+	  for(size_t j=0; j<SegmentSize(); j++)  os << p[j] << sep;
+	os << endl;     
+      }
+    }
+  }
+  //! ASCII formatted output (print) on cout
+  inline void Print(int lev=0, const char * sep=NULL) const
+  {
+    Print(cout, lev, sep);
+  }
+
+  //! Returns the unique object identifier 
+  inline uint_8 DRefId() const { return mSRef->dsid; }
+
+protected:
+  void Delete() 
+  {
+    if (mSRef == NULL) return;
+    mSRef->nref--;
+    if (mSRef->nref > 0)  { mSRef = NULL; return; }
+    //DEL cout << " DEBUG-SegDataBlock::Delete() NbSegments() = " << NbSegments() << endl;
+    for(size_t k=0; k<NbSegments(); k++) {
+      delete[] mSRef->dseg[k];
+      mSRef->dseg[k] = NULL;
+    }
+    delete mSRef;
+    mSRef = NULL;
+  }
+  //! SDREF structure for reference management - for internal use by SegDataBlock
+  typedef struct {
+    size_t nref;      //!< Number of references to the data structure
+    uint_8 dsid;      //!< Data structure Id - Used by FIO_SegDataBlock
+    std::vector<T *> dseg;
+    size_t segsize;
+  } SDREF;
+
+  SDREF *  mSRef;    //!< SDREF structure for reference sharing
+};
+
+//! Definition of operator \<\< for ascii formatted output of SegDataBlock
+template<class T> 
+inline ostream& operator << (ostream& os, const SegDataBlock<T>& a)
+  {  a.Print(os); return(os); }
+
+} // Fin du namespace
+
+#endif
Index: /trunk/SophyaLib/BaseTools/sophyainit.cc
===================================================================
--- /trunk/SophyaLib/BaseTools/sophyainit.cc	(revision 2659)
+++ /trunk/SophyaLib/BaseTools/sophyainit.cc	(revision 2660)
@@ -14,4 +14,7 @@
 #include "fiondblock.h"
 #include "dvlist.h"
+
+#include "fiosegdb.h" 
+#include "ppfwrapstlv.h" 
 
 #include "sversion.h"
@@ -52,5 +55,7 @@
   #endif
 
+  // Initialisation des mecanismes PPF I/O 
   PIOPersist::Initialize();
+  // Enregistrement des handlers PPF pour les NDataBlock<T> 
   PPRegister(FIO_NDataBlock<uint_1>);
   DObjRegister(FIO_NDataBlock<uint_1>, NDataBlock<uint_1>);
@@ -76,6 +81,55 @@
   DObjRegister(FIO_NDataBlock< complex<r_8> >, NDataBlock< complex<r_8> >);
 
+  // Enregistrement des handlers PPF pour les DVList
   PPRegister(ObjFileIO<DVList>);
   DObjRegister(ObjFileIO<DVList>, DVList);
+
+  // Enregistrement des handlers PPF pour les SegDataBlock<T> 
+  PPRegister(FIO_SegDataBlock<uint_2>);
+  DObjRegister(FIO_SegDataBlock<uint_2>, SegDataBlock<uint_2>);
+  PPRegister(FIO_SegDataBlock<int_2>);
+  DObjRegister(FIO_SegDataBlock<int_2>, SegDataBlock<int_2>);
+  PPRegister(FIO_SegDataBlock<int_4>);
+  DObjRegister(FIO_SegDataBlock<int_4>, SegDataBlock<int_4>);
+  PPRegister(FIO_SegDataBlock<int_8>);
+  DObjRegister(FIO_SegDataBlock<int_8>, SegDataBlock<int_8>);
+  PPRegister(FIO_SegDataBlock<uint_4>);
+  DObjRegister(FIO_SegDataBlock<uint_4>, SegDataBlock<uint_4>);
+  PPRegister(FIO_SegDataBlock<uint_8>);
+  DObjRegister(FIO_SegDataBlock<uint_8>, SegDataBlock<uint_8>);
+  PPRegister(FIO_SegDataBlock<r_4>);
+  DObjRegister(FIO_SegDataBlock<r_4>, SegDataBlock<r_4>);
+  PPRegister(FIO_SegDataBlock<r_8>);
+  DObjRegister(FIO_SegDataBlock<r_8>, SegDataBlock<r_8>);
+  PPRegister(FIO_SegDataBlock< complex<r_4> >);
+  DObjRegister(FIO_SegDataBlock< complex<r_4> >, SegDataBlock< complex<r_4> >);
+  PPRegister(FIO_SegDataBlock< complex<r_8> >);
+  DObjRegister(FIO_SegDataBlock< complex<r_8> >, SegDataBlock< complex<r_8> >);
+  PPRegister(FIO_SegDataBlock<string>);
+  DObjRegister(FIO_SegDataBlock<string>, SegDataBlock<string>);
+
+  // Enregistrement des handlers PPF pour les vecteurs de la STL
+  PPRegister(PPFWrapperSTLVector<uint_2>);
+  DObjRegister(PPFWrapperSTLVector<uint_2>, std::vector<uint_2>);
+  PPRegister(PPFWrapperSTLVector<int_2>);
+  DObjRegister(PPFWrapperSTLVector<int_2>, std::vector<int_2>);
+  PPRegister(PPFWrapperSTLVector<int_4>);
+  DObjRegister(PPFWrapperSTLVector<int_4>, std::vector<int_4>);
+  PPRegister(PPFWrapperSTLVector<int_8>);
+  DObjRegister(PPFWrapperSTLVector<int_8>, std::vector<int_8>);
+  PPRegister(PPFWrapperSTLVector<uint_4>);
+  DObjRegister(PPFWrapperSTLVector<uint_4>, std::vector<uint_4>);
+  PPRegister(PPFWrapperSTLVector<uint_8>);
+  DObjRegister(PPFWrapperSTLVector<uint_8>, std::vector<uint_8>);
+  PPRegister(PPFWrapperSTLVector<r_4>);
+  DObjRegister(PPFWrapperSTLVector<r_4>, std::vector<r_4>);
+  PPRegister(PPFWrapperSTLVector<r_8>);
+  DObjRegister(PPFWrapperSTLVector<r_8>, std::vector<r_8>);
+  PPRegister(PPFWrapperSTLVector< complex<r_4> >);
+  DObjRegister(PPFWrapperSTLVector< complex<r_4> >, std::vector< complex<r_4> >);
+  PPRegister(PPFWrapperSTLVector< complex<r_8> >);
+  DObjRegister(PPFWrapperSTLVector< complex<r_8> >, std::vector< complex<r_8> >);
+  PPRegister(PPFWrapperSTLVector<string>);
+  DObjRegister(PPFWrapperSTLVector<string>, std::vector<string>);
 
 
Index: /trunk/SophyaLib/BaseTools/swsegdb.h
===================================================================
--- /trunk/SophyaLib/BaseTools/swsegdb.h	(revision 2660)
+++ /trunk/SophyaLib/BaseTools/swsegdb.h	(revision 2660)
@@ -0,0 +1,175 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees swapable
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef SWSEGDATABLOCK_H
+#define SWSEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "segdatablock.h"
+#include "pexceptions.h"
+#include <vector>
+#include <typeinfo>
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+//// ------------- Class DataSwapperInterface --------------- //
+//// ---------------- Class SwSegDataBlock ------------------ //
+////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::DataSwapperInterface
+  \ingroup BaseTools
+  Interface definition for  data swapper (pure virtual) classes to be used 
+  with SOPHYA::SwSegDataBlock classes.
+*/
+template <class T> 
+class DataSwapperInterface {
+public:
+  virtual ~DataSwapperInterface() { }
+  //! Swap out the data array pointed by \b d with size \b sz
+  virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false) = 0;
+  //! Swap in the data array pointed by \b d with size \b sz
+  virtual void  ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz) = 0;
+};
+
+//! Segmented data structure with swap management
+/*!
+  \class SOPHYA::SwSegDataBlock
+  \ingroup BaseTools
+  Segmented data structure with swap space management.
+*/
+template <class T>
+class SwSegDataBlock : public SegDBInterface<T> {
+public:
+  //! Constructor - creation from swap position tags (values)
+  SwSegDataBlock(DataSwapperInterface<T> & dsw, vector<int_8> const & swpos, size_t segsz)
+  {
+    mSRef = NULL;
+    SetSize(segsz, swpos.size());
+    mSRef->swapper = &dsw;
+    mSRef->swp = swpos;
+    for(size_t k=0; k<mSRef->fgwp.size(); k++)  mSRef->fgwp[k] = true; 
+    }
+  //! Constructor - optional specification of segment size and number of segments
+  SwSegDataBlock(DataSwapperInterface<T> & dsw, size_t segsz=32, size_t nbseg=0)
+  {
+    mSRef = NULL;
+    SetSize(segsz, nbseg);
+    mSRef->swapper = &dsw;
+  }
+  //! copy constructor - shares the data
+  SwSegDataBlock(const SwSegDataBlock<T>& a)
+  {
+    mSRef = a.mSRef;
+    mSRef->nref++;
+  }
+
+  //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
+  virtual ~SwSegDataBlock() { Delete(); }
+  //! Adds one segment to the data structure - returns the pointer to the allocated segment.
+  virtual size_t Extend() 
+  {
+    mSRef->swp.push_back(0);
+    mSRef->fgwp.push_back(false);
+    return mSRef->swp.size();
+  }
+  //! Changes the data segment size and reallocates the memory segments
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0)
+  {
+    Delete();
+    mSRef = new SWSDREF;
+    mSRef->nref = 1;
+    mSRef->segsize = segsz;
+    mSRef->dsid = AnyDataObj::getUniqueId();
+    mSRef->buff = new T[segsz];
+    mSRef->bidx = -1;        
+    mSRef->fgcstbuff = true; 
+    for(size_t k=0; k<nbseg; k++) {
+      mSRef->swp.push_back(0);
+      mSRef->fgwp.push_back(false);
+    }
+  }
+  //! Return the segment size data structure
+  virtual  size_t SegmentSize() const  { return mSRef->segsize; }
+  //! Return the number of data segments
+  virtual size_t NbSegments() const { return mSRef->swp.size(); } ;
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return  mSRef->swp.size()*mSRef->segsize; }
+  //! Return pointer to data segment \b k
+  virtual T* GetSegment(size_t k) 
+  {
+    getSeg(k);
+    mSRef->fgcstbuff = false;
+    return mSRef->buff;
+  }
+         
+  virtual T const * GetSegment(size_t k) const 
+  {
+    getSeg(k);
+    mSRef->fgcstbuff = true;
+    return mSRef->buff;
+  }
+  //! Return the position tag (swap position) table
+  std::vector< int_8 > & GetSwapPosTagTable() const 
+  { 
+    if ((mSRef->bidx >= 0) && !mSRef->fgcstbuff) {
+      int_8 nswp = mSRef->swapper->WriteToSwap(mSRef->buff, mSRef->segsize, mSRef->bidx, 
+					       mSRef->swp[mSRef->bidx], mSRef->fgwp[mSRef->bidx]);
+      mSRef->swp[mSRef->bidx] = nswp;
+      mSRef->fgwp[mSRef->bidx] = true;
+    }
+    return  mSRef->swp; 
+  } 
+
+protected: 
+  SwSegDataBlock() 
+  {
+    throw ForbiddenError("SwSegDataBlock() default constructor not allowed (swsegdb.h)");
+  }
+  void Delete()   
+  {
+    if (mSRef == NULL) return;
+    mSRef->nref--;
+    if (mSRef->nref > 0)  { mSRef = NULL; return; }
+    delete[] mSRef->buff;
+    delete mSRef;
+    mSRef = NULL;  
+  } 
+  void getSeg(size_t k) const
+  {
+    if (k == mSRef->bidx)  return ;
+    if ((mSRef->bidx >= 0) && !mSRef->fgcstbuff) {
+      int_8 nswp = mSRef->swapper->WriteToSwap(mSRef->buff, mSRef->segsize, mSRef->bidx, 
+					       mSRef->swp[mSRef->bidx], mSRef->fgwp[mSRef->bidx]);
+      mSRef->swp[mSRef->bidx] = nswp;
+      mSRef->fgwp[mSRef->bidx] = true;
+    }
+    if (mSRef->fgwp[k]) 
+      mSRef->swapper->ReadFromSwap(k, mSRef->swp[k], mSRef->buff, mSRef->segsize);
+    else { delete[] mSRef->buff;  mSRef->buff = new T[mSRef->segsize]; }  
+    mSRef->bidx = k;
+    return;
+  }
+
+  typedef struct {
+    size_t nref;      // Number of references to the data structure  
+    uint_8 dsid;      // Data structure id
+    size_t segsize;   // data segment size
+    mutable std::vector< int_8 > swp;  // swap position tag for each segment
+    mutable std::vector< bool > fgwp;  // swap flag (true = already swapped)  for each segment
+    mutable T * buff;                // Data buffer   
+    mutable int_8 bidx;              // segment index (number) corresponding to buffer 
+    mutable bool fgcstbuff;            // true : this is a constant T * buff<
+    DataSwapperInterface<T> * swapper;   // Data swapper
+  } SWSDREF;
+
+  SWSDREF *  mSRef;    // SWSDREF structure for reference sharing
+};
+
+
+} // Fin du namespace
+
+#endif
