Index: trunk/SophyaLib/BaseTools/ndatablock.cc
===================================================================
--- trunk/SophyaLib/BaseTools/ndatablock.cc	(revision 489)
+++ trunk/SophyaLib/BaseTools/ndatablock.cc	(revision 502)
@@ -1,4 +1,4 @@
 // Gestion de block de donnees avec partage de references
-//                         C.Magneville          04/99
+// malheureusement tres mal concu...  C.Magneville 04/99
 // LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
 #include "machdefs.h"
@@ -37,6 +37,6 @@
 template <class T>
 NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br)
-// Createur d'une structure de "n" donnees, avec donnees preallouees
-//  (Voir explications dans Alloc())
+// Createur d'une structure de "n" donnees, avec donnees preallouees.
+// Attention createur TRES DANGEREUX (Voir explications dans Alloc()).
 : mSz(0), mSRef(NULL), mIsTemp(false)
 {
@@ -100,5 +100,5 @@
 void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br)
 // Allocation d'un NOUVEL espace de stoquage de "n" donnees
-// Si data==NULL : allocation de l'espace memoire (vide)
+// Si data==NULL : allocation de l'espace memoire (remplit de zeros)
 //    data!=NULL : partage des donnees avec l'adresse data
 // Si br==NULL   : les donnees nous appartiennent
@@ -106,17 +106,58 @@
 //
 // Exemple: on veut connecter a un tableau de T*
-// 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "data"
+// > float *x = new float[5]; ... remplissage de x[] ...;
+// 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]"
 //    a- Premiere solution
-//       float *x = new float[5]; ... remplissage de x[] ...;
-//       NDataBlock A(5,x,new Bridge);
-//       delete [] x;   // Il faut deleter explicitement
-//       (et Bridge est delete par le destructeur de la classe)
+//       > NDataBlock A(5,x,new Bridge);
+//       ......
+//       > delete [] x;
+//          - Il faut deleter x[] explicitement.
+//          - Le destructeur de "A" ne detruit pas x[].
+//          ATTENTION: Une fois x[] detruit, "A" ne peut
+//                     plus acceder les donnees!
+//          - Bridge est detruit par le destructeur de "A"
 //    b- Autre solution:
-//       NDataBlock A(5); A.FillFrom(5,x);
-//       delete [] x;   // Il faut deleter explicitement
+//       > NDataBlock A(5); A.FillFrom(5,x);
+//       > delete [] x;
+//       ......
+//          - Il faut deleter x[] explicitement.
+//          - "A" possede une copie en local de x[].
+//          - Le destructeur de "A" ne detruit pas x[] mais la copie locale.
 // 2- On veut que NDataBlock desalloue le tableau
