0027067: Avoid use of virtual methods for implementation of destructors in legacy...
[occt.git] / src / Interface / Interface_FileReaderTool.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14// dce 21/01/99 S3767 : Suppression of general messages
42cf5bc1 15
16#include <Interface_Check.hxx>
7fd59977 17#include <Interface_CheckFailure.hxx>
42cf5bc1 18#include <Interface_FileReaderData.hxx>
19#include <Interface_FileReaderTool.hxx>
20#include <Interface_GeneralLib.hxx>
7fd59977 21#include <Interface_GeneralModule.hxx>
42cf5bc1 22#include <Interface_InterfaceMismatch.hxx>
23#include <Interface_InterfaceModel.hxx>
24#include <Interface_Protocol.hxx>
25#include <Interface_ReaderLib.hxx>
7fd59977 26#include <Interface_ReaderModule.hxx>
42cf5bc1 27#include <Interface_ReportEntity.hxx>
28#include <Message.hxx>
7fd59977 29#include <Message_Messenger.hxx>
30#include <Message_Msg.hxx>
42cf5bc1 31#include <Standard_DomainError.hxx>
7fd59977 32#include <Standard_ErrorHandler.hxx>
33#include <Standard_Failure.hxx>
42cf5bc1 34#include <Standard_NoSuchObject.hxx>
35#include <Standard_OutOfRange.hxx>
36#include <Standard_Transient.hxx>
7fd59977 37#include <Standard_TypeMismatch.hxx>
42cf5bc1 38
57c28b61 39#ifdef _WIN32
7fd59977 40#include <OSD_Exception.hxx>
41#else
42#include <OSD_Signal.hxx>
43#endif
44#include <stdio.h>
45
46// MGE 16/06/98
47// To use Msg class
48#include <Message_Msg.hxx>
49// To use TCollectionHAsciiString
50#include <TCollection_HAsciiString.hxx>
51
52// Failure pour recuperer erreur en lecture fichier,
53// TypeMismatch pour message d erreur circonstancie (cas particulier important)
54
55
56// Gere le chargement d un Fichier, prealablement transforme en FileReaderData
57// (de la bonne norme), dans un Modele
58
59
60//=======================================================================
61//function : Interface_FileReaderTool
62//purpose :
63//=======================================================================
64
65Interface_FileReaderTool::Interface_FileReaderTool ()
66{
67 themessenger = Message::DefaultMessenger();
68 theerrhand = Standard_True;
69 thetrace = 1;
70 thenbrep0 = thenbreps = 0;
71}
72
73//=======================================================================
74//function : SetData
75//purpose :
76//=======================================================================
77
78void Interface_FileReaderTool::SetData(const Handle(Interface_FileReaderData)& reader,
79 const Handle(Interface_Protocol)& protocol)
80{
81 thereader = reader;
82 theproto = protocol;
83}
84
85
86//=======================================================================
87//function : Protocol
88//purpose :
89//=======================================================================
90
91Handle(Interface_Protocol) Interface_FileReaderTool::Protocol () const
92{
93 return theproto;
94}
95
96
97//=======================================================================
98//function : Data
99//purpose :
100//=======================================================================
101
102Handle(Interface_FileReaderData) Interface_FileReaderTool::Data () const
103{
104 return thereader;
105}
106
107
108//=======================================================================
109//function : SetModel
110//purpose :
111//=======================================================================
112
113void Interface_FileReaderTool::SetModel
114 (const Handle(Interface_InterfaceModel)& amodel)
115{
116 themodel = amodel;
117}
118
119
120//=======================================================================
121//function : Model
122//purpose :
123//=======================================================================
124
125Handle(Interface_InterfaceModel) Interface_FileReaderTool::Model () const
126{
127 return themodel;
128}
129
130//=======================================================================
131//function : SetMessenger
132//purpose :
133//=======================================================================
134
135void Interface_FileReaderTool::SetMessenger (const Handle(Message_Messenger)& messenger)
136{
137 if ( messenger.IsNull() )
138 themessenger = Message::DefaultMessenger();
139 else
140 themessenger = messenger;
141}
142
143//=======================================================================
144//function : Messenger
145//purpose :
146//=======================================================================
147
148Handle(Message_Messenger) Interface_FileReaderTool::Messenger () const
149{
150 return themessenger;
151}
152
153//=======================================================================
154//function : SetTraceLevel
155//purpose :
156//=======================================================================
157
158void Interface_FileReaderTool::SetTraceLevel (const Standard_Integer tracelev)
159{
160 thetrace = tracelev;
161}
162
163//=======================================================================
164//function : TraceLevel
165//purpose :
166//=======================================================================
167
168Standard_Integer Interface_FileReaderTool::TraceLevel () const
169{
170 return thetrace;
171}
172
173//=======================================================================
174//function : SetErrorHandle
175//purpose :
176//=======================================================================
177
178void Interface_FileReaderTool::SetErrorHandle(const Standard_Boolean err)
179{
180 theerrhand = err;
181}
182
183
184//=======================================================================
185//function : ErrorHandle
186//purpose :
187//=======================================================================
188
189Standard_Boolean Interface_FileReaderTool::ErrorHandle() const
190{
191 return theerrhand;
192}
193
194// .... Actions Connexes au CHARGEMENT DU MODELE ....
195
196// SetEntities fait appel a des methodes a fournir :
197// s appuyant sur un Recognizer adapte a l interface :
198// - Recognize fait reco->Evaluate(... : selon record no num)
199// et recupere le resultat
200// ainsi que la definition de l entite inconnue de l interface
201
202
203//=======================================================================
204//function : SetEntities
205//purpose :
206//=======================================================================
207
208void Interface_FileReaderTool::SetEntities ()
209{
210 Standard_Integer num;
211 thenbreps = 0; thenbrep0 = 0;
212
213 for (num = thereader->FindNextRecord(0); num > 0;
214 num = thereader->FindNextRecord(num)) {
215 Handle(Standard_Transient) newent;
216 Handle(Interface_Check) ach = new Interface_Check;
217 if (!Recognize (num,ach,newent)) {
218 newent = UnknownEntity();
219 if (thereports.IsNull()) thereports =
220 new TColStd_HArray1OfTransient (1,thereader->NbRecords());
221 thenbreps ++; thenbrep0 ++;
222 thereports->SetValue (num,new Interface_ReportEntity(ach,newent));
223 }
224 else if ((ach->NbFails() + ach->NbWarnings() > 0) && !newent.IsNull()) {
225 if (thereports.IsNull()) thereports =
226 new TColStd_HArray1OfTransient (1,thereader->NbRecords());
227 thenbreps ++; thenbrep0 ++;
228 thereports->SetValue (num,new Interface_ReportEntity(ach,newent));
229 }
230 thereader->BindEntity (num,newent);
231 }
232}
233
234
235//=======================================================================
236//function : RecognizeByLib
237//purpose :
238//=======================================================================
239
240Standard_Boolean Interface_FileReaderTool::RecognizeByLib(const Standard_Integer num,
241 Interface_GeneralLib& glib,
242 Interface_ReaderLib& rlib,
243 Handle(Interface_Check)& ach,
244 Handle(Standard_Transient)& ent) const
245{
246 Handle(Interface_GeneralModule) gmod;
247 Handle(Interface_ReaderModule) rmod;
248 Handle(Interface_Protocol) proto;
249 Standard_Integer CN = 0;
250// Chercher dans ReaderLib : Reconnaissance de cas -> CN , proto
251 for (rlib.Start(); rlib.More(); rlib.Next()) {
252 rmod = rlib.Module();
253 if (rmod.IsNull()) continue;
254 CN = rmod->CaseNum(thereader,num);
255 if (CN > 0) { proto = rlib.Protocol(); break; }
256 }
257 if (CN <= 0 || proto.IsNull()) return Standard_False;
258// Se recaler dans GeneralLib : Creation de l entite vide
259 Handle(Standard_Type) typrot = proto->DynamicType();
260 for (glib.Start(); glib.More(); glib.Next()) {
261 proto = glib.Protocol();
262 if (proto.IsNull()) continue;
263 if (proto->DynamicType() != typrot) continue;
264 Standard_Boolean res = glib.Module()->NewVoid(CN,ent);
265 if (res) return res;
266 if (!rmod.IsNull()) return rmod->NewRead (CN,thereader,num,ach,ent);
267// return res;
268 }
269 return Standard_False;
270}
271
272
273//=======================================================================
274//function : UnknownEntity
275//purpose :
276//=======================================================================
277
278Handle(Standard_Transient) Interface_FileReaderTool::UnknownEntity() const
279{
280 return theproto->UnknownEntity();
281}
282
283
284//=======================================================================
285//function : NewModel
286//purpose :
287//=======================================================================
288
289Handle(Interface_InterfaceModel) Interface_FileReaderTool::NewModel() const
290{
291 return theproto->NewModel();
292}
293
294
295//=======================================================================
296//function : EndRead
297//purpose :
298//=======================================================================
299
300void Interface_FileReaderTool::EndRead(const Handle(Interface_InterfaceModel)& )
301{
302} // par defaut, ne fait rien; redefinissable selon besoin
303
304
305// .... (Sa Majeste le) CHARGEMENT DU MODELE ....
306
307
308//=======================================================================
309//function : LoadModel
310//purpose :
311//=======================================================================
312
313void Interface_FileReaderTool::LoadModel
314 (const Handle(Interface_InterfaceModel)& amodel)
315//
316// Methode generale de lecture d un fichier : il est lu via un FileReaderData
317// qui doit y donner acces de la facon la plus performante possible
318// chaque interface definit son FileHeader avec ses methodes, appelees ici
319{
320 // MGE 16/06/98
321 // Building of Messages
322 //====================================
323 Handle(Message_Messenger) TF = Messenger();
324 //====================================
325 Handle(Interface_Check) ach = new Interface_Check;
326
327 SetModel(amodel);
328
329// .. Demarrage : Lecture du Header ..
330 if (theerrhand) {
331 try {
332 OCC_CATCH_SIGNALS
333 BeginRead(amodel); // selon la norme
334 }
335 catch (Standard_Failure) {
336 // Sendinf of message : Internal error during the header reading
337 Message_Msg Msg11("XSTEP_11");
338 TF->Send (Msg11, Message_Info);
339 }
340 }
341 else
342 BeginRead(amodel); // selon la norme
343
344 // .. Lecture des Entites ..
345
346 amodel->Reservate (thereader->NbEntities());
347
348 Standard_Integer num, num0 = thereader->FindNextRecord(0);
349 num = num0;
350
351 while (num > 0) {
352 Standard_Integer ierr = 0; // erreur sur analyse d une entite
353 Handle(Standard_Transient) anent;
354 try {
355 OCC_CATCH_SIGNALS
356 for (num = num0; num > 0; num = thereader->FindNextRecord(num)) {
357 num0 = num;
358
359 // Lecture sous protection contre crash
360 // (fait aussi AddEntity mais pas SetReportEntity)
361 anent = LoadedEntity(num);
362
363 // Lecture non protegee : utile pour travailler avec dbx
364//// else
365//// anent = LoadedEntity(num);
366
367 // .. Fin Lecture ..
368 if (anent.IsNull()) {
369 // Sending of message : Number of ignored Null Entities
370 Message_Msg Msg21("XSTEP_21");
371 Msg21.Arg(amodel->NbEntities());
372 TF->Send (Msg21, Message_Info);
373 continue;
374 }
375 // LoadedEntity fait AddEntity MAIS PAS SetReport (en bloc a la fin)
376
377 } // ---- fin boucle sur entites
378 num0 = 0; // plus rien
379 } // ---- fin du try, le catch suit
380
381 // En cas d erreur NON PREVUE par l analyse, recuperation par defaut
382 // Attention : la recuperation peut elle-meme planter ... (cf ierr)
383 catch (Standard_Failure) {
384 // Au passage suivant, on attaquera le record suivant
385 num0 = thereader->FindNextRecord(num); //:g9 abv 28 May 98: tr8_as2_ug.stp - infinite cycle: (0);
386
387 Handle(Standard_Failure) afail = Standard_Failure::Caught();
57c28b61 388#ifdef _WIN32
7fd59977 389 if (afail.IsNull() || afail->IsKind(STANDARD_TYPE(OSD_Exception))) ierr = 2;
390#else
391 if (afail.IsNull() || afail->IsKind(STANDARD_TYPE(OSD_Signal))) ierr = 2;
392#endif
393//:abv 03Apr00: anent is actually a previous one: if (anent.IsNull())
394 anent = thereader->BoundEntity(num);
395 if (anent.IsNull()) {
396 if (thetrace > 0)
397 {
398 // Sending of message : Number of ignored Null Entities
399 Message_Msg Msg21("XSTEP_21");
400 Msg21.Arg(amodel->NbEntities()+1);
401 TF->Send (Msg21, Message_Info);
402 continue;
403 }
404 }
405 /*Handle(Interface_Check)*/ ach = new Interface_Check(anent);
406 //: abv 03 Apr 00: trj3_s1-tc-214.stp: generate a message on exception
407 Message_Msg Msg278("XSTEP_278");
408 Msg278.Arg(amodel->StringLabel(anent));
409 ach->SendFail (Msg278);
410
411 if (ierr == 2) {
412 // Sending of message : reading of entity failed
413 Message_Msg Msg22("XSTEP_22");
414 Msg22.Arg(amodel->StringLabel(anent));
415 TF->Send (Msg22, Message_Info);
416 return;
417 }
418
419 if (!ierr) {
420 //char mess[100]; svv #2
421 ierr = 1;
422// ce qui serait bien ici serait de recuperer le texte de l erreur pour ach ...
423 if (thetrace > 0) {
424 // Sending of message : recovered entity
425 Message_Msg Msg23("XSTEP_23");
426 Msg23.Arg(num);
427 TF->Send (Msg23, Message_Info);
428 }
429
430// Finalement, on charge une Entite Inconnue
431 thenbreps ++;
432 Handle(Interface_ReportEntity) rep =
433 new Interface_ReportEntity(ach,anent);
434 Handle(Standard_Transient) undef = UnknownEntity();
435 AnalyseRecord(num,undef,ach);
436 rep->SetContent(undef);
437
438 if (thereports.IsNull()) thereports =
439 new TColStd_HArray1OfTransient (1,thereader->NbRecords());
440 thenbreps ++;
441 thereports->SetValue (num,rep);
442 //if(isValid)
443 amodel->AddEntity (anent); // pas fait par LoadedEntity ...
444 }
445 else {
446 if (thetrace > 0) {
447 // Sending of message : reading of entity failed
448 Message_Msg Msg22("XSTEP_22");
449 Msg22.Arg(amodel->StringLabel(anent));
450 TF->Send (Msg22, Message_Info);
451 }
452// On garde <rep> telle quelle : pas d analyse fichier supplementaire,
453// Mais la phase preliminaire eventuelle est conservee
454// (en particulier, on garde trace du Type lu du fichier, etc...)
455 }
456 } // ----- fin complete du try/catch
457 } // ----- fin du while
458
459// .. Ajout des Reports, silya
460 if (!thereports.IsNull()) {
461 if (thetrace > 0)
462 {
463 // Sending of message : report
464 Message_Msg Msg24("XSTEP_24");
465 Msg24.Arg(thenbreps);
466 TF->Send (Msg24, Message_Info);
467 }
468 amodel->Reservate (-thenbreps-10);
469 thenbreps = thereports->Upper();
470 for (Standard_Integer nr = 1; nr <= thenbreps; nr ++) {
471 if (thereports->Value(nr).IsNull()) continue;
472 Handle(Standard_Transient) anent = thereader->BoundEntity (nr);
473 Handle(Interface_ReportEntity) rep =
474 Handle(Interface_ReportEntity)::DownCast(thereports->Value(nr));
475 amodel->SetReportEntity (-amodel->Number(anent),rep);
476 }
477 }
478
479// Conclusion : peut ne rien faire : selon necessite
480 if (theerrhand) {
481 try {
482 OCC_CATCH_SIGNALS
483 EndRead(amodel); // selon la norme
484 }
485 catch (Standard_Failure) {
486 // Sendinf of message : Internal error during the header reading
487 Message_Msg Msg11("XSTEP_11");
488 TF->Send (Msg11, Message_Info);
489 }
490 }
491 else
492 EndRead(amodel); // selon la norme
493}
494
495
496//=======================================================================
497//function : LoadedEntity
498//purpose :
499//=======================================================================
500
501Handle(Standard_Transient) Interface_FileReaderTool::LoadedEntity
502 (const Standard_Integer num)
503{
504 Handle(Standard_Transient) anent = thereader->BoundEntity(num);
505 Handle(Interface_Check) ach = new Interface_Check(anent);
506 Handle(Interface_ReportEntity) rep; // entite Report, s il y a lieu
507 Standard_Integer irep = 0;
508 //Standard_Integer nbe = 0; svv #2
509 if (thenbrep0 > 0) {
510 rep = Handle(Interface_ReportEntity)::DownCast(thereports->Value(num));
511 if (!rep.IsNull()) { irep = num; ach = rep->Check(); }
512 }
513
514// Trace Entite Inconnue
515 if (thetrace >= 2 && theproto->IsUnknownEntity(anent)) {
516 Handle(Message_Messenger) TF = Messenger();
517 Message_Msg Msg22("XSTEP_22");
518 // Sending of message : reading of entity failed
519 Msg22.Arg(themodel->StringLabel(anent)->String());
520 TF->Send (Msg22, Message_Info);
521 }
522// .. Chargement proprement dit : Specifique de la Norme ..
523 AnalyseRecord(num,anent,ach);
524
525// .. Ajout dans le modele de l entite telle quelle ..
526// ATTENTION, ReportEntity traitee en bloc apres les Load
527 themodel->AddEntity(anent);
528
529// Erreur ou Correction : On cree une ReportEntity qui memorise le Check,
530// l Entite, et en cas d Erreur une UndefinedEntity pour les Parametres
531
532// On exploite ici le flag IsLoadError : s il a ete defini (a vrai ou faux)
533// il a priorite sur les fails du check. Sinon, ce sont les fails qui parlent
534
535 Standard_Integer nbf = ach->NbFails();
536 Standard_Integer nbw = ach->NbWarnings();
537 if (nbf + nbw > 0) {
538 //Standard_Integer n0; svv #2
539 themodel->NbEntities();
540 rep = new Interface_ReportEntity(ach,anent);
541 if (irep == 0) {
542 if (thereports.IsNull()) thereports =
543 new TColStd_HArray1OfTransient (1,thereader->NbRecords());
544 irep = num;
545 thenbreps ++;
546 }
547 thereports->SetValue(irep,rep);
548
549 if ( thetrace >= 2)
550 ach->Print (Messenger(),2);
551 }
552
553// Rechargement ? si oui, dans une UnknownEntity fournie par le protocole
554 if (thereader->IsErrorLoad()) nbf = (thereader->ResetErrorLoad() ? 1 : 0);
555 if (nbf > 0) {
556 Handle(Standard_Transient) undef = UnknownEntity();
557 AnalyseRecord(num,undef,ach);
558 rep->SetContent(undef);
559 }
560
561// Conclusion (Unknown : traite en externe because traitement Raise)
562//// if (irep > 0) themodel->SetReportEntity (nbe,rep); en bloc a la fin
563
564 return anent;
565}
566
567
568//=======================================================================
e6f550da 569//function : ~Interface_FileReaderTool
7fd59977 570//purpose :
571//=======================================================================
572
e6f550da 573Interface_FileReaderTool::~Interface_FileReaderTool()
bc650d41 574{}
7fd59977 575
bc650d41
G
576void Interface_FileReaderTool::Clear()
577{
578 theproto.Nullify();
579 thereader.Nullify();
580 themodel.Nullify();
581 thereports.Nullify();
973c2be1 582}