Back to index

salome-kernel  6.5.0
CalciumCouplingPolicy.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : CalciumCouplingPolicy.hxx
00024 //  Author : Eric Fayolle (EDF)
00025 //  Module : KERNEL
00026 // Id          : $Id: CalciumCouplingPolicy.hxx,v 1.3.2.3.10.2.12.1 2012-04-12 14:05:06 vsr Exp $
00027 //
00028 #ifndef __CALCIUM_COUPLING_POLICY__ 
00029 #define __CALCIUM_COUPLING_POLICY__
00030 
00031 #include <vector>
00032 #include <map>
00033 
00034 #include "DisplayPair.hxx"
00035 #include "CouplingPolicy.hxx"
00036 #include "AdjacentFunctor.hxx"
00037 #include <boost/lambda/lambda.hpp>
00038 #include <boost/utility/enable_if.hpp>
00039 #include <boost/type_traits/is_arithmetic.hpp>
00040 #include "CalciumTypes.hxx"
00041 #include "CalciumException.hxx"
00042 
00043 //#define MYDEBUG
00044 
00045 class CalciumCouplingPolicy : public CouplingPolicy  {
00046 
00047 
00048 public:
00049 
00050   template <typename T_TIME, typename T_TAG >        class InternalDataIdContainer;
00051   template <typename T_TIME, typename T_TAG > friend class InternalDataIdContainer;
00052   template <typename DataManipulator, 
00053     class EnableIf >                  friend class BoundedDataIdProcessor;
00054   template <typename DataManipulator >        friend class EraseDataIdProcessor;
00055   template <typename DataManipulator >        friend class EraseDataIdBeforeOrAfterTagProcessor;
00056   template <typename DataManipulator >        friend class DisconnectProcessor;
00057 
00058   typedef CalciumTypes::DependencyType       DependencyType;
00059   typedef CalciumTypes::DateCalSchem         DateCalSchem;
00060   typedef CalciumTypes::InterpolationSchem   InterpolationSchem;
00061   typedef CalciumTypes::ExtrapolationSchem   ExtrapolationSchem;
00062   typedef CalciumTypes::DisconnectDirective  DisconnectDirective;  
00063 
00064 private:
00065 
00066   DependencyType      _dependencyType;
00067   size_t              _storageLevel;
00068   DateCalSchem        _dateCalSchem;
00069   InterpolationSchem  _interpolationSchem;
00070   ExtrapolationSchem  _extrapolationSchem;
00071   double              _alpha;
00072   double              _deltaT;
00073   DisconnectDirective _disconnectDirective;
00074 
00075 public:
00076   CalciumCouplingPolicy();
00077 
00078   void           setDependencyType (DependencyType dependencyType);
00079   DependencyType getDependencyType () const;
00080  
00081   void   setStorageLevel   (size_t storageLevel);
00082   size_t getStorageLevel   () const;
00083 
00084   void         setDateCalSchem   (DateCalSchem   dateCalSchem);
00085   DateCalSchem getDateCalSchem () const;
00086 
00087   void   setAlpha(double alpha);
00088   double getAlpha() const ;
00089 
00090   void   setDeltaT(double deltaT );
00091   double getDeltaT() const ;
00092 
00093   void setInterpolationSchem (InterpolationSchem interpolationSchem);
00094   void setExtrapolationSchem (ExtrapolationSchem extrapolationSchem);
00095   InterpolationSchem getInterpolationSchem () const ;
00096   ExtrapolationSchem getExtrapolationSchem () const ;
00097 
00098   // Classe DataId rassemblant les paramètres de la méthode PORT::put 
00099   // qui identifient l'instance d'une donnée pour Calcium
00100   // Rem : Le DataId doit pouvoir être une key dans une map stl
00101   typedef double TimeType;
00102   typedef long   TagType;
00103   typedef std::pair< TimeType , TagType >     DataId;
00104   typedef InternalDataIdContainer < TimeType , TagType >  DataIdContainer;
00105   typedef std::vector< DataId >::iterator  iterator;
00106 
00107   template <typename T_TIME, typename T_TAG >  
00108   struct InternalDataIdContainer;
00109 
00110   inline TimeType getTime(const DataId &dataId) const { return dataId.first;}
00111   inline TagType  getTag (const DataId &dataId) const { return dataId.second;}
00112 
00113   template <typename DataManipulator, 
00114             class EnableIf = void >    struct BoundedDataIdProcessor;
00115   //template <typename DataManipulator>  struct BoundedDataIdProcessor;
00116   template <typename DataManipulator>  struct EraseDataIdProcessor;
00117   template <typename DataManipulator>  struct EraseDataIdBeforeOrAfterTagProcessor;
00118   template <typename DataManipulator>  struct DisconnectProcessor;
00119 
00120   // Renvoie isEqual si le dataId attendu est trouvé dans storedDataIds :
00121   //   - l'itérateur wDataIt1 pointe alors sur ce dataId
00122   // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et 
00123   // que la politique de couplage gére ce cas de figure 
00124   //   - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
00125   // Le container doit être associatif
00126   template < typename AssocContainer >
00127   bool isDataIdConveniant( AssocContainer & storedDatas, 
00128                            const typename AssocContainer::key_type & expectedDataId,
00129                            bool & isEqual, bool & isBounded, 
00130                            typename AssocContainer::iterator & wDataIt1) const;
00131 
00132   TimeType getEffectiveTime(TimeType ti, TimeType tf);
00133 
00134   void disconnect(bool provideLastGivenValue);
00135 
00136 }; //Fin de CalciumCouplingPolicy
00137 
00138 
00139 
00140 //*************   DEFINITION DES METHODES ET OBJETS TEMPLATES *************// 
00141 
00142 
00143 
00144 // Définition du container de DataId pour répondre au concept
00145 // de mode de couplage
00146 template <typename T_TIME, typename T_TAG > 
00147 struct CalciumCouplingPolicy::InternalDataIdContainer : public std::vector< std::pair< T_TIME,T_TAG> >  {
00148   typedef std::vector < DataId >        DataIdVect;
00149     
00150   InternalDataIdContainer(const DataId & dataId, 
00151                           const CalciumCouplingPolicy & policy
00152                           ):std::vector< std::pair< T_TIME,T_TAG> >() {
00153     // Ignore les paramètres qui ne sont pas en rapport avec le type de dépendance
00154     switch (policy._dependencyType) {
00155     case CalciumTypes::TIME_DEPENDENCY:
00156       this->push_back(DataId(dataId.first,0));
00157       break;
00158     case CalciumTypes::ITERATION_DEPENDENCY:
00159       this->push_back(DataId(0,dataId.second));
00160       break;
00161     default:
00162       throw(CalciumException(CalciumTypes::CPIT,LOC("The dependency type must be set by setDependencyType before calling DataIdContainer contructor")));
00163       break;
00164     }
00165   };
00166 };
00167 
00168 
00169 template <typename DataManipulator, class EnableIf >
00170 struct CalciumCouplingPolicy::BoundedDataIdProcessor{
00171   BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
00172   template < typename Iterator, typename DataId > 
00173   void inline apply(typename iterator_t<Iterator>::value_type & data,
00174                     const DataId & dataId,
00175                     const Iterator  & it1) const {
00176     typedef typename iterator_t<Iterator>::value_type value_type;
00177 #ifdef MYDEBUG
00178     std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl;
00179 #endif
00180 
00181   }
00182 };
00183 
00184 
00185 template <typename DataManipulator >
00186 struct CalciumCouplingPolicy::BoundedDataIdProcessor<
00187   DataManipulator, 
00188   typename boost::enable_if< boost::is_float< typename DataManipulator::InnerType> >::type > {
00189     
00190   const CalciumCouplingPolicy & _couplingPolicy;
00191     
00192   BoundedDataIdProcessor(const CalciumCouplingPolicy &couplingPolicy):
00193     _couplingPolicy(couplingPolicy) {};
00194     
00195   // Méthode implémentant l'interpolation temporelle
00196   template < typename MapIterator > 
00197   void inline apply (typename iterator_t<MapIterator>::value_type & data,
00198                      const DataId & dataId, const MapIterator & it1) const {
00199       
00200     typedef typename iterator_t<MapIterator>::value_type value_type;
00201     typedef typename DataManipulator::InnerType InnerType;
00202     typedef typename DataManipulator::Type Type;
00203 
00204     MapIterator it2=it1; ++it2;
00205     size_t   dataSize1 = DataManipulator::size(it1->second);
00206 #ifdef MYDEBUG
00207     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId1 : " << dataSize1 << std::endl;
00208 #endif
00209  
00210     // Gérer dans calcium la limite de la taille du buffer donnée par
00211     // l'utilisateur.
00212     size_t   dataSize2 = DataManipulator::size(it2->second);
00213 #ifdef MYDEBUG
00214     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId2 : " << dataSize2 << std::endl;
00215 #endif
00216 
00217     size_t   dataSize  = std::min< size_t >( dataSize1, dataSize2 );
00218     DataId   dataId2 = it2->first;
00219     DataId   dataId1 = it1->first;
00220     TimeType t2      = dataId2.first;
00221     TimeType t1      = dataId1.first;
00222 #ifdef MYDEBUG
00223     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t1 : " << t1 << std::endl;
00224     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t2 : " << t2 << std::endl;
00225 #endif
00226     TimeType t       = dataId.first;
00227 #ifdef MYDEBUG
00228     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t : " << t << std::endl;
00229 #endif
00230     TimeType timeDiff  = t2-t1;
00231 #ifdef MYDEBUG
00232     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de timeDiff : " << timeDiff << std::endl;
00233 #endif
00234     TimeType coeff   = (t2-t)/timeDiff;
00235 #ifdef MYDEBUG
00236     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de coeff : " << coeff << std::endl;
00237 #endif
00238 
00239     InnerType const * const InIt1 = DataManipulator::getPointer(it1->second);
00240 #ifdef MYDEBUG
00241     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t1 : " << std::endl;
00242     std::copy(InIt1,InIt1+dataSize1,std::ostream_iterator<InnerType>(std::cout," "));
00243     std::cout << std::endl;
00244 #endif
00245     InnerType const * const InIt2 = DataManipulator::getPointer(it2->second);
00246 #ifdef MYDEBUG
00247     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t2 : " << std::endl;
00248     std::copy(InIt2,InIt2+dataSize2,std::ostream_iterator<InnerType>(std::cout," "));
00249     std::cout << std::endl;
00250 #endif
00251     Type              dataOut = DataManipulator::create(dataSize);
00252     InnerType * const OutIt   = DataManipulator::getPointer(dataOut);
00253  
00254 #ifdef MYDEBUG
00255     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : interpolationSchem : " << _couplingPolicy._interpolationSchem << std::endl;
00256     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : alpha : " << _couplingPolicy._alpha << std::endl;
00257     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : datecalschem : " << _couplingPolicy._dateCalSchem << std::endl;
00258     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : storageLevel : " << _couplingPolicy._storageLevel << std::endl;
00259 #endif
00260     if ( timeDiff == 0.0 ||  _couplingPolicy._interpolationSchem == CalciumTypes::L0_SCHEM ) {
00261       std::copy(InIt1,InIt1+dataSize,OutIt);
00262     } else {
00263 
00264       boost::lambda::placeholder1_type _1;
00265       boost::lambda::placeholder2_type _2;
00266       // OLD: REM : Pour des buffers de type int
00267       // OLD: le compilo indiquera warning: converting to `long int' from `Double'
00268       std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
00269                      ( _1 - _2 ) * coeff + _2 );
00270 //       for(size_t i =0;  i < dataSize3; ++i) {
00271 //      OutIt[i]=(InIt1[i] - InIt2[i]) * coeff + InIt2[i];
00272 //       }
00273 
00274     }
00275 #ifdef MYDEBUG
00276     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données calculées à t : " << std::endl;
00277     std::copy(OutIt,OutIt+dataSize,std::ostream_iterator<InnerType>(std::cout," "));
00278     std::cout << std::endl;
00279 #endif
00280     data = dataOut;
00281     
00282   }
00283 };
00284 
00285 // Renvoie isEqual si le dataId attendu est trouvé dans storedDataIds :
00286 //   - l'itérateur wDataIt1 pointe alors sur ce dataId
00287 // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et 
00288 // que la politique de couplage gére ce cas de figure 
00289 //   - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
00290 // Le container doit être associatif
00291 template < typename AssocContainer >
00292 bool CalciumCouplingPolicy::isDataIdConveniant( AssocContainer & storedDatas, const typename AssocContainer::key_type & expectedDataId,
00293                                                 bool & isEqual, bool & isBounded, typename AssocContainer::iterator & wDataIt1) const {
00294  
00295   // Rem : le type key_type == DataId
00296   typedef typename AssocContainer::key_type key_type;
00297   AdjacentFunctor< key_type > af(expectedDataId);
00298   if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY )
00299   {
00300 #ifdef MYDEBUG
00301     std::cout << "-------- time expected : " << expectedDataId.first << std::endl;
00302     std::cout << "-------- time expected corrected : " << expectedDataId.first*(1.0-_deltaT) << std::endl;
00303 #endif
00304     af.setMaxValue(key_type(expectedDataId.first*(1.0-_deltaT),0));
00305   }
00306   isBounded = false;
00307 
00308   // Rem 1 :
00309   // L'algo adjacent_find ne peut être utilisé avec l'AdjacentPredicate 
00310   //   - si la table contient un seul élément l'algorithme adjacent_find retourne end()
00311   //     que se soit l'élément attendu ou non
00312   //   - si la table contient deux éléments dont le dernier est celui recherché
00313   //     l'algorithme adjacent_find retourne end() aussi
00314   //   d'ou la necessité d'effectuer  un find avant ou d'écrire un algorithme ad hoc
00315  
00316   // Rem 2 :
00317   //
00318   // L'algo find_if ne peut être utilisé car il recopie l'AdjacentFunctor
00319   // qui ne peut alors pas mémoriser ses états précédents
00320   //    
00321  
00322   // Un codage en reverse serait plus efficace
00323   typename AssocContainer::iterator prev    = storedDatas.begin();
00324   typename AssocContainer::iterator current = prev;
00325   while ( (current != storedDatas.end()) && !af(current->first)  ) 
00326   {
00327 #ifdef MYDEBUG
00328     std::cerr << "------- stored time : " << current->first << std::endl;
00329 #endif
00330     //  if ( af(current->first) ) break;
00331     prev = current++;
00332   }
00333 
00334   isEqual = af.isEqual();
00335     
00336   // On considère qu'il n'est pas possible d'encadrer en dépendance itérative,
00337   // on se veut pas calculer d'interpolation. 
00338   if  ( _dependencyType == CalciumTypes::TIME_DEPENDENCY)  isBounded = af.isBounded();
00339 
00340   if ( isEqual ) wDataIt1 = current;
00341   else 
00342     if (isBounded) wDataIt1 = prev;
00343     else
00344       wDataIt1 = storedDatas.end();
00345 
00346 #ifdef MYDEBUG
00347   std::cout << "-------- isDataIdConvenient : isEqual : " << isEqual << " , isBounded " << isBounded << std::endl;
00348 #endif
00349 
00350   return isEqual || isBounded;
00351 }
00352 
00353 //Remove DataId before or after a given time or tag
00354 template < typename DataManipulator > 
00355 struct CalciumCouplingPolicy::EraseDataIdBeforeOrAfterTagProcessor
00356 {
00357   CalciumCouplingPolicy &_couplingPolicy;
00358     
00359   EraseDataIdBeforeOrAfterTagProcessor(CalciumCouplingPolicy &couplingPolicy):
00360     _couplingPolicy(couplingPolicy) {};
00361 
00362   template < typename Container,typename TimeType,typename TagType >
00363   void apply(Container & storedDatas, TimeType time, TagType tag, bool before) const 
00364     {
00365       typedef typename Container::iterator   iterator;
00366       typedef typename Container::reverse_iterator   riterator;
00367 
00368       if(_couplingPolicy._dependencyType == CalciumTypes::TIME_DEPENDENCY)
00369         {
00370           if(before)
00371             {
00372               iterator it=storedDatas.begin();
00373               while(it != storedDatas.end() && it->first.first <= time)
00374                 {
00375                   DataManipulator::delete_data(it->second);
00376                   storedDatas.erase(it);
00377                   it=storedDatas.begin();
00378                 }
00379             }
00380           else
00381             {
00382               riterator it=storedDatas.rbegin();
00383               while(it != storedDatas.rend() && it->first.first >= time)
00384                 {
00385                   DataManipulator::delete_data(it->second);
00386                   storedDatas.erase(it->first);
00387                   it=storedDatas.rbegin();
00388                 }
00389             }
00390         }
00391       else
00392         {
00393           if(before)
00394             {
00395               iterator it=storedDatas.begin();
00396               while(it != storedDatas.end() && it->first.second <= tag)
00397                 {
00398                   DataManipulator::delete_data(it->second);
00399                   storedDatas.erase(it);
00400                   it=storedDatas.begin();
00401                 }
00402             }
00403           else
00404             {
00405               riterator it=storedDatas.rbegin();
00406               while(it != storedDatas.rend() && it->first.second >= tag)
00407                 {
00408                   DataManipulator::delete_data(it->second);
00409                   storedDatas.erase(it->first);
00410                   it=storedDatas.rbegin();
00411                 }
00412             }
00413         }
00414     }
00415 };
00416 
00417 // TODO :PAS ENCORE TESTE AVEC UN NIVEAU POSITIONNE
00418 // Supprime les DataId et les données associées
00419 // du container associatif quand le nombre
00420 // de données stockées dépasse le niveau CALCIUM.
00421 // Cette méthode est appelée de GenericPort::get et GenericPort::next 
00422 // TODO : Elle devrait également être appelée dans GenericPort::Put
00423 // mais il faut étudier les interactions avec GenericPort::Get et GenericPort::next
00424 template < typename DataManipulator > 
00425 struct CalciumCouplingPolicy::EraseDataIdProcessor {
00426 
00427   CalciumCouplingPolicy &_couplingPolicy;
00428     
00429   EraseDataIdProcessor(CalciumCouplingPolicy &couplingPolicy):
00430     _couplingPolicy(couplingPolicy) {};
00431 
00432   template < typename Container >
00433   void apply(Container & storedDatas, 
00434              typename Container::iterator & wDataIt1 ) const {
00435 
00436     typedef typename Container::key_type   key_type;
00437     typedef typename Container::value_type value_type;
00438     typedef typename Container::iterator iterator;
00439 
00440 #ifdef MYDEBUG
00441     std::cout << "-------- CalciumCouplingPolicy::eraseDataId, storedDatasSize : " << storedDatas.size() << std::endl;
00442 #endif
00443  
00444     if ( _couplingPolicy._storageLevel == CalciumTypes::UNLIMITED_STORAGE_LEVEL ) return;
00445  
00446     size_t storedDatasSize = storedDatas.size();
00447     long   s = storedDatasSize - _couplingPolicy._storageLevel;
00448     if (s > 0 ) {
00449       size_t dist=distance(storedDatas.begin(),wDataIt1);
00450       for (int i=0; i<s; ++i) {
00451               //no bug if removed : DataManipulator::delete_data((*storedDatas.begin()).second);
00452               DataManipulator::delete_data((*storedDatas.begin()).second);
00453               storedDatas.erase(storedDatas.begin());
00454       }
00455       // Si l'itérateur pointait sur une valeur que l'on vient de supprimer
00456       if (dist < s ) {
00457         throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "StorageLevel management " 
00458                                             << _couplingPolicy._storageLevel << 
00459                                             " has just removed the data to send")));
00460       }
00461     }
00462 #ifdef MYDEBUG
00463     std::cout << "-------- CalciumCouplingPolicy::eraseDataId, new storedDatasSize : " << storedDatas.size() << std::endl;
00464 #endif
00465     return;
00466 
00467   }
00468 };
00469 
00470 
00471 // Lorsque cette méthode est appelée depuis GenericPort::Get 
00472 // l'expectedDataId n'a pas été trouvé et n'est pas non plus 
00473 // encadré (en mode temporel).
00474 // Si apply n'effectue pas de traitement particulier la méthode renvoie false
00475 // Si le port a déjà reçu une directive de deconnexion STOP une exception est levée
00476 // Si le port a déjà reçu une directive de deconnexion CONTINUE, 
00477 // on donne la dernière valeur connu et on renvoie true.
00478 template < typename DataManipulator > 
00479 struct CalciumCouplingPolicy::DisconnectProcessor {
00480 
00481   const CalciumCouplingPolicy  & _couplingPolicy;
00482     
00483   DisconnectProcessor(const CalciumCouplingPolicy & couplingPolicy):
00484     _couplingPolicy(couplingPolicy) {};
00485 
00486   template < typename Container, typename DataId >
00487   bool apply(Container & storedDatas,
00488              const DataId & expectedDataId,
00489              typename Container::iterator & wDataIt1 ) const {
00490 
00491     typedef typename Container::key_type   key_type;
00492     typedef typename Container::value_type value_type;
00493     typedef typename Container::iterator   iterator;
00494 
00495     // Pas de traitement particulier a effectuer
00496 #ifdef MYDEBUG
00497     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK1 ("<< _couplingPolicy._disconnectDirective<<") --------" << std::endl;
00498 #endif
00499     if ( (_couplingPolicy._disconnectDirective) == (CalciumTypes::UNDEFINED_DIRECTIVE) ) return false;
00500   
00501 #ifdef MYDEBUG
00502     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK2 --------" << std::endl;
00503 #endif
00504 
00505     // TODO : Ds GenericPort::next il faut convertir en CPSTOPSEQ
00506     if ( _couplingPolicy._disconnectDirective == CalciumTypes::CP_ARRET )
00507       throw(CalciumException(CalciumTypes::CPINARRET,LOC(OSS()<< "CP_ARRET directive" 
00508                                            << " interrupts all further data reading")));
00509 #ifdef MYDEBUG
00510     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK3 --------" << std::endl;
00511 #endif
00512 
00513 
00514     // S'il n'y a plus de données indique que l'on a pas pu effectuer de traitement
00515     // TODO : Dans la gestion des niveaux il faut peut être interdire un niveau ==  0
00516     if ( storedDatas.empty() ) 
00517       throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive" 
00518                                           << " is active but no data is available.")));
00519     
00520     // expectedDataId n'a ni été trouvé dans storedDataIds ni encadré mais il se peut
00521     // qu'en mode itératif il ne soit pas plus grand que le plus grand DataId stocké auquel
00522     // cas on doit renvoyer une expection car on n'est plus connecté et on ne pourra jamais
00523     // fournir de données pour ce dataId.
00524 #ifdef MYDEBUG
00525     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK4  " << expectedDataId <<" --------" << std::endl;
00526 #endif
00527 
00528     // >= expectedDataId
00529     iterator it1 = storedDatas.lower_bound(expectedDataId);
00530 #ifdef MYDEBUG
00531     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK5  " << std::endl;
00532     for (iterator it=storedDatas.begin();it!=storedDatas.end();++it)
00533       std::cout <<" "<<(*it).first ;
00534     std::cout <<std::endl;
00535 #endif
00536 
00537     // TODO : Il faut en fait renvoyer le plus proche cf IT ou DT
00538     if (it1 == storedDatas.end())
00539       throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive" 
00540                                           << " is active but the requested dataId is less or equal to the last one received.")));
00541   
00542 #ifdef MYDEBUG
00543     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK6 " << std::endl;
00544 #endif
00545 
00546     wDataIt1 = storedDatas.end();
00547     --wDataIt1;
00548 #ifdef MYDEBUG
00549     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor, CP_CONT : " << (*wDataIt1).first << std::endl;
00550 #endif
00551 
00552     return true;
00553   }
00554 };
00555 
00556 #endif