-//       float *x = new float[5]; ... remplissage de x[] ...;
-//       NDataBlock A(5,x);
-//       (Ne Pas Faire "delete [] x;")
+//       > NDataBlock A(5,x);
+//          - Ne Pas Faire "delete [] x;"
+//          - "A" partage les donnees avec x[].
+//          - Le destructeur de "A" detruit x[].
+//
+// --- REMARQUE SUR LE DANGER DE CERTAINES SITUATIONS (CMV):
+// 1-/ x = new float[n1]; NDataBlock A(n2,x);
+//     1er danger: si n2>n1 depassement de tableaux (core dump)
+//     2sd danger: celui qui alloue x[] ne doit pas faire le "delete"
+//                 en desaccord avec toutes les regles de bonne conduite.
+// 2-/ float x[5]={1,2,3,4,5}; {NDataBlock A(n2,&x[0]);} cout<<x[2];
+//     Ici, a la sortie du bloc {}, le destructeur de "A" va detruire
+//     l'adresse de &x[0]: je n'ose imaginer que ca se fasse sans probleme
+//     et de toute facon, cout<<x[2]; va surement faire des etincelles.
+// 3-/ x = new float[n1]; NDataBlock A(n2,x,new Bridge);
+//     1er danger: si n2>n1 depassement de tableaux (core dump)
+//     2sd danger: si la methode bridgee (blitz?) detruit x[]
+//                 "A" n'a plus de donnees connectees!
+// --- CONCLUSION
+// Cette classe est franchement merdique.
+// - On peut accepter la prise de risque liee a NDataBlock(n2,x,new Bridge);
+//   car je ne vois pas comment on pourrait faire autrement pour connecter
+//   un tableau de type blitz par exemple.
+// - Par contre le createur NDataBlock(n2,x); doit etre interdit
+//   dans sa forme actelle car trop dangereux et il me semble inutile.
+// - Dans cette nouvelle optique:
+//   NDataBlock(n2,x,new Bridge) et NDataBlock(n2,x) disparaissent
+//   On remplace par NDataBlock(n2,x) {Alloc(n2,x,new Bridge);}
+//      qui force le Bridge dans tout les cas puisque NDataBlock
+//      ne possede pas les donnees.
+//   Mais puis-je encore le faire vu que NDataBlock est a la base
+//   de TVector,TMatrix et qu'il faut donc reprendre tout le code DPC
+// - Quoiqu'il arrive Alloc est une methode privee et peut donc rester
+//   sous sa forme actuelle.
+//            
 {
 #ifdef DEBUG_NDATABLOCK
@@ -219,6 +260,6 @@
 
 #ifdef DEBUG_NDATABLOCK
-cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="
-    <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
+  cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="
+      <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
 #endif
 
@@ -252,4 +293,34 @@
 if(mSz<n) n = mSz;
 memcpy(Data(),data,n*sizeof(T));
+}
+
+template <class T>
+void NDataBlock<T>::Realloc(size_t nnew,bool force)
+// Re-allocation de "nnew" place memoire pour les donnees
+// avec conservation des "nold" donnees precedentes si possible.
+// "force" gere la re-allocation de la place memoire pour les donnees.
+// Divers cas se presentent:
+// a-/ *** nnew>nold force=quelconque ***
+//     place re-allouee, donnees [0,nold[ copiees, surplus [nold,new[ mis a zero
+// b-/ *** nnew<=nold force=true ***
+//     place re-allouee, donnees [0,nnew[ copiees, pas de surplus
+// c-/ *** nnew<=nold force=false ***
+//     place non re-allouee, seule la valeur de la taille est diminuee
+// - On tient compte du partage des donnees dans tous les cas.
+// - Si il n'y a pas de donnees connectees a la classe, on re-alloue
+//   dans tous les cas
+{
+if(nnew==0) throw(ParmError("NDataBlock::Realloc  n<=0\n"));
+
+// Cas sans re-allocation memoire
+if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;}
+
+// Cas avec re-allocation memoire
+size_t ncop;
+if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew;
+T* dataloc = new T[nnew];
+if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T));
+if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T));
+Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge
 }
 
Index: trunk/SophyaLib/BaseTools/ndatablock.h
===================================================================
--- trunk/SophyaLib/BaseTools/ndatablock.h	(revision 489)
+++ trunk/SophyaLib/BaseTools/ndatablock.h	(revision 502)
@@ -46,5 +46,12 @@
   inline void Reset(T v=0)
          {if(mSz==0) return; T *p=Begin(),*pe=End(); while(p<pe) *p++=v;}
+
+  // ReSize redimmensionne une structure pour "n" donnees.
+  // Les donnees precedentes sont perdues (pour cette classe)
+  // et le nouveau tableau mis a zero. La nouvelle structure de
+  // donnees n'a qu'une reference (celle de cette classe).
   inline void ReSize(size_t n) {Alloc(n);}
+
+  void Realloc(size_t nnew,bool force=false);
   
   // Informations pointeur/data
@@ -60,4 +67,5 @@
   inline T*        End()          {return mSRef->data+mSz;}
   inline T const*  End() const    {return mSRef->data+mSz;}
+  inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;}
 
   // Impression
