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__
# -----------------------------------------------------------------------------
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__
# -----------------------------------------------------------------------------
# ================================================================
#
#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, ...
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.)
\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, <b>the recommended way is
+the second, easier to configure.</b>
<ol>
<li>
<b>First way - references to different module directories</b>
-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
<b>Second and easiest way - one single virtual install directory</b>
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,
The following command::
\code
-python <KERNEL_ROOT_DIR>/bin/SALOME/appli_gen.py --prefix=<install directory> --config=<configuration file>
+python <KERNEL_ROOT_DIR>/bin/salome/appli_gen.py --prefix=<install directory> --config=<configuration file>
\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.
+<b>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</b>
-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).
</li>
</ol>
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.
+<b>With the virtual installation (second way, above), env.d
+scripts are built automatically.</b>
**The following is only an example proposed by createAppli.sh, (first way of installation) not working as it is**.
- 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
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).
</li>
<li>
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.
</li>
<li>
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 <b>Windows (R) operating system</b> (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...
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,
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
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::
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);
} ;
} ;
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)
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])
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 */
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 ); \
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, \
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); \
\
};
-
+/* 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) {
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;
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*/
}
+
+/***************************/
/* INTERFACES D'ECRITURE */
+/***************************/
#define CALCIUM_ECR_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
InfoType cp_##_name (void * component, int mode, \
}; \
+/* 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,
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<nbelem; ++j) dLogique[j]=data[j];
-
- InfoType info = ecp_ecriture_bool (component, mode, &t, i,
- nomvar, nbelem,
- dLogique);
-
- free(dLogique);
-
- fprintf(stderr,"End of cpelo: %s %d \n",nomvar,i);
- fflush(stdout);
- fflush(stderr);
-
- return info;
-};
-
-/* 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_(ecp,float,float,cplx,);
std::vector<std::string>::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;
{
typedef typename ProvidesPortTraits<T2>::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<IsSameType<T1,InnerType>::value >::apply(dataPtr);
+ DeleteTraits<IsSameType<T1,InnerType>::value, DataManipulator >::apply(dataPtr);
}
template <typename T1> static void
}
// T1 est le type de données
- // T2 est un <nom> de type Calcium permettant de sélectionner le port correspondant
+ // T2 est un <nom> 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
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<T1,InnerType>::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<T1,InnerType>::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<T1,InnerType>::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<T1,InnerType>::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<false>::apply(data,corbaData,nRead);
+ Copy2UserSpace<false, DataManipulator >::apply(data,corbaData,nRead);
+ DataManipulator::copy(corbaData,data,nRead);
+
#ifdef _DEBUG_
std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
#endif
// 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<IsSameType<T1,InnerType>::value >::apply(corbaData,data,bufferLength);
+ Copy2CorbaSpace<IsSameType<T1,InnerType>::value, DataManipulator >::apply(corbaData,data,bufferLength);
//TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
#ifndef _CALCIUM_GENERIC_PROVIDES_PORT_HXX_
#define _CALCIUM_GENERIC_PROVIDES_PORT_HXX_
+#include <omnithread.h>
+
#include "PortProperties_i.hxx"
#include "calcium_provides_port.hxx"
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); \
} \
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); \
+ } \
+ }; \
// 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
#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,
template <> struct ProvidesPortTraits<cplx> {
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<str> {
typedef calcium_string_port_provides PortType;
};
- template <> struct ProvidesPortTraits<char *> {
- typedef calcium_string_port_provides PortType;
- };
+
template < typename T > struct StarTrait { typedef T NonStarType; };
template < typename T > struct StarTrait< T * > { typedef T NonStarType; };
#include <iostream>
#include "CalciumPortTraits.hxx"
-template <bool zerocopy>
+template <bool zerocopy, typename DataManipulator>
struct Copy2CorbaSpace {
template <class T1, class T2>
typedef typename ProvidesPortTraits<T2>::PortType PortType;
//typedef typename UsesPortTraits<T2>::PortType PortType;
- typedef typename PortType::DataManipulator DataManipulator;
+//ESSAI: typedef typename PortType::DataManipulator DataManipulator;
typedef typename DataManipulator::InnerType InnerType;
#ifdef _DEBUG_
};
// Cas ou il faut effectuer une recopie
-template <> struct
-Copy2CorbaSpace<false> {
+template <typename DataManipulator> struct
+Copy2CorbaSpace<false, DataManipulator> {
template <class T1, class T2>
static void apply( T1 * & corbaData, T2 & data, size_t nRead){
typedef typename ProvidesPortTraits<T2>::PortType PortType;
// typedef typename UsesPortTraits<T2>::PortType PortType;
- typedef typename PortType::DataManipulator DataManipulator;
+//ESSAI: typedef typename PortType::DataManipulator DataManipulator;
typedef typename DataManipulator::InnerType InnerType;
corbaData = DataManipulator::create(nRead);
//Les demandes de copies vers l'espace utilisateur
//proviennent d'une procédure de lecture
+
//Cas du zero copie
-template <bool zerocopy >
+template <bool zerocopy, typename DataManipulator >
struct Copy2UserSpace{
template <class T1, class T2>
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<T1>::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 :
};
// Cas où il faut effectuer une recopie
-template <>
-struct Copy2UserSpace<false> {
+template <typename DataManipulator>
+struct Copy2UserSpace<false, DataManipulator> {
//Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead
template <class T1, class T2>
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<T1>::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<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
- DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
- std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(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<false> MARK 1b --data("<<tmpData<<")[0.."<<
- DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
- std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(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<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
+ DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+ std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(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<false> MARK 1b --data("<<tmpData<<")[0.."<<
+ DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+ std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(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<false> MARK 1c --data("<<tmpData<<")[0.."<<
- DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
- std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(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<false> MARK 1c --data("<<tmpData<<")[0.."<<
+ DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+ std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+ for (int i=0; i< DataManipulator::size(corbaData); ++i)
+ fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
+ std::cerr << std::endl;
#endif
}
// Désallocation des buffers si necessaire
-template <bool rel>
+template <bool rel, typename DataManipulator >
struct DeleteTraits {
template <typename T>
static void apply(T * dataPtr) {
- typedef typename ProvidesPortTraits<T>::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<false>{
+// dans le cas d'un type Utilisateur différent du type CORBA
+template <typename DataManipulator>
+struct DeleteTraits< false, DataManipulator > {
template <typename T>
static void apply(T * dataPtr) { delete[] dataPtr; }
calcium.h \
Calcium.hxx \
calciumP.h \
+ calciumE.h \
version.h \
calcium.hf
#ifndef __CALCIUM_H
#define __CALCIUM_H
+#include <calciumE.h>
#include <version.h>
#include <calciumP.h>
--- /dev/null
+/* 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 <calciumP.h>
+
+#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
*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) {
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
InnerType * p_data = const_cast<seq_T &>(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
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) {
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);
}
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 )
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 :
}
// 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<std::string> (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);
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) {
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")):
#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"
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 -
Engines::ContainerManager_ptr getContainerManager();
Engines::ResourcesManager_ptr getResourcesManager();
+ void shutdownServers();
+ static void killOmniNames();
+
protected:
/*! Establish if a component called "componentName" in a container called
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; i<l; i++)
- theStream << myTitle[i] << "\n";
-
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(i=0; i<l; i++) {
+ aString += myTitle[i];
+ aString +='\n';
+ }
+
//Nb rows
- theStream << myNbRows << "\n";
+ sprintf(buffer, "%d\n", myNbRows);
+ aString+=buffer;
- //Rows titles
+ //Row titles
for(i=0; i<myNbRows; i++) {
l = myRows[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myRows[i][j] << "\n";
- }
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myRows[i][j];
+ aString += '\n';
+ }
+ }
//Nb columns
- theStream << myNbColumns << "\n";
+ sprintf(buffer, "%d\n", myNbColumns);
+ aString+=buffer;
//Columns titles
for(i=0; i<myNbColumns; i++) {
l = myCols[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myCols[i][j] << "\n";
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myCols[i][j];
+ aString += '\n';
+ }
}
//Store the table values
l = myTable.size();
- theStream << l << "\n";
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
for(MI p = myTable.begin(); p != myTable.end(); p++) {
- theStream << p->first << "\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<string> v;
+ int i, j, l, pos, aSize = (int)value.size();
+ for(i = 0, pos = 0; i<aSize; i++) {
+ if(value[i] == '\n') {
+ v.push_back(value.substr(pos, i-pos));
+ pos = i+1;
+ }
+ }
- int i, j, l;
+ Backup();
- char anExtChar;
+ pos = 0;
std::string aStr;
//Title
- theStream >> l;
+ l = strtol(v[pos++].c_str(), NULL, 10);
myTitle = std::string(l, 0);
for(i=0; i<l; i++) {
- theStream >> 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<l; j++) {
- theStream >> 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<l; j++) {
- theStream >> 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;
}
}
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; i<l; i++)
- theStream << myTitle[i] << "\n";
-
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(i=0; i<l; i++) {
+ aString += myTitle[i];
+ aString +='\n';
+ }
+
//Nb rows
- theStream << myNbRows << "\n";
+ sprintf(buffer, "%d\n", myNbRows);
+ aString+=buffer;
- //Rows titles
+ //Row titles
for(i=0; i<myNbRows; i++) {
l = myRows[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myRows[i][j] << "\n";
- }
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myRows[i][j];
+ aString += '\n';
+ }
+ }
//Nb columns
- theStream << myNbColumns << "\n";
+ sprintf(buffer, "%d\n", myNbColumns);
+ aString+=buffer;
//Columns titles
for(i=0; i<myNbColumns; i++) {
l = myCols[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myCols[i][j] << "\n";
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myCols[i][j];
+ aString += '\n';
+ }
}
//Store the table values
l = myTable.size();
- theStream << l << "\n";
- char *aBuffer = new char[128];
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
for(MI p = myTable.begin(); p != myTable.end(); p++) {
- theStream << p->first << "\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<string> v;
+ int i, j, l, pos, aSize = (int)value.size();
+ for(i = 0, pos = 0; i<aSize; i++) {
+ if(value[i] == '\n') {
+ v.push_back(value.substr(pos, i-pos));
+ pos = i+1;
+ }
+ }
- int i, j, l;
+ Backup();
- char anExtChar;
+ pos = 0;
std::string aStr;
//Title
- theStream >> l;
+ l = strtol(v[pos++].c_str(), NULL, 10);
myTitle = std::string(l, 0);
for(i=0; i<l; i++) {
- theStream >> 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<l; j++) {
- theStream >> 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<l; j++) {
- theStream >> 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;
}
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; i<l; i++)
- theStream << myTitle[i] << "\n";
-
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(i=0; i<l; i++) {
+ aString += myTitle[i];
+ aString +='\n';
+ }
+
//Nb rows
- theStream << myNbRows << "\n";
+ sprintf(buffer, "%d\n", myNbRows);
+ aString+=buffer;
- //Rows titles
+ //Row titles
for(i=0; i<myNbRows; i++) {
l = myRows[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myRows[i][j] << "\n";
- }
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myRows[i][j];
+ aString += '\n';
+ }
+ }
//Nb columns
- theStream << myNbColumns << "\n";
+ sprintf(buffer, "%d\n", myNbColumns);
+ aString+=buffer;
//Columns titles
for(i=0; i<myNbColumns; i++) {
l = myCols[i].size();
- theStream << l << "\n";
- for(j=0; j<l; j++)
- theStream << myCols[i][j] << "\n";
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
+ for(j=0; j<l; j++) {
+ aString += myCols[i][j];
+ aString += '\n';
+ }
}
//Store the table values
l = myTable.size();
- theStream << l << "\n";
+ sprintf(buffer, "%d\n", l);
+ aString+=buffer;
for(MI p = myTable.begin(); p!=myTable.end(); p++) {
if (p->second.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<<aValueSize << "\n";
- theStream.write(p->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<string> v;
+ int i, j, l, pos, aSize = (int)value.size();
+ for(i = 0, pos = 0; i<aSize; i++) {
+ if(value[i] == '\n') {
+ v.push_back(value.substr(pos, i-pos));
+ pos = i+1;
+ }
+ }
- int i, j, l;
- char *aValueString = new char[aSize];
+ Backup();
- char anExtChar;
+ pos = 0;
std::string aStr;
//Title
- theStream >> l;
+ l = strtol(v[pos++].c_str(), NULL, 10);
myTitle = std::string(l, 0);
for(i=0; i<l; i++) {
- theStream >> 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<myNbRows; i++) {
- theStream >> l;
+ for(i=1; i<=myNbRows; i++) {
+ l = strtol(v[pos++].c_str(), NULL, 10);
aStr = std::string(l,0);
for(j=0; j<l; j++) {
- theStream >> 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<myNbColumns; i++) {
- theStream >> l;
+ for(i=1; i<=myNbColumns; i++) {
+ l = strtol(v[pos++].c_str(), NULL, 10);
aStr = std::string(l,0);
for(j=0; j<l; j++) {
- theStream >> 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);
}