From: secher Date: Thu, 22 May 2008 09:22:08 +0000 (+0000) Subject: merging with V4_1_0_maintainenance X-Git-Tag: afterMerge_V4_1_3rc1~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3404b27031929072c16872420447ddebf2cf5a33;p=modules%2Fkernel.git merging with V4_1_0_maintainenance --- diff --git a/bin/setenv.py b/bin/setenv.py index 7e1b93d80..86a4803ba 100755 --- a/bin/setenv.py +++ b/bin/setenv.py @@ -70,13 +70,7 @@ def get_lib_dir(): global __lib__dir__ if __lib__dir__: return __lib__dir__ import platform - if platform.architecture()[0] == "64bit": - if platform.machine() == "ia64": - __lib__dir__ = "lib" - else: - __lib__dir__ = "lib64" - else: - __lib__dir__ = "lib" + __lib__dir__ = "lib" return __lib__dir__ # ----------------------------------------------------------------------------- diff --git a/bin/virtual_salome.py b/bin/virtual_salome.py index 4efd5979f..401b9ccab 100644 --- a/bin/virtual_salome.py +++ b/bin/virtual_salome.py @@ -80,13 +80,7 @@ def get_lib_dir(): global __lib__dir__ if __lib__dir__: return __lib__dir__ import platform - if platform.architecture()[0] == "64bit": - if platform.machine() == "ia64": - __lib__dir__ = "lib" - else: - __lib__dir__ = "lib64" - else: - __lib__dir__ = "lib" + __lib__dir__ = "lib" return __lib__dir__ # ----------------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 4d28fad9f..e487aa532 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ # ================================================================ # #AC_PREREQ(2.59) -AC_INIT([Salome2 Project], [4.1.1], [paul.rascle@edf.fr], [SalomeKer]) +AC_INIT([Salome2 Project], [4.1.2], [paul.rascle@edf.fr], [SalomeKer]) # AC_CONFIG_AUX_DIR defines an alternative directory where to find the auxiliary # scripts such as config.guess, install-sh, ... @@ -14,7 +14,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([tar-pax]) #AC_CONFIG_HEADER([config.h]) -XVERSION=0x040101 +XVERSION=0x040102 AC_SUBST(XVERSION) # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.) diff --git a/doc/salome/salome_application.dox b/doc/salome/salome_application.dox index 0060c7794..d970338a3 100644 --- a/doc/salome/salome_application.dox +++ b/doc/salome/salome_application.dox @@ -42,14 +42,15 @@ computer. \section S2_sal_appl Application Directory -There is two ways for creation of an application directory +There are two ways for creation of an application directory, the recommended way is +the second, easier to configure.
  1. First way - references to different module directories -The script createAppli.sh in ${KERNEL_ROOT_DIR}/bin/SALOME creates an -application directory with the given path in parameter. ${APPLI} is a path +The script createAppli.sh in ${KERNEL_ROOT_DIR}/bin/salome creates an +application directory with the given path in parameter. The path given, ${APPLI}, is relative to ${HOME}. The directory is only a skeleton, the user has to edit several files to @@ -66,7 +67,7 @@ configure his own application. These files are described after, the list is: Second and easiest way - one single virtual install directory The user must create a %SALOME application configuration file by modifying a -copy of ${KERNEL_ROOT_DIR}/bin/SALOME/config_appli.xml. +copy of ${KERNEL_ROOT_DIR}/bin/salome/config_appli.xml. The file describes the list of %SALOME modules used in the application, with their respective installation path. The configuration file also defines the path of an existing script which sets the %SALOME prerequisites, @@ -74,19 +75,22 @@ and optionnaly, the path of samples directory (SAMPLES_SRC). The following command:: \code -python /bin/SALOME/appli_gen.py --prefix= --config= +python /bin/salome/appli_gen.py --prefix= --config= \endcode creates a virtual installation of %SALOME in the application directory ${APPLI} (bin, lib, doc, share...), with, for each file (executable, script, data, library, resources...), symbolic links to the actual file. +Note: it is recommended to set the environment for %SALOME prerequisites +before invoking the above command, in order to use the same python as SALOME, +otherwise installation may be wrong -Providing an existing an existing script for %SALOME prerequisites (the same one +Providing an existing script for %SALOME prerequisites (the same one used for modules compilation, or given with the modules installation), the installation works without further modification for a single computer (unless some modules needs a special environment not defined in the above script). For a distributed application (several computers), one must copy and adapt -CatalogResources.xml from ${KERNEL_ROOT_DIR}/bin/SALOME/appliskel (see below). +CatalogResources.xml from ${KERNEL_ROOT_DIR}/bin/salome/appliskel (see below).
@@ -112,8 +116,8 @@ script is used by run scripts. With the first way of installation, each user **must define** his own configuration for these scripts, following the above rules. -With the virtual installation (second way, above), env.d -scripts are built automatically. +With the virtual installation (second way, above), env.d +scripts are built automatically. **The following is only an example proposed by createAppli.sh, (first way of installation) not working as it is**. @@ -144,8 +148,8 @@ The %SALOME user can use 4 scripts: - runAppli Launches a %SALOME Session - (similar to ${KERNEL_ROOT_DIR}/bin/SALOME/runSALOME but with a different - name to avoid confusions). + (similar to ${KERNEL_ROOT_DIR}/bin/salome/runSalome but with a different + name to avoid confusions). See parameters below. - runSession Launches a shell script in the %SALOME application environment, with access @@ -158,9 +162,9 @@ The %SALOME user can use 4 scripts: It is also possible to use runSession, then python. - runTests - Similar to runSession, used for unit testing. runSession tries to use an + Similar to runSession, used for unit testing, but runSession tries to use an already existing naming service definition from a running session (hostname - and port number), runTests defines a new configuration for naming service + and port number), and runTests defines a new configuration for naming service (new port number).
  • @@ -172,8 +176,8 @@ The %SALOME user can use 4 scripts: For remote calls, %SALOME uses one script. - runRemote.sh - This script is mainly used to launch containers. The first 2 arguments - define the hostname and port userd for naming service, the remaining + This script is mainly used to launch containers. The first 3 arguments + define the hostname and port userd for naming service, plus a working directory, the remaining arguments define the command to execute.
  • @@ -249,10 +253,10 @@ If you have no active Python interpreter connected to your session, you can kill all the %SALOME servers of **all the sessions** on a given computer:: \code -./runSession killSALOME.py +./runSession killSalome.py \endcode -Remember! it's the same idea in *Windows (R) operating system* (Microsoft and Windows are either registered trademarks or trademarks of +Remember! it's the same idea in Windows (R) operating system (Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries) : use the start menu to stop... @@ -262,7 +266,7 @@ To kill a given session (when several session are running), one needs the naming service port number:: \code -./runSession killSALOMEWithPort 2810 +./runSession killSalomeWithPort 2810 \endcode Note that the port number of the last launched session can be found on Linux, @@ -285,8 +289,8 @@ This is used to launch a %SALOME Python script without GUI Example of script (test_session_geom.py): \code -import SALOME_session -SALOME_session.startSession(modules=["GEOM"]) +import salome_session +salome_session.startSession(modules=["GEOM"]) import GEOM_usinggeom raw_input("Press a key and the servers will be killed ...") \endcode @@ -313,13 +317,13 @@ first, launch a %SALOME session with gui, then, on another terminal:: python \endcode -Import %SALOME module. SALOME_init() without arguments creates a new study +Import %SALOME module. salome_init() without arguments creates a new study in the running session (note: SALOME_init(n) attachs to a running session whose studyId is n):: \code -import SALOME -SALOME.SALOME_init() +import salome +salome.salome_init() \endcode An example of script given with SMESH:: diff --git a/idl/SALOME_Session.idl b/idl/SALOME_Session.idl index 041df52a7..9ca58aa22 100644 --- a/idl/SALOME_Session.idl +++ b/idl/SALOME_Session.idl @@ -113,5 +113,22 @@ module SALOME Restores a state of the study at theSavePoint */ boolean restoreVisualState(in long theSavePoint); +/*! + Emit a qt signal from the session GUI desktop window. + This method can be used to send a message to the GUI from the standalone + container. + Caution: this method can block the Session and the calling container + if it is called when container processes some request from the GUI + (mutual lock takes place). + In such a case it is recommended to use oneway method. +*/ + void emitMessage(in string theMessage); +/*! + Emit a qt signal from the session GUI desktop window. + This method can be used to send a message to the GUI from the standalone + container. + This method never blocks the Session and the calling container. +*/ + oneway void emitMessageOneWay(in string theMessage); } ; } ; diff --git a/salome_adm/unix/config_files/ac_linker_options.m4 b/salome_adm/unix/config_files/ac_linker_options.m4 index 9006a46fe..ec3fe668d 100644 --- a/salome_adm/unix/config_files/ac_linker_options.m4 +++ b/salome_adm/unix/config_files/ac_linker_options.m4 @@ -29,10 +29,6 @@ AC_DEFUN([AC_LINKER_OPTIONS],[ AC_CHECKING(for LIB_LOCATION_SUFFIX) LIB_LOCATION_SUFFIX="" - case "$build_cpu" in - x86_64*) LIB_LOCATION_SUFFIX="64" ;; - *) LIB_LOCATION_SUFFIX="" ;; - esac AC_SUBST(LIB_LOCATION_SUFFIX) AC_MSG_RESULT(LIB_LOCATION_SUFFIX is $LIB_LOCATION_SUFFIX) diff --git a/salome_adm/unix/config_files/check_withihm.m4 b/salome_adm/unix/config_files/check_withihm.m4 index e4b412c0d..3e3aba71f 100644 --- a/salome_adm/unix/config_files/check_withihm.m4 +++ b/salome_adm/unix/config_files/check_withihm.m4 @@ -22,47 +22,38 @@ dnl AC_DEFUN([CHECK_WITHIHM],[ +AC_ARG_WITH(gui, + [ --with-gui build package with GUI support [[default=yes]]]) AC_ARG_WITH(ihm, - --with-ihm [default=yes], - WITHIHM="yes",WITHIHM="no") - -if test "${with_ihm}" = yes; then - - echo - echo --------------------------------------------- - echo testing WITH_IHM : yes - echo --------------------------------------------- - echo - WITHIHM="yes" - if test "${with_ihm}" = "yes";then - withihm_ok=yes - fi - -elif test "${with_ihm}" = no; then - - echo - echo --------------------------------------------- - echo testing WITH_IHM : no - echo --------------------------------------------- - echo - WITHIHM="no" - if test "${with_ihm}" = "no";then - withihm_ok=no - fi - + [ --with-ihm obsolete, use --with-gui instead]) + +if test "${with_gui}" == "yes" || test "${with_gui}" == "no" ; then + WITHGUI="${with_gui}" + WITHIHM=$WITHGUI +elif test "x${with_gui}" != "x" ; then + AC_MSG_FAILURE(wrong value for --with-gui or --without-gui option) +elif test "${with_ihm}" == "yes" || test "${with_ihm}" == "no" ; then + WITHIHM="${with_ihm}" + WITHGUI=$WITHIHM +elif test "x${with_ihm}" != "x" ; then + AC_MSG_FAILURE(wrong value for --with-ihm or --without-ihm option) else + WITHIHM="yes" + WITHGUI="yes" +fi - echo - echo --------------------------------------------- - echo testing WITH_IHM : yes - echo --------------------------------------------- - echo - WITHIHM="yes" - if test "${with_ihm}" = "yes";then - withihm_ok=yes - fi +echo +echo --------------------------------------------- +echo testing if GUI support is enabled : ${WITHGUI} +echo --------------------------------------------- +echo + +withihm_ok=$WITHGUI +withgui_ok=$WITHGUI -fi AC_SUBST(WITHIHM) +AC_SUBST(WITHGUI) ])dnl + +AC_DEFUN([CHECK_WITHGUI],[CHECK_WITHIHM]) diff --git a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c index cba14ca11..e7c051448 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c +++ b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c @@ -34,7 +34,9 @@ typedef int InfoType; typedef char bool; -/* INTERFACES DE LECTURE en 0 copie */ +/************************************/ +/* INTERFACES DE LECTURE EN 0 COPIE */ +/************************************/ /* Definition des méthodes calcium étendues en 0 copie */ /* Le buffer est alloué par le port pas par l'utilisateur */ @@ -50,8 +52,11 @@ typedef char bool; int * nRead, _type _qual ** data ) { \ size_t _nRead; \ long _i=*i; \ + fflush(stdout); \ + fflush(stderr); \ + fprintf(stderr,"Beginning of ecp_" #_name " : %s %d %f\n",nomvar,*i,*ti); \ + \ \ - /* std::cerr << "-------- CalciumInterface(C Part) MARK 1 ------------------" << std::endl; */ \ InfoType info = ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \ nomvar, bufferLength, &_nRead, \ data ); \ @@ -70,20 +75,54 @@ typedef char bool; return info; \ }; \ void ecp_##_name##_free ( _type _qual * data) { \ - ecp_lecture_##_typeName##_free(data); \ + ecp_lecture_##_typeName##_free(data); \ }; #define STAR * CALCIUM_EXT_LECT_INTERFACE_C_(len,float,int,int,); CALCIUM_EXT_LECT_INTERFACE_C_(lre,float,float,float,); CALCIUM_EXT_LECT_INTERFACE_C_(ldb,double,double,double,); -/* CALCIUM_EXT_LECT_INTERFACE_C_(llo,float,bool,bool,); */ +CALCIUM_EXT_LECT_INTERFACE_C_(llo,float,int,bool,); CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); /* CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]); */ +/* L'interface de cette routine diffère de celle obtenue par la macro : + CALCIUM_LECT_INTERFACE_C_. + Le paramètre supplémentaire strSize indique la taille fixe et identique + des chaînes stockées dans data (les ports CALCIUM n'en n'ont pas besoin) +*/ +InfoType ecp_lch(void * component, int mode, float * ti, float * tf, int * i, + char * nomvar, int bufferLength, int * nRead, + char *** data, int strSize) { + + size_t _nRead; + long _i=*i; + fflush(stdout);fflush(stderr); + fprintf(stderr,"Beginning of cp_lch: %s %d %f\n",nomvar,*i,*ti); + + + InfoType info = ecp_lecture_str (component, mode, ti, tf, &_i, + nomvar, bufferLength, &_nRead, + data);/*, strSize ); + strSize est inutile pour les ports CALCIUM + qui gèrent des tailles quelconques de chaines. */ + if(mode == CP_SEQUENTIEL) + *i = _i; + *nRead=_nRead; + fprintf(stderr,"End of cp_lch: %s %d \n",nomvar,*i); + fflush(stdout);fflush(stderr); + + return info; +}; + +void ecp_lch_free (char* * data) { \ + ecp_lecture_str_free(data); \ +}; -/* INTERFACES DE LECTURE avec recopie */ +/**************************************/ +/* INTERFACES DE LECTURE AVEC RECOPIE */ +/**************************************/ #define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \ InfoType cp_##_name (void * component, int mode, \ @@ -99,12 +138,12 @@ CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; \ \ InfoType info = ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \ - nomvar, bufferLength, &_nRead, \ + nomvar, bufferLength, &_nRead, \ &data ); \ if(mode == CP_SEQUENTIEL) \ *i = _i; \ *nRead=_nRead; \ - fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,*i); \ + fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,*i); \ fflush(stdout); \ fflush(stderr); \ \ @@ -115,7 +154,11 @@ CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); }; - +/* L'interface de cette routine diffère de celle obtenue par la macro : + CALCIUM_LECT_INTERFACE_C_. + Le paramètre supplémentaire strSize indique la taille fixe et identique + des chaînes stockées dans data (les ports CALCIUM n'en n'ont pas besoin) +*/ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, char * nomvar, int bufferLength, int * nRead, char ** data, int strSize) { @@ -129,7 +172,9 @@ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, InfoType info = ecp_lecture_str (component, mode, ti, tf, &_i, nomvar, bufferLength, &_nRead, - &data);/*, strSize );*/ + &data);/*, strSize ); + strSize est inutile pour les ports CALCIUM + qui gèrent des tailles quelconques de chaines. */ if(mode == CP_SEQUENTIEL) *i = _i; *nRead=_nRead; @@ -139,50 +184,22 @@ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, return info; }; -InfoType cp_llo(void * component, int mode, float * ti, float * tf, int * i, - char * nomvar, int bufferLength, int * nRead, - int * data ) { - - bool *dLogique=NULL; - size_t _nRead; - long _i=*i; - int j; - fflush(stdout);fflush(stderr); - fprintf(stderr,"Beginning of cpllo: %s %d %f\n",nomvar,*i,*ti); - - if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; - - dLogique = (bool *) malloc(bufferLength * sizeof(int)); - - InfoType info = ecp_lecture_bool (component, mode, ti, tf, &_i, - nomvar, bufferLength, &_nRead, - &dLogique); - if(mode == CP_SEQUENTIEL) - *i = _i; - *nRead=_nRead; - - for ( j=0; j<_nRead; ++j) data[j] = dLogique[j]; - free(dLogique); - - fprintf(stderr,"End of cpllo: %s %d \n",nomvar,*i); - fflush(stdout);fflush(stderr); - - return info; -}; - /* Definition des méthodes calcium standard */ CALCIUM_LECT_INTERFACE_C_(len,float,int,int,); CALCIUM_LECT_INTERFACE_C_(lre,float,float,float,); CALCIUM_LECT_INTERFACE_C_(ldb,double,double,double,); -/* CALCIUM_LECT_INTERFACE_C_(llo,float,bool,bool,); */ +CALCIUM_LECT_INTERFACE_C_(llo,float,int,bool,); CALCIUM_LECT_INTERFACE_C_(lcp,float,float,cplx,); #define STAR * /* CALCIUM_LECT_INTERFACE_C_(lch,float,char,STAR); */ + +/**********************************************/ /* INTERFACES DE DÉBUT ET DE FIN DE COUPLAGE */ +/**********************************************/ InfoType cp_cd (void * component, char * instanceName) { /* TODO : Trouver le nom de l'instance SALOME*/ @@ -198,7 +215,10 @@ InfoType cp_fin (void * component, int code) { } + +/***************************/ /* INTERFACES D'ECRITURE */ +/***************************/ #define CALCIUM_ECR_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \ InfoType cp_##_name (void * component, int mode, \ @@ -223,6 +243,15 @@ InfoType cp_fin (void * component, int code) { }; \ +/* Definition des méthodes calcium standard */ + +CALCIUM_ECR_INTERFACE_C_(een,float,int,int,); +CALCIUM_ECR_INTERFACE_C_(ere,float,float,float,); +CALCIUM_ECR_INTERFACE_C_(edb,double,double,double,); +/*CALCIUM_ECR_INTERFACE_C_(elo,float,bool,bool,);*/ +CALCIUM_ECR_INTERFACE_C_(elo,float,int,bool,); +CALCIUM_ECR_INTERFACE_C_(ecp,float,float,cplx,); + InfoType cp_ech(void * component, int mode, float t, int i, char * nomvar, int nbelem, @@ -243,38 +272,4 @@ InfoType cp_ech(void * component, int mode, float t, int i, return info; }; -InfoType cp_elo(void * component, int mode, float t, int i, - char * nomvar, int nbelem, - int * data ) { - - /*long _i=i;*/ - bool * dLogique = NULL; - int j=0; - fflush(stdout);fflush(stderr); - fprintf(stderr,"Beginning of cpelo: %s %d %f\n",nomvar,i,t); - if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL; - - dLogique = (bool *) malloc(nbelem * sizeof(int)); - for (j=0; j::const_iterator it; component.get_uses_port_names(usesPortNames); - //récupérer le type de réel du port est un peu difficile - //car l'interface nous donne aucune indication + //Récupérer le type de réel du port est un peu difficile + //car l'interface ne donne aucune indication // uses_port *myUsesPort; calcium_uses_port* myCalciumUsesPort; @@ -127,10 +127,10 @@ namespace CalciumInterface { { typedef typename ProvidesPortTraits::PortType PortType; typedef typename PortType::DataManipulator DataManipulator; - typedef typename DataManipulator::Type DataType; // Attention != T + typedef typename DataManipulator::Type DataType; // Attention != T1 typedef typename DataManipulator::InnerType InnerType; - DeleteTraits::value >::apply(dataPtr); + DeleteTraits::value, DataManipulator >::apply(dataPtr); } template static void @@ -160,7 +160,7 @@ namespace CalciumInterface { } // T1 est le type de données - // T2 est un de type Calcium permettant de sélectionner le port correspondant + // T2 est un de type Calcium permettant de sélectionner le port CORBA correspondant // T1 et T2 sont dissociés pour discriminer le cas des nombres complexes // -> Les données des nombres complexes sont de type float mais // le port à utiliser est le port cplx @@ -269,30 +269,41 @@ namespace CalciumInterface { MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)"); } nRead = corbaDataSize; - // Si les types T et InnerType sont différents, il faudra effectuer tout de même une recopie + // Si les types T1 et InnerType sont différents, il faudra effectuer tout de même une recopie if (!IsSameType::value) data = new T1[nRead]; #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl; #endif - // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes - Copy2UserSpace< IsSameType::value >::apply(data,corbaData,nRead); + // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes. + // Copy2UserSpace : + // La raison d'être du foncteur Copy2UserSpace est que le compilateur n'acceptera + // pas une expresion d'affectation sur des types incompatibles même + // si cette expression se trouve dans une branche non exécuté d'un test + // sur la compatibilité des types. + // En utilisant le foncteur Copy2UserSpace, seul la spécialisation en adéquation + // avec la compatibilité des types sera compilée + Copy2UserSpace< IsSameType::value, DataManipulator >::apply(data,corbaData,nRead); #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl; #endif // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante : - // DataManipulator::delete_data(corbaData); + // DataManipulator::delete_data(corbaData); + // ni DataManipulator::getPointer(corbaData,true); qui détruit la sequence lorsque l'on + // prend la propriété du buffer // old : Dans les deux cas la structure CORBA n'est plus utile // old : Si !IsSameType::value l'objet CORBA est détruit avec son contenu // old : Dans l'autre cas seul la coquille CORBA est détruite - // L'utilisateur devra appeler ecp_free (version modifiée) qui déterminera s'il est necessaire - // de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété + // L'utilisateur devra appeler ecp_free qui déterminera s'il est necessaire + // de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété } else { nRead = std::min < size_t > (corbaDataSize,bufferLength); #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl; #endif - Copy2UserSpace::apply(data,corbaData,nRead); + Copy2UserSpace::apply(data,corbaData,nRead); + DataManipulator::copy(corbaData,data,nRead); + #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl; #endif @@ -445,7 +456,7 @@ namespace CalciumInterface { // OLD : Il faut effectuer une copie dans le port provides. // OLD : Cette copie est effectuée dans GenericPortUses::put // OLD : en fonction de la collocalisation ou non. - Copy2CorbaSpace::value >::apply(corbaData,data,bufferLength); + Copy2CorbaSpace::value, DataManipulator >::apply(corbaData,data,bufferLength); //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) { diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx index b419e3869..6f8fd6d97 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx @@ -27,6 +27,8 @@ #ifndef _CALCIUM_GENERIC_PROVIDES_PORT_HXX_ #define _CALCIUM_GENERIC_PROVIDES_PORT_HXX_ +#include + #include "PortProperties_i.hxx" #include "calcium_provides_port.hxx" @@ -55,17 +57,23 @@ class specificPortName : public virtual CorbaInterface , \ public virtual POA_Ports::PortProperties, \ public GenericProvidesPort< __VA_ARGS__ , CalciumCouplingPolicy, calcium_provides_port > { \ + private : \ + omni_semaphore _mustnotdisconnectyet; \ public : \ typedef __VA_ARGS__ DataManipulator; \ typedef DataManipulator::Type CorbaDataType; \ typedef GenericPort< DataManipulator , \ CalciumCouplingPolicy > Port; \ \ + specificPortName () :_mustnotdisconnectyet(0) {}; \ + \ virtual ~ specificPortName (); \ \ inline void disconnect(bool provideLastGivenValue) { \ - Port::disconnect(provideLastGivenValue); \ - } \ + if (! _mustnotdisconnectyet.trywait() ) { \ + Port::disconnect(provideLastGivenValue); \ + } \ + } \ inline void setDependencyType(CalciumTypes::DependencyType dependencyType) { \ Port::setDependencyType(dependencyType); \ } \ @@ -128,15 +136,14 @@ virtual CORBA::Any* get_property(const char* name) \ throw (Ports::NotDefined); \ \ - virtual void provides_port_changed(int connection_nbr, \ - const Engines::DSC::Message message) { \ - if ( !connection_nbr && (message == Engines::DSC::RemovingConnection) ) \ - { \ - disconnect(false); \ - } \ - } \ - }; \ - + virtual void provides_port_changed(int connection_nbr, \ + const Engines::DSC::Message message) { \ + if ( message == Engines::DSC::AddingConnection) \ + _mustnotdisconnectyet.post(); \ + else if ( message == Engines::DSC::RemovingConnection ) \ + disconnect(false); \ + } \ + }; \ diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx index 62994aa97..4d0ac6aac 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx @@ -47,6 +47,9 @@ // Interface C/C++ +// L'utilisateur CALCIUM n'a normalement pas a utliser cette interface +// En C/C++ il utilisera celle définie dans Calcium.c +// En C++/CORBA directement celle de CalciumCxxInterface // En CALCIUM l'utilisation de données de type double // implique des dates de type double, pour les autres @@ -159,24 +162,29 @@ ecp_fin_ (void * component, int code) { #define STAR * // Le premier argument est utilisée : -// - comme suffixe dans la définition des noms ecp_lecture_ ecp_ecriture_ ecp_free_ +// - comme suffixe dans la définition des noms ecp_lecture_ , ecp_ecriture_ et ecp_free_ // - comme second argument template à l'appel de la méthode C++ correspondante -// ( le port correspondant est alors obtenu par un trait) +// ( le type de port correspondant est alors obtenu par un trait) // Le second argument est utilisée : // - pour typer le paramètre data de la procédure générée // - pour déduire le type des paramètres t, ti tf via un trait // - comme premier paramètre template à l'appel de la méthode C++ correspondante +// (pour typer les données passées en paramètre ) +// Notons que dans le cas CALCIUM_C2CPP_INTERFACE_(int,int,), le type int n'existe pas +// en CORBA, le port CALCIUM correspondant utilise une séquence de long. La méthode +// C++ CALCIUM de lecture repère cette différence de type et charge +// le manipulateur de données d'effectuer une recopie (qui fonctionne si les types sont compatibles). CALCIUM_C2CPP_INTERFACE_(int,int,); CALCIUM_C2CPP_INTERFACE_(float,float, ); CALCIUM_C2CPP_INTERFACE_(double,double,); -CALCIUM_C2CPP_INTERFACE_(bool,bool,); +// Fonctionne mais essai suivant pour simplification de Calcium.c CALCIUM_C2CPP_INTERFACE_(bool,bool,); +CALCIUM_C2CPP_INTERFACE_(bool,int,); CALCIUM_C2CPP_INTERFACE_(cplx,float,); CALCIUM_C2CPP_INTERFACE_(str,char*,); // INTERFACE C/CPP pour les chaines de caractères // Le paramètre supplémentaire strsize n'étant pas utilisé // j'utilise la génération par la macro CALCIUM_C2CPP_INTERFACE_(str,char*,); -// TODO : vérifier ecp_free pour ce type particulier // extern "C" CalciumTypes::InfoType ecp_lecture_str (void * component, int dependencyType, // float * ti, float * tf, long * i, // const char * const nomvar, size_t bufferLength, diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx index d05cc440d..ededf2609 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx @@ -57,15 +57,13 @@ struct cplx {}; template <> struct ProvidesPortTraits { typedef calcium_complex_port_provides PortType; }; -// Défénition du type str pour obtenir le type de port +// Définition du type str pour obtenir le type de port // correspondant struct str {}; template <> struct ProvidesPortTraits { typedef calcium_string_port_provides PortType; }; - template <> struct ProvidesPortTraits { - typedef calcium_string_port_provides PortType; - }; + template < typename T > struct StarTrait { typedef T NonStarType; }; template < typename T > struct StarTrait< T * > { typedef T NonStarType; }; diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx index 21f338497..a7210e851 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx @@ -33,7 +33,7 @@ #include #include "CalciumPortTraits.hxx" -template +template struct Copy2CorbaSpace { template @@ -41,7 +41,7 @@ struct Copy2CorbaSpace { typedef typename ProvidesPortTraits::PortType PortType; //typedef typename UsesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; +//ESSAI: typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; #ifdef _DEBUG_ @@ -58,15 +58,15 @@ struct Copy2CorbaSpace { }; // Cas ou il faut effectuer une recopie -template <> struct -Copy2CorbaSpace { +template struct +Copy2CorbaSpace { template static void apply( T1 * & corbaData, T2 & data, size_t nRead){ typedef typename ProvidesPortTraits::PortType PortType; // typedef typename UsesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; +//ESSAI: typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; corbaData = DataManipulator::create(nRead); diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx index be959838e..eab7a2a5d 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx @@ -38,37 +38,48 @@ //Les demandes de copies vers l'espace utilisateur //proviennent d'une procédure de lecture + //Cas du zero copie -template +template struct Copy2UserSpace{ template static void apply( T1 * & data, T2 & corbaData, size_t nRead ){ - // La ligne suivante appelle à un commentaire - // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str' - typedef typename ProvidesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; - typedef typename DataManipulator::InnerType InnerType; - - // Devient propriétaire des données contenues dans la structure CORBA - // (allouées par allocbuff() pour une séquence) - // Le client est propriétaire des données. - // Il doit cependant être attentif au fait que s'il les modifie, - // une nouvelle demande de lecture lui fournira les données modifiées. - // TODO : ? Si plusieurs lecteurs demandent la même donnée ? - // ? qui devient le propriétaire? --> normalement le premier car - // ensuite la séquence n'est plus propriétaire. - // NO: Le port devrait resté propriétaire du contenu de la séquence - // NO: L'utilisateur doit de toute les façons utiliser les données reçues en - // NO: lecture seulement car si une nouvelle demande de lecture est formulée - // NO: pour ces données, les eventuelles modifications seraient visibles ! - // YES : La solution de donner la propriété à l'utilisateur est convenable car si - // le port déréférence ces données (garbage collecteur, niveau) le buffer - // reste disponible à l'ulisateur en lecture et écriture - // Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK) - // du coup quid d'une nouvelle demande de lecture : A TESTER - InnerType * dataPtr = DataManipulator::getPointer(corbaData,true); + typedef typename DataManipulator::InnerType InnerType; + + // OLD:Devient propriétaire des données contenues dans la structure CORBA + // OLD:(allouées par allocbuff() pour une séquence) + // OLD:Le client est propriétaire des données. + // OLD:Il doit cependant être attentif au fait que s'il les modifie, + // OLD:une nouvelle demande de lecture lui fournira les données modifiées. + // OLD:TODO : Si plusieurs lecteurs demandent la même donnée, + // OLD: ? qui devient le propriétaire? --> Forcément le premier car + // OLD: ensuite la séquence n'est plus propriétaire et rendra un pointeur NULL. + // OLD: NO: Le port devrait resté propriétaire du contenu de la séquence + // OLD: NO: L'utilisateur doit de toute les façons utiliser les données reçues en + // OLD: NO: lecture seulement car si une nouvelle demande de lecture est formulée + // OLD: NO: pour ces données, les eventuelles modifications seraient visibles ! + // OLD:YES : La solution de donner la propriété à l'utilisateur est convenable car si + // OLD:le port déréférence ces données (garbage collecteur, niveau) le buffer + // OLD:reste disponible à l'ulisateur en lecture et écriture + // OLD:Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK) + // OLD:du coup quid d'une nouvelle demande de lecture : A TESTER + + // Le PORT doit être capable de répondre aux demandes de lecture + // multiples d'une donnée pour une même estampille et doit donc garder un pointeur valide + // sur le buffer. Il se pose cependant un problème s'il décide + // de supprimer la donnée alors que des client utilise le buffer (historique) ! + // La seule façon de gérer proprement cette situation est d'utiliser un shared_pointer (TODO). + // Pour l'instant l'utilisateur du mode zero copie doit s'assurer que le niveau d'historique + // utilisé par le port est compatible avec son utilisation des buffers. Il doit + // être également conscient que s'il modifie le buffer, il est modifier pour tous les + // utilisateurs actuels et futurs. + + //REF: InnerType * dataPtr = DataManipulator::getPointer(corbaData,true); + // Laisse la propriété des données à la structure CORBA + // (buffer allouée par allocbuff() pour une séquence) + InnerType * dataPtr = DataManipulator::getPointer(corbaData,false); // Cette ligne poserait uun problème dans la méthode appelante, si elle // ne testait pas que les types utilisateurs et CORBA sont identiques : @@ -85,60 +96,57 @@ struct Copy2UserSpace{ }; // Cas où il faut effectuer une recopie -template <> -struct Copy2UserSpace { +template +struct Copy2UserSpace { //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead template static void apply( T1 * &data, T2 & corbaData, size_t nRead){ - // La ligne suivante appelle à un commentaire - // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str' - typedef typename ProvidesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; #ifdef _DEBUG_ InnerType * dataPtr = NULL; - // Affiche la valeur du pointeur de la structure corba - // et les pointeurs contenus le cas échéant - dataPtr = DataManipulator::getPointer(corbaData,false); - std::cerr << "-------- Copy2UserSpace MARK 1a --dataPtr("<(std::cerr," ")); - for (int i=0; i< DataManipulator::size(corbaData); ++i) - fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]); - std::cerr << std::endl; - - T1 * tmpData = data; - std::cerr << "-------- Copy2UserSpace MARK 1b --data("<(std::cerr," ")); - for (int i=0; i< DataManipulator::size(corbaData); ++i) - fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); - std::cerr << std::endl; + // Affiche la valeur du pointeur de la structure corba + // et les pointeurs contenus le cas échéant + dataPtr = DataManipulator::getPointer(corbaData,false); + std::cerr << "-------- Copy2UserSpace MARK 1a --dataPtr("<(std::cerr," ")); + for (int i=0; i< DataManipulator::size(corbaData); ++i) + fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]); + std::cerr << std::endl; + + T1 * tmpData = data; + //Cette affichage peut provoquer la détection d'écriture d'un espace non initailisé. + std::cerr << "-------- Copy2UserSpace MARK 1b --data("<(std::cerr," ")); + for (int i=0; i< DataManipulator::size(corbaData); ++i) + fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); + std::cerr << std::endl; #endif - // Pour les types pointeurs et ref il faut effectuer une recopie profonde. - // On la délègue au manipulateur de données. + // Pour les types pointeurs et ref il faut effectuer une recopie profonde. + // On la délègue au manipulateur de données. - // Recopie des données dans le buffer allouée par l'utilisateur - // OU - // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture) - // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles. + // Recopie des données dans le buffer allouée par l'utilisateur + // OU + // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture) + // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles. - //std::copy(dataPtr,dataPtr+nRead,data); - DataManipulator::copy(corbaData,data,nRead); + //std::copy(dataPtr,dataPtr+nRead,data); + DataManipulator::copy(corbaData,data,nRead); #ifdef _DEBUG_ - tmpData = data; - std::cerr << "-------- Copy2UserSpace MARK 1c --data("<(std::cerr," ")); - for (int i=0; i< DataManipulator::size(corbaData); ++i) - fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); - std::cerr << std::endl; + tmpData = data; + std::cerr << "-------- Copy2UserSpace MARK 1c --data("<(std::cerr," ")); + for (int i=0; i< DataManipulator::size(corbaData); ++i) + fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); + std::cerr << std::endl; #endif } @@ -147,31 +155,24 @@ struct Copy2UserSpace { // Désallocation des buffers si necessaire -template +template struct DeleteTraits { template static void apply(T * dataPtr) { - typedef typename ProvidesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; - //typedef typename DataManipulator::Type DataType; // Attention != T + typedef typename DataManipulator::Type DataType; // Attention != T // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non // la donnée corba associée à un DataId ! // Ne pas effectuer la desallocation suivante : // DataManipulator::relPointer(dataPtr); - // TODO : Il convient cependant de rendre la propriété du buffer à la séquence CORBA - // TODO : PB : On n'a plus de référence sur la séquence. - // TODO : Modifier l'API ecp_free pour indiquer le dataId associé ? - // TODO : ??VERIF accès concurrent à la séquence stockée ?? suppression simultanée ? - } }; // Désalocation du buffer intermédiaire -// dans le cas de types utilisateur/CORBA différents -template <> -struct DeleteTraits{ +// dans le cas d'un type Utilisateur différent du type CORBA +template +struct DeleteTraits< false, DataManipulator > { template static void apply(T * dataPtr) { delete[] dataPtr; } diff --git a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am index 3bdabe92a..3792dc9a2 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am +++ b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am @@ -57,6 +57,7 @@ salomeinclude_HEADERS = calcium_port_factory.hxx \ calcium.h \ Calcium.hxx \ calciumP.h \ + calciumE.h \ version.h \ calcium.hf diff --git a/src/DSC/DSC_User/Datastream/Calcium/calcium.h b/src/DSC/DSC_User/Datastream/Calcium/calcium.h index b90d5499f..a1d87b295 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/calcium.h +++ b/src/DSC/DSC_User/Datastream/Calcium/calcium.h @@ -29,6 +29,7 @@ #ifndef __CALCIUM_H #define __CALCIUM_H +#include #include #include diff --git a/src/DSC/DSC_User/Datastream/Calcium/calciumE.h b/src/DSC/DSC_User/Datastream/Calcium/calciumE.h new file mode 100644 index 000000000..49c9e57d8 --- /dev/null +++ b/src/DSC/DSC_User/Datastream/Calcium/calciumE.h @@ -0,0 +1,401 @@ +/* Copyright (C) 2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, + * CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + * + * + * + * File : calcium.h + * Author : Eric Fayolle (EDF) + * Module : KERNEL + */ + +/* Outils d'Aide au Couplage de Code de Calcul : $Id$ */ + +#ifndef __CALCIUM_E_H +#define __CALCIUM_E_H + +#include + +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) +#define CPNeedPrototype 1 +#else +#define CPNeedPrototype 0 +#endif + + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* */ +/* */ +/* Fonctions de connexion */ +/* */ +/* */ +extern int ecp_cd( +/* ----- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + char * /* S Nom de l instance appelante*/ +#endif +); + + +/* */ +/* */ +/* Fonction de deconnexion */ +/* */ +/* */ +extern int ecp_fin( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Directive de continuation */ + /* CP_CONT ou CP_ARRET */ +#endif +); + +/* */ +/* */ +/* Fonctions de libération du buffer 0 copy */ +/* */ + + extern void ecp_len_free( +#if CPNeedPrototype + int * +#endif + ); + extern void ecp_lre_free( +#if CPNeedPrototype + float * +#endif + ); + extern void ecp_ldb_free( +#if CPNeedPrototype + double * +#endif + ); + extern void ecp_llo_free( +#if CPNeedPrototype + int * +#endif + ); + extern void ecp_lcp_free( +#if CPNeedPrototype + float * +#endif + ); + extern void ecp_lch_free( +#if CPNeedPrototype + char ** +#endif + ); + + + +/* */ +/* */ +/* Fonctions de lecture bloquante 0 copy */ +/* */ +/* */ +extern int ecp_len( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d'entiers pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_lre( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_ldb( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + double* /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + double* /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + double**/* E/S Tableau de doubles pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_lcp( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues (dimension = 2 * le nombre */ + /* de valeurs lues) */ +#endif +); + +extern int ecp_llo( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d 'entier pour stocker les */ + /* valeurs lues (remplace le logiques) */ +#endif +); + +extern int ecp_lch( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + char **[]/*E/S Tableau de chaines pour stocker les */ + /* valeurs lues (remplace le logiques) */, + int /* E Taille des chaines du tablaeu */ +#endif +); + + + +/* */ +/* */ +/* Fonctions de lecture non bloquantes */ +/* */ +/* */ +extern int ecp_nlen( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d'entiers pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nlre( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nldb( +/* ------- */ + +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + double */* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + double */* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + double**/* E/S Tableau de doubles pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nlcp( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues (dimension = 2 * le nombre */ + /* de valeurs lues) */ +#endif +); + +extern int ecp_nllo( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int **/* E/S Tableau d 'entier pour stocker les */ + /* valeurs lues (remplace le logiques) */ +#endif +); + +extern int ecp_nlch( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + char **[]/* E/S Tableau de chaines pour stocker les */ + /* valeurs lues (remplace le logiques) */, + int /* E Taille des chaines du tablaeu */ +#endif +); + + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + + +#endif diff --git a/src/DSC/DSC_User/Datastream/Calcium/calciumf.c b/src/DSC/DSC_User/Datastream/Calcium/calciumf.c index 557e1ed1a..442470f49 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/calciumf.c +++ b/src/DSC/DSC_User/Datastream/Calcium/calciumf.c @@ -116,7 +116,7 @@ void F_FUNC(cplch,CPLCH)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_ *err=cp_lch((void *)*compo,*dep,ti,tf,iter,cnom,*max,n,tabChaine,STR_LEN(tab)); for (index = 0; index < *n; index++) - strcpy(&tab[index * STR_LEN(tab)], tabChaine[index]); + strncpy(&tab[index * STR_LEN(tab)], tabChaine[index], strlen(tabChaine[index])); fprintf(stderr,"End of CPLCH: %s %f %f \n",cnom,*ti,*tf); if (tabChaine != (char **) NULL) { diff --git a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx index c0adc1853..cbaa6470e 100644 --- a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx +++ b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx @@ -208,19 +208,25 @@ public: CORBA::Long len = data.length(); CORBA::Long max = data.maximum(); // Récupère et devient propriétaire des données reçues dans la séquence. - // La séquence (mais pas le buffer) sera désallouée au retour - // de la méthode GenericPort::put (car le mapping CORBA de ce type IN est : const seq & ) + // La séquence reçue (mais pas le buffer) sera désallouée au retour + // de la méthode CORBA qui a reçu le type CorbaInType en paramètre + // (ex: GenericPort::put) + // REM : Le mapping CORBA du type séquence IN est : const seq & // OLD : On ne teste pas si le flag release de la séquence est à true ou false // OLD : ( pour des séquences de chaines ou d'objrefs ) // OLD : -> Si on est collocalisé le port uses doit créer une copie pour éviter la modification // OLD : du contenu de la séquence lorsque l'utilisateur modifie ses données dans son programme (0 copie) + // OLD : ATTENTION TESTER p194 si le pointeur est null (release flag==false) + // OLD : -> La séquence n'était pas propriétaire des données ! // Le flag release() de la séquence est à false si elle n'est pas propriétaire du buffer - // En collocalité c'est le cas (on évite ici la copie réalisée auparavant dans le port uses). + // En collocalité release() renvoie false car + // l'appelé n'est pas propriétaire de la séquence. On effectue alors + // une copie pour éviter de perturber les structures de données de l'appelant. + // En non collocalisé on recrée une séquence avec le buffer de la première dont on + // a demandé la propriété. - // ATTENTION TESTER p194 si le pointeur est null (release flag==false) - // -> La séquence n'était pas propriétaire des données ! #ifdef _DEBUG_ std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl; #endif @@ -228,8 +234,8 @@ public: InnerType * p_data = const_cast(data).get_buffer(true); // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie) - // Les données de la séquence seront automatiquement désallouées par appel à la méthode freebuf - // dans le destructeur de la séquence (cf delete_data). + // Les données de la nouvelle séquence seront automatiquement désallouées + // par appel à la méthode freebuf dans le destructeur de la séquence (cf delete_data). #ifdef _DEBUG_ std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(0 copy) bis ------"<< p_data <<"------------" << std::endl; #endif @@ -265,9 +271,13 @@ public: return new seq_T (data); } - // Permet d'obtenir un pointeur sur le buffer de la séquence - // si ownerShip=True, la séquence n'est plus propriétaire du buffer et est - // détruite (mais pas le buffer !) + // Permet d'obtenir un pointeur sur le buffer de la séquence : + // Si ownerShip=True, la séquence n'est plus propriétaire du buffer + // (son pointeur de buffer interne est aussi réinitialisé) + // On détruit également explicitement la séquence (mais pas le buffer !) + // Si ownerShip=False, la séquence reste propriétaire du buffer + // et l'utilisateur devra appeler delete_data sur la séquence contenante pour + // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool ownerShip = false) { InnerType * p_data; if (ownerShip) { @@ -278,9 +288,8 @@ public: return p_data; } - // Permet de désallouer le buffer dont on détient le pointeur par appel - // à la méthode getPointer avec ownerShip=True si la séquence contenante - // à été détruite. + // Permet de désallouer le buffer dont on détient le pointeur après appel + // à la méthode getPointer avec ownerShip=True static inline void relPointer(InnerType * dataPtr) { seq_T::freebuf(dataPtr); } @@ -290,7 +299,7 @@ public: return seq_T::allocbuf(size); } - // Operation de création de la séquence corba soit + // Opération de création de la séquence CORBA soit // - Vide et de taille size // - Utilisant les données du pointeur *data de taille size // (généralement pas de recopie qlq soit l'ownership ) @@ -317,7 +326,7 @@ public: for (int i = 0; i< isize; ++i) idata[i]=dataPtr[i]; - // Ce mode de recopie ne permet pas la conversion de type (ex int -> CORBA::Long + // Le mode de recopie suivant ne permet pas la conversion de type (ex int -> CORBA::Long) //OLD: Type tmp = new seq_T(isize,isize,idata,false); //OLD: // giveOwnerShip == false -> seul le contenu du buffer data est détruit et remplacé //OLD: // par celui de data dans l'affectation suivante : @@ -331,6 +340,10 @@ public: } // Copie le contenu de la séquence de char* dans le buffer idata de taille isize + // La généralisation de la recopie profonde est difficile du fait que CORBA ne renvoie pas + // pas des objets de haut niveau de type std::vector (avec des interfaces d'accès identiques) + // mais un type simple C comme char *Tab[N]. On doit alors utiliser une méthode de recopie spécifique + // comme l'appel C strcpy. static inline void copy( Type data, char* * const idata, size_t isize ) { char* *dataPtr = getPointer(data,false); @@ -415,9 +428,13 @@ public: delete data; } - // Récupère un pointeur sur les données de type InnerType contenue dans la séquence - // si ownership=True, l'utilisateur devra appeler relPointer - // si ownership=False, l'utilisateur devra appeler delete_data sur la séquence contenante + // Permet d'obtenir un pointeur sur le buffer de la séquence : + // Si ownerShip=True, la séquence n'est plus propriétaire du buffer + // (son pointeur de buffer interne est aussi réinitialisé) + // On détruit également explicitement la séquence (mais pas le buffer !) + // Si ownerShip=False, la séquence reste propriétaire du buffer + // et l'utilisateur devra appeler delete_data sur la séquence contenante pour + // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) { InnerType * p_data; if (getOwnerShip) { diff --git a/src/KERNEL_PY/salome_shared_modules.py b/src/KERNEL_PY/salome_shared_modules.py index 892b1085f..a1f2b2df8 100755 --- a/src/KERNEL_PY/salome_shared_modules.py +++ b/src/KERNEL_PY/salome_shared_modules.py @@ -79,13 +79,7 @@ if sys.platform == "win32": splitter = ";" path=salome_path.split(splitter) import platform -if platform.architecture()[0] == "64bit": - if platform.machine() == "ia64": - libdir = "lib" - else: - libdir = "lib64" -else: - libdir = "lib" +libdir = "lib" for rep in path: # Import all *_shared_modules in rep for f in glob.glob(os.path.join(rep,libdir,"python"+sys.version[:3],"site-packages","salome","shared_modules","*_shared_modules.py")): diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx index a18a09c8e..d1b105a37 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx @@ -44,8 +44,16 @@ #include "SALOME_LifeCycleCORBA.hxx" #ifndef WNT #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Session) +#include CORBA_CLIENT_HEADER(DSC_Engines) +#include CORBA_CLIENT_HEADER(SALOME_Registry) +#include CORBA_CLIENT_HEADER(SALOMEDS) #else #include "SALOME_ModuleCatalog.hh" +#include "SALOME_Session.hh" +#include "DSC_Engines.hh" +#include "SALOME_Registry.hh" +#include "SALOMEDS.hh" #endif #include "SALOME_ContainerManager.hxx" #include "SALOME_Component_i.hxx" @@ -421,6 +429,100 @@ Engines::ResourcesManager_ptr SALOME_LifeCycleCORBA::getResourcesManager() return resManager._retn(); } +//============================================================================= +/*! Public - + * shutdown all the SALOME servers except SALOME_Session_Server, omniNames and notifd + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::shutdownServers() +{ + // get each Container from NamingService => shutdown it + // (the order is inverse to the order of servers initialization) + + SALOME::Session_var session = SALOME::Session::_nil(); + CORBA::Long pid = 0; + CORBA::Object_var objS = _NS->Resolve("/Kernel/Session"); + if (!CORBA::is_nil(objS)) + { + session = SALOME::Session::_narrow(objS); + if (!CORBA::is_nil(session)) + { + pid = session->getPID(); + session->ping(); + } + } + + string hostname = GetHostname(); + + // 1) SalomeLauncher + CORBA::Object_var objSL = _NS->Resolve("/SalomeLauncher"); + Engines::SalomeLauncher_var launcher = Engines::SalomeLauncher::_narrow(objSL); + if (!CORBA::is_nil(launcher) && (pid != launcher->getPID())) + launcher->Shutdown(); + + // 2) ConnectionManager + CORBA::Object_var objCnM=_NS->Resolve("/ConnectionManager"); + Engines::ConnectionManager_var connMan=Engines::ConnectionManager::_narrow(objCnM); + if ( !CORBA::is_nil(connMan) && ( pid != connMan->getPID() ) ) + connMan->ShutdownWithExit(); + + // 3) SALOMEDS + CORBA::Object_var objSDS = _NS->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(objSDS) ; + if ( !CORBA::is_nil(studyManager) && ( pid != studyManager->getPID() ) ) + studyManager->Shutdown(); + + // 4) ModuleCatalog + CORBA::Object_var objMC=_NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objMC); + if ( !CORBA::is_nil(catalog) && ( pid != catalog->getPID() ) ) + catalog->shutdown(); + + // 5) Registry + CORBA::Object_var objR = _NS->Resolve("/Registry"); + Registry::Components_var registry = Registry::Components::_narrow(objR); + if ( !CORBA::is_nil(registry) && ( pid != registry->getPID() ) ) + registry->Shutdown(); +} + +//============================================================================= +/*! Public - + * shutdown omniNames and notifd + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::killOmniNames() +{ + string portNumber (::getenv ("NSPORT") ); + if ( !portNumber.empty() ) + { + string cmd ; + cmd = string( "ps -eo pid,command | grep -v grep | grep -E \"omniNames.*") + + portNumber + + string("\" | awk '{cmd=sprintf(\"kill -9 %s\",$1); system(cmd)}'" ); + MESSAGE(cmd); + system ( cmd.c_str() ); + } + + // NPAL 18309 (Kill Notifd) + if ( !portNumber.empty() ) + { + string cmd = ("import pickle, os; "); + cmd += string("from killSalomeWithPort import getPiDict; "); + cmd += string("filedict=getPiDict(") + portNumber + "); "; + cmd += string("f=open(filedict, 'r'); "); + cmd += string("pids=pickle.load(f); "); + cmd += string("m={}; "); + cmd += string("[ m.update(i) for i in pids ]; "); + cmd += string("pids=filter(lambda a: 'notifd' in m[a], m.keys()); "); + cmd += string("[ os.kill(pid, 9) for pid in pids ]; "); + cmd += string("os.remove(filedict); "); + cmd = string("python -c \"") + cmd +"\" > /dev/null"; + MESSAGE(cmd); + system( cmd.c_str() ); + } +} //============================================================================= /*! Protected - diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx index ced93eb1e..42e67688d 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx @@ -104,6 +104,9 @@ public: Engines::ContainerManager_ptr getContainerManager(); Engines::ResourcesManager_ptr getResourcesManager(); + void shutdownServers(); + static void killOmniNames(); + protected: /*! Establish if a component called "componentName" in a container called diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfInteger.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfInteger.cxx index 0539b5e81..27abce57b 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfInteger.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfInteger.cxx @@ -432,107 +432,122 @@ vector SALOMEDSImpl_AttributeTableOfInteger::GetSetColumnIndices(const int string SALOMEDSImpl_AttributeTableOfInteger::Save() { - ostrstream theStream; + string aString; + char* buffer = new char[1024]; int i, j, l; - theStream.precision(64); - //Title l = myTitle.size(); - theStream << l << "\n"; - for(i=0; ifirst << "\n"; - theStream << p->second << "\n"; + sprintf(buffer, "%d\n%d\n", p->first, p->second); + aString += buffer; } - string aString((char*)theStream.rdbuf()->str()); + delete []buffer; return aString; } + + void SALOMEDSImpl_AttributeTableOfInteger::Load(const string& value) { - istrstream theStream(value.c_str(), strlen(value.c_str())); - Backup(); + vector v; + int i, j, l, pos, aSize = (int)value.size(); + for(i = 0, pos = 0; i> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTitle = std::string(l, 0); for(i=0; i> anExtChar; - myTitle[i] = anExtChar; + myTitle[i] = v[pos++][0]; } //Nb rows - theStream >> myNbRows; + myNbRows = strtol(v[pos++].c_str(), NULL, 10); //Rows titles myRows.clear(); for(i=1; i<=myNbRows; i++) { - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myRows.push_back(aStr); } //Nb columns - theStream >> myNbColumns; + myNbColumns = strtol(v[pos++].c_str(), NULL, 10); //Columns titles myCols.clear(); for(i=1; i<=myNbColumns; i++) { - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myCols.push_back(aStr); } //Restore the table values - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTable.clear(); for(i=1; i<=l; i++) { - int aKey, aValue; - theStream >> aKey; - theStream >> aValue; + int aKey = strtol(v[pos++].c_str(), NULL, 10); + int aValue = strtol(v[pos++].c_str(), NULL, 10); myTable[aKey] = aValue; } } diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfReal.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfReal.cxx index 64c5f03a6..2c3aba89e 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfReal.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfReal.cxx @@ -432,109 +432,120 @@ vector SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int the string SALOMEDSImpl_AttributeTableOfReal::Save() { - ostrstream theStream; + string aString; + char* buffer = new char[1024]; int i, j, l; //Title l = myTitle.size(); - theStream << l << "\n"; - for(i=0; ifirst << "\n"; - sprintf(aBuffer, "%.64e", p->second); - theStream << aBuffer << "\n"; + sprintf(buffer, "%d\n%.64e\n", p->first, p->second); + aString += buffer; } - - delete []aBuffer; - string aString((char*)theStream.rdbuf()->str()); + + delete []buffer; return aString; } void SALOMEDSImpl_AttributeTableOfReal::Load(const string& value) { - istrstream theStream(value.c_str(), strlen(value.c_str())); - Backup(); + vector v; + int i, j, l, pos, aSize = (int)value.size(); + for(i = 0, pos = 0; i> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTitle = std::string(l, 0); for(i=0; i> anExtChar; - myTitle[i] = anExtChar; + myTitle[i] = v[pos++][0]; } //Nb rows - theStream >> myNbRows; + myNbRows = strtol(v[pos++].c_str(), NULL, 10); //Rows titles myRows.clear(); for(i=1; i<=myNbRows; i++) { - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myRows.push_back(aStr); } //Nb columns - theStream >> myNbColumns; + myNbColumns = strtol(v[pos++].c_str(), NULL, 10); //Columns titles myCols.clear(); for(i=1; i<=myNbColumns; i++) { - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myCols.push_back(aStr); } //Restore the table values - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTable.clear(); for(i=1; i<=l; i++) { - int aKey; - double aValue; - theStream >> aKey; - theStream >> aValue; + int aKey = strtol(v[pos++].c_str(), NULL, 10); + double aValue = strtod(v[pos++].c_str(), NULL); myTable[aKey] = aValue; } diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfString.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfString.cxx index 245de358c..350dc0b28 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfString.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTableOfString.cxx @@ -433,131 +433,137 @@ vector SALOMEDSImpl_AttributeTableOfString::GetSetColumnIndices(const int t string SALOMEDSImpl_AttributeTableOfString::Save() { - ostrstream theStream; + string aString; + char* buffer = new char[1024]; int i, j, l; - + //Title l = myTitle.size(); - theStream << l << "\n"; - for(i=0; isecond.size()) { // check empty string in the value table - theStream << p->first << "\n"; + sprintf(buffer, "%d\n", p->first); + aString += buffer; unsigned long aValueSize = p->second.size(); - theStream<second.c_str(),aValueSize); - theStream<<"\n"; + sprintf(buffer, "%ld\n", aValueSize); + aString +=buffer; + aString += p->second; + aString += '\n'; } else { // write index only of kind: "0key"; "05", for an example - theStream << "0" << p->first << "\n"; + sprintf(buffer, "0%d\n", p->first); + aString+=buffer; } } - string aString((char*)theStream.rdbuf()->str()); + + delete []buffer; return aString; } void SALOMEDSImpl_AttributeTableOfString::Load(const string& value) { - istrstream theStream(value.c_str(), strlen(value.c_str())); - Backup(); - - theStream.seekg(0, ios::end); - long aSize = theStream.tellg(); - theStream.seekg(0, ios::beg); + vector v; + int i, j, l, pos, aSize = (int)value.size(); + for(i = 0, pos = 0; i> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTitle = std::string(l, 0); for(i=0; i> anExtChar; - myTitle[i] = anExtChar; + myTitle[i] = v[pos++][0]; } //Nb rows - theStream >> myNbRows; + myNbRows = strtol(v[pos++].c_str(), NULL, 10); //Rows titles myRows.clear(); - for(i=0; i> l; + for(i=1; i<=myNbRows; i++) { + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myRows.push_back(aStr); } //Nb columns - theStream >> myNbColumns; + myNbColumns = strtol(v[pos++].c_str(), NULL, 10); //Columns titles myCols.clear(); - for(i=0; i> l; + for(i=1; i<=myNbColumns; i++) { + l = strtol(v[pos++].c_str(), NULL, 10); aStr = std::string(l,0); for(j=0; j> anExtChar; - aStr[j] = anExtChar; + aStr[j] = v[pos++][0]; } myCols.push_back(aStr); } //Restore the table values - string aValue; - theStream >> l; + l = strtol(v[pos++].c_str(), NULL, 10); myTable.clear(); - theStream.getline(aValueString,aSize,'\n'); for(i=1; i<=l; i++) { - int aKey; - - theStream.getline(aValueString,aSize,'\n'); - aValue = aValueString; - aKey = atoi(aValue.c_str()); - if (aValue[0] == '0') + aStr = v[pos++]; //Ket as a string + int aKey = strtol(aStr.c_str(), NULL, 10); + string aValue; + if(aStr[0] == '0') //If the first character of the key is 0, then empty value aValue = ""; else { - unsigned long aValueSize; - theStream >> aValueSize; - theStream.read(aValueString, 1); // an '\n' omitting - theStream.read(aValueString, aValueSize); - theStream.read(aValueString, 1); // an '\n' omitting - aValue = aValueString; + long aSize = strtol(v[pos++].c_str(), NULL, 10); + aValue = v[pos++]; } myTable[aKey] = aValue; } - delete(aValueString); }