]> SALOME platform Git repositories - modules/kernel.git/blob - src/DSC/DSC_Basic/DSC_interface.cxx
Salome HOME
#18963 Minimize compiler warnings
[modules/kernel.git] / src / DSC / DSC_Basic / DSC_interface.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : DSC_interface.cxx
24 //  Author : André RIBES (EDF)
25 //  Module : KERNEL
26 //
27 #include <string>
28 #include "DSC_interface.hxx"
29 #ifdef WIN32
30 #else
31 #include <sys/time.h>
32 #endif
33 #include <fstream>
34 #include <sys/stat.h>
35 #include <sstream>
36 #include <stdlib.h>
37
38 //#define MYDEBUG
39
40 Engines_DSC_interface::Engines_DSC_interface() {}
41
42 Engines_DSC_interface::~Engines_DSC_interface() 
43 {
44   my_ports_it = my_ports.begin();
45   for(;my_ports_it != my_ports.end();my_ports_it++)
46     delete my_ports_it->second;
47
48 }
49
50 void
51 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref, 
52                                  const char* provides_port_name,
53                                  Ports::PortProperties_ptr port_prop) 
54 {
55   // Method args test
56   assert(provides_port_name);
57   if (CORBA::is_nil(ref))
58     throw Engines::DSC::NilPort();
59   if (CORBA::is_nil(port_prop))
60     throw Engines::DSC::BadProperty();
61
62   my_ports_it = my_ports.find(provides_port_name);
63   if (my_ports_it ==  my_ports.end()) {
64     // Creating a new port provides
65     port_t * new_port = new port_t();
66     new_port->type = provides;
67     new_port->connection_nbr = 0;
68     new_port->provides_port_ref = Ports::Port::_duplicate(ref);
69     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
70
71     // Port into the port's map
72     my_ports[provides_port_name] = new_port;
73   }
74   else
75     throw Engines::DSC::PortAlreadyDefined();
76 }
77
78 void
79 Engines_DSC_interface::add_uses_port(const char* repository_id, 
80                              const char* uses_port_name,
81                              Ports::PortProperties_ptr port_prop) 
82 {
83   // Method args test
84   // Note : We can't be shure that repository id
85   // is a correct CORBA id.
86   assert(repository_id);
87   assert(uses_port_name);
88   if (CORBA::is_nil(port_prop))
89     throw Engines::DSC::BadProperty();
90
91   my_ports_it = my_ports.find(uses_port_name);
92   if (my_ports_it ==  my_ports.end()) {
93     // Creating a new uses port
94     port_t * new_port = new port_t();
95     new_port->type = uses;
96     new_port->connection_nbr = 0;
97     new_port->uses_port_refs.length(0);
98     new_port->repository_id = repository_id;
99     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
100
101     // Port into port's map
102     my_ports[uses_port_name] = new_port;
103   }
104   else
105     throw Engines::DSC::PortAlreadyDefined();
106 }
107
108 Ports::Port_ptr
109 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
110                                  const CORBA::Boolean connection_error) 
111 {
112   // Method arg test
113   assert(provides_port_name);
114
115   Ports::Port_ptr rtn_port = Ports::Port::_nil();
116 //   std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
117 //   ports::iterator it;
118 //   std::cout << "----> ";
119 //   for(it=my_ports.begin();it!=my_ports.end();++it) 
120 //     std::cout << "|"<<(*it).first<<"|, ";
121 //   std::cout << std::endl;
122  
123   // Searching the port
124   my_ports_it = my_ports.find(provides_port_name);
125   if (my_ports_it ==  my_ports.end())
126     throw Engines::DSC::PortNotDefined();
127   if (my_ports[provides_port_name]->type != provides) {
128     Engines::DSC::BadPortType BPT;
129     BPT.expected = CORBA::string_dup("Expected a provides port");
130     BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
131     throw BPT;
132   }
133
134   if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
135     throw Engines::DSC::PortNotConnected();
136
137   rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
138   return rtn_port;
139 }
140
141 Engines::DSC::uses_port * 
142 Engines_DSC_interface::get_uses_port(const char* uses_port_name) 
143 {
144   // Method arg test
145   assert(uses_port_name);
146
147   Engines::DSC::uses_port * rtn_port = NULL;  
148
149   // Searching the uses port
150   my_ports_it = my_ports.find(uses_port_name);
151   if (my_ports_it == my_ports.end())
152     throw Engines::DSC::PortNotDefined();
153   if (my_ports[uses_port_name]->type != uses){
154     Engines::DSC::BadPortType BPT;
155     BPT.expected = CORBA::string_dup("Expected a uses port");
156     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
157 #ifdef MYDEBUG
158    std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
159 #endif
160     throw BPT;
161   }
162
163   // Is the port connected ?
164   if (my_ports[uses_port_name]->connection_nbr > 0) {
165     rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
166   }
167   else
168     {
169 #ifdef MYDEBUG
170    std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
171 #endif
172     throw Engines::DSC::PortNotConnected();
173     }
174   
175   return rtn_port;
176 }
177
178 void
179 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
180 {
181   // Method arg test
182   assert(provides_port_name);
183
184   // Searching the provides port
185   my_ports_it = my_ports.find(provides_port_name);
186   if (my_ports_it ==  my_ports.end())
187     throw Engines::DSC::PortNotDefined();
188   if (my_ports[provides_port_name]->type != provides)
189     throw Engines::DSC::PortNotDefined();
190
191
192   // Adding a new connection
193   my_ports[provides_port_name]->connection_nbr += 1;
194   // User code is informed
195   provides_port_changed(provides_port_name, 
196                         my_ports[provides_port_name]->connection_nbr,
197                         Engines::DSC::AddingConnection
198                        );
199 }
200
201 void
202 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
203                                          Ports::Port_ptr provides_port_ref) 
204 {
205   // Method arg test
206   assert(uses_port_name);
207
208   if (CORBA::is_nil(provides_port_ref))
209     throw Engines::DSC::NilPort();
210
211   // Searching the uses port
212   my_ports_it = my_ports.find(uses_port_name);
213   if (my_ports_it ==  my_ports.end())
214     throw Engines::DSC::PortNotDefined();
215   if (my_ports[uses_port_name]->type != uses) {
216     Engines::DSC::BadPortType BPT;
217     BPT.expected = CORBA::string_dup("Expected a uses port");
218     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
219     throw BPT;
220   }
221
222   // repository_id test
223   const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
224   if (provides_port_ref->_is_a(repository_id)) 
225   {
226     // Adding provides port into the uses port sequence
227     CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
228     my_ports[uses_port_name]->
229       uses_port_refs.length(lgth + 1);
230     my_ports[uses_port_name]->uses_port_refs[lgth] = 
231       Ports::Port::_duplicate(provides_port_ref);
232
233     // Adding a new connection
234     my_ports[uses_port_name]->connection_nbr += 1;
235     // User code is informed
236     uses_port_changed(uses_port_name,
237                       new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
238                       Engines::DSC::AddingConnection);
239   }
240   else {
241     Engines::DSC::BadPortType BPT;
242     BPT.expected = CORBA::string_dup("Expected ...");
243     BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
244                                       repository_id).c_str());
245     throw BPT;
246   }
247
248 }
249
250 CORBA::Boolean
251 Engines_DSC_interface::is_connected(const char* port_name) 
252 {
253   CORBA::Boolean rtn = false;
254
255   // Method arg test
256   assert(port_name);
257
258   my_ports_it = my_ports.find(port_name);
259   if (my_ports_it ==  my_ports.end())
260     throw Engines::DSC::PortNotDefined();
261
262   // Is it connected ?
263   if (my_ports[port_name]->connection_nbr > 0)
264     rtn = true;
265
266   return rtn;
267 }
268
269 void
270 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
271                                         const Engines::DSC::Message message)
272 {
273   // Method args test
274   assert(provides_port_name);
275
276   my_ports_it = my_ports.find(provides_port_name);
277   if (my_ports_it ==  my_ports.end())
278     throw Engines::DSC::PortNotDefined();
279   if (my_ports[provides_port_name]->type != provides)
280     throw Engines::DSC::PortNotDefined();
281
282   // Is it connected ?
283   if (my_ports[provides_port_name]->connection_nbr > 0) 
284   {
285     my_ports[provides_port_name]->connection_nbr -= 1;
286     provides_port_changed(provides_port_name,
287                           my_ports[provides_port_name]->connection_nbr,
288                           message);
289   }
290   else
291     throw Engines::DSC::PortNotConnected();
292 }
293
294 void
295 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
296                                     Ports::Port_ptr provides_port_ref,
297                                     const Engines::DSC::Message message)
298 {
299   // Method args test
300   assert(uses_port_name);
301
302   my_ports_it = my_ports.find(uses_port_name);
303   if (my_ports_it ==  my_ports.end())
304     throw Engines::DSC::PortNotDefined();
305   if (my_ports[uses_port_name]->type != uses)
306     throw Engines::DSC::PortNotDefined();
307
308   if (CORBA::is_nil(provides_port_ref))
309     throw Engines::DSC::BadPortReference();
310
311   // Is it connected ?
312   if (my_ports[uses_port_name]->connection_nbr > 0) {
313     CORBA::Long port_index = -1;
314     CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length(); 
315     for(int i = 0; i < (int)seq_length; i++)
316     {
317       if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
318       {
319         port_index = i;
320         break;
321       }
322     }
323     if (port_index == -1)
324       throw Engines::DSC::BadPortReference();
325
326     my_ports[uses_port_name]->connection_nbr -= 1;
327     Engines::DSC::uses_port * new_uses_port = 
328       new Engines::DSC::uses_port();
329     new_uses_port->length(seq_length - 1);
330
331     int index_ancien = 0;
332     int index_nouveau = 0;
333     for(;index_ancien < (int)seq_length;) {
334       if (index_ancien == port_index) 
335       {
336         // Rien a faire !
337         // On ne change pas le index du nouveau tableau
338         index_ancien += 1;
339       }
340       else 
341       {
342         (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
343         index_ancien += 1;
344         index_nouveau += 1;
345       }
346     }
347
348     // New uses port's sequence
349     my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
350
351     // The user code is informed
352     uses_port_changed(uses_port_name,
353                       new_uses_port,
354                       message);
355   }
356   else
357     throw Engines::DSC::PortNotConnected();
358 }
359
360 Ports::PortProperties_ptr
361 Engines_DSC_interface::get_port_properties(const char* port_name) 
362 {
363   Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
364
365   // Method arg test
366   assert(port_name);
367
368   my_ports_it = my_ports.find(port_name);
369   if (my_ports_it ==  my_ports.end())
370     throw Engines::DSC::PortNotDefined();
371
372   rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
373   return rtn_properties;
374 }
375
376 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
377 static  int traceType=-1; // 0=stderr;1=file;
378 static  int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
379 static  std::ofstream traceFile;
380 static  std::ostream *out;
381
382 //! Initialize the trace file
383 /*!
384  * The trace file depends on an environment variable (DSC_TRACE). If this variable
385  * is equal to 1, the trace file is a file with the name : <TMPDIR>/<container name>.tce.
386  * In all other cases, the trace file is stderr
387  * The environment variable DSC_TRACELEVEL can be used to suppress the trace (value 0)
388  *
389  * \param containerName the name of the container where the trace is built
390  */
391 static void initTrace(const std::string& containerName)
392 {
393   // if initialization has already been done do nothing
394   if(traceLevel >= 0)return;
395
396   std::string typeenv="0";
397   std::string levelenv="1";
398   char* valenv=0;
399   valenv=getenv("DSC_TRACE");
400   if(valenv)typeenv=valenv;
401   valenv=getenv("DSC_TRACELEVEL");
402   if(valenv)levelenv=valenv;
403
404   if(levelenv=="0")
405     traceLevel=0; // no trace
406   else if(levelenv=="2")
407     traceLevel=2; //detailed trace
408   else
409     traceLevel=1; // normal trace (default)
410
411   if(traceLevel==0)
412     return;
413
414   if(typeenv=="1")
415     {
416       //trace in file
417       traceType=1;
418 #ifdef WIN32
419       std::string logFilename=getenv("TEMP");
420       logFilename += "\\";
421 #else
422       std::string logFilename="/tmp";
423       char* val = getenv("SALOME_TMP_DIR");
424       if(val)
425         {
426           struct stat file_info;
427           stat(val, &file_info);
428           bool is_dir = S_ISDIR(file_info.st_mode);
429           if (is_dir)logFilename=val;
430         }
431       logFilename += "/";
432 #endif
433
434       logFilename=logFilename+containerName+".tce";
435       traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
436       out=&traceFile;
437     }
438   else
439     {
440       //trace to stderr (default)
441       traceType=0;
442       out=&std::cerr;
443     }
444   //trace heading
445   out->width(17);
446   *out << "Elapsed time" ;
447   *out << " | " ;
448   out->width(16);
449   *out << "Request" ;
450   *out << " | " ;
451   out->width(16);
452   *out << "Container" ;
453   *out << " | " ;
454   out->width(16);
455   *out << "Instance" ;
456   *out << " | " ;
457   out->width(16);
458   *out << "Port" ;
459   *out << " | " ;
460   out->width(24);
461   *out << "Error";
462   *out << " | " ;
463   *out << "Infos" ;
464   *out << std::endl;
465 }
466
467
468 //! Write a record in the trace file
469 /*!
470  * \param request the name of the request executed
471  * \param containerName the name of the container where the request is executed
472  * \param instance_name the name of the component where the request is executed
473  * \param port_name the name of the port that is concerned
474  * \param error if an error has occured, a string that identifies the error
475  * \param message informations about error or about the request
476  */
477 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name, 
478                                        const char* port_name, const char* error, const char* message)
479 {
480   if(traceLevel < 0)
481     initTrace(containerName);
482   if(traceLevel == 0)return;
483
484 #ifdef WIN32
485 #else
486   struct timeval tv;
487   gettimeofday(&tv,0);
488   long tt0=tv.tv_sec/3600; //hours
489
490   if(traceType == 2)
491     {
492       //notifier (not used: salome notifier is now obsolete)
493       std::ostringstream msg;
494       msg.width(7);
495       msg << tt0 ;
496       msg << ":" ;
497       long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
498       msg.width(2);
499       msg << tt1 ;
500       msg << ":" ;
501       long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
502       msg.width(2);
503       msg << tt2 ;
504       msg << ":" ;
505       long tt3=tv.tv_usec/1000; //milliseconds
506       msg.width(3);
507       msg << tt3 ;
508       msg << " | " ;
509       msg.width(24);
510       msg << error;
511       msg << " | " ;
512       msg << message ;
513       //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
514     }
515   else
516     {
517       //cerr or file
518       out->width(7);
519       *out << tt0 ;
520       *out << ":" ;
521       long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
522       out->width(2);
523       *out << tt1 ;
524       *out << ":" ;
525       long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
526       out->width(2);
527       *out << tt2 ;
528       *out << ":" ;
529       long tt3=tv.tv_usec/1000; //milliseconds
530       out->width(3);
531       *out << tt3 ;
532       *out << " | " ;
533       out->width(16);
534       *out << request ;
535       *out << " | " ;
536       out->width(16);
537       *out << containerName ;
538       *out << " | " ;
539       out->width(16);
540       *out << instance_name ;
541       *out << " | " ;
542       out->width(16);
543       *out << port_name ;
544       *out << " | " ;
545       out->width(24);
546       *out << error;
547       *out << " | " ;
548       *out << message ;
549       *out << std::endl;
550     }
551 #endif
552 }
553