0031004: Coding - eliminate warnings issued by gcc 9.1.0
[occt.git] / src / StepData / StepData_StepWriter.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// List of changes:
15//skl 29.01.2003 - deleted one space symbol at the begining
16// of strings from Header Section
7fd59977 17
7fd59977 18#include <Interface_Check.hxx>
42cf5bc1 19#include <Interface_CheckIterator.hxx>
20#include <Interface_EntityIterator.hxx>
21#include <Interface_FloatWriter.hxx>
7fd59977 22#include <Interface_InterfaceMismatch.hxx>
7fd59977 23#include <Interface_Macros.hxx>
42cf5bc1 24#include <Interface_ReportEntity.hxx>
25#include <Standard_NoSuchObject.hxx>
26#include <Standard_Transient.hxx>
27#include <StepData_ESDescr.hxx>
28#include <StepData_Field.hxx>
29#include <StepData_FieldList.hxx>
30#include <StepData_PDescr.hxx>
31#include <StepData_Protocol.hxx>
32#include <StepData_ReadWriteModule.hxx>
33#include <StepData_SelectArrReal.hxx>
34#include <StepData_SelectMember.hxx>
35#include <StepData_StepModel.hxx>
36#include <StepData_StepWriter.hxx>
37#include <StepData_UndefinedEntity.hxx>
38#include <StepData_WriterLib.hxx>
39#include <TCollection_AsciiString.hxx>
40#include <TCollection_HAsciiString.hxx>
7fd59977 41
42cf5bc1 42#include <stdio.h>
7fd59977 43#define StepLong 72
44// StepLong : longueur maxi d une ligne de fichier Step
45
46
47// Constantes litterales (interessantes, pour les performances ET LA MEMOIRE)
48
49static TCollection_AsciiString textscope (" &SCOPE");
50static TCollection_AsciiString textendscope (" ENDSCOPE");
51static TCollection_AsciiString textcomm (" /* ");
52static TCollection_AsciiString textendcomm (" */");
53static TCollection_AsciiString textlist ("(");
54static TCollection_AsciiString textendlist (")");
55static TCollection_AsciiString textendent (");");
56static TCollection_AsciiString textparam (",");
57static TCollection_AsciiString textundef ("$");
58static TCollection_AsciiString textderived ("*");
59static TCollection_AsciiString texttrue (".T.");
60static TCollection_AsciiString textfalse (".F.");
61static TCollection_AsciiString textunknown (".U.");
62
63
64
65//=======================================================================
66//function : StepData_StepWriter
67//purpose :
68//=======================================================================
69
70StepData_StepWriter::StepData_StepWriter(const Handle(StepData_StepModel)& amodel)
71 : thecurr (StepLong) , thefloatw (12)
72{
73 themodel = amodel; thelabmode = thetypmode = 0;
74 thefile = new TColStd_HSequenceOfHAsciiString();
75 thesect = Standard_False; thefirst = Standard_True;
76 themult = Standard_False; thecomm = Standard_False;
77 thelevel = theindval = 0; theindent = Standard_False;
78// Format flottant : reporte dans le FloatWriter
79}
80
81// .... Controle d Envoi des Flottants ....
82
83//=======================================================================
84//function : FloatWriter
85//purpose :
86//=======================================================================
87
88Interface_FloatWriter& StepData_StepWriter::FloatWriter ()
89{ return thefloatw; } // s y reporter
90
91
92//=======================================================================
93//function : LabelMode
94//purpose :
95//=======================================================================
96
97Standard_Integer& StepData_StepWriter::LabelMode ()
98{ return thelabmode; }
99
100
101//=======================================================================
102//function : TypeMode
103//purpose :
104//=======================================================================
105
106Standard_Integer& StepData_StepWriter::TypeMode ()
107{ return thetypmode; }
108
109// .... Description des Scopes (AVANT Envoi) ....
110
111
112//=======================================================================
113//function : SetScope
114//purpose :
115//=======================================================================
116
117void StepData_StepWriter::SetScope (const Standard_Integer numscope,
118 const Standard_Integer numin)
119{
120 Standard_Integer nb = themodel->NbEntities();
121 if (numscope <= 0 || numscope > nb || numin <= 0 || numin > nb)
9775fa61 122 throw Interface_InterfaceMismatch("StepWriter : SetScope, out of range");
7fd59977 123 if (thescopenext.IsNull()) {
124 thescopebeg = new TColStd_HArray1OfInteger (1,nb); thescopebeg->Init(0);
125 thescopeend = new TColStd_HArray1OfInteger (1,nb); thescopeend->Init(0);
126 thescopenext = new TColStd_HArray1OfInteger (1,nb); thescopenext->Init(0);
127 }
128 else if (thescopenext->Value(numin) != 0) {
0797d9d3 129#ifdef OCCT_DEBUG
04232180 130 std::cout << "StepWriter : SetScope (scope : " << numscope << " entity : "
131 << numin << "), Entity already in a Scope"<<std::endl;
7fd59977 132#endif
9775fa61 133 throw Interface_InterfaceMismatch("StepWriter : SetScope, already set");
7fd59977 134 }
135 thescopenext->SetValue(numin,-1); // nouvelle fin de scope
136 if (thescopebeg->Value(numscope) == 0) thescopebeg->SetValue(numscope,numin);
137 Standard_Integer lastin = thescopeend->Value(numscope);
138 if (lastin > 0) thescopenext->SetValue(lastin,numin);
139 thescopeend->SetValue(numscope,numin);
140}
141
142
143//=======================================================================
144//function : IsInScope
145//purpose :
146//=======================================================================
147
148Standard_Boolean StepData_StepWriter::IsInScope(const Standard_Integer num) const
149{
150 if (thescopenext.IsNull()) return Standard_False;
151 return (thescopenext->Value(num) != 0);
152}
153
154// ###########################################################################
155// ## ## ## ## ENVOI DES SECTIONS ## ## ## ##
156
157// .... Envoi du Modele Complet ....
158
159
160//=======================================================================
161//function : SendModel
162//purpose :
163//=======================================================================
164
165void StepData_StepWriter::SendModel(const Handle(StepData_Protocol)& protocol,
166 const Standard_Boolean headeronly)
167{
168 StepData_WriterLib lib(protocol);
169
170 if (!headeronly)
171 thefile->Append (new TCollection_HAsciiString("ISO-10303-21;"));
172 SendHeader();
173
174// .... Header : suite d entites sans Ident ....
175
176 Interface_EntityIterator header = themodel->Header();
177 thenum = 0;
178 for (header.Start(); header.More(); header.Next()) {
179 Handle(Standard_Transient) anent = header.Value();
180
181// Write Entity via Lib (similaire a SendEntity)
182 Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
183 if (lib.Select(anent,module,CN)) {
184 if (module->IsComplex(CN)) StartComplex();
185 else {
186 TCollection_AsciiString styp;
187 if (thetypmode > 0) styp = module->ShortType(CN);
188 if (styp.Length() == 0) styp = module->StepType(CN);
189 StartEntity (styp);
190 }
191 module->WriteStep(CN,*this,anent);
192 if (module->IsComplex(CN)) EndComplex();
193 } else {
194// Pas trouve ci-dessus ... tenter UndefinedEntity
195 DeclareAndCast(StepData_UndefinedEntity,und,anent);
196 if (und.IsNull()) continue;
197 if (und->IsComplex()) StartComplex();
198 und->WriteParams(*this);
199 if (und->IsComplex()) EndComplex();
200 }
201 EndEntity ();
202 }
203 EndSec();
204 if (headeronly) return;
205
206// Data : Comme Header mais avec des Idents ... sinon le code est le meme
207 SendData();
208
209// .... Erreurs Globales (silya) ....
210
211 Handle(Interface_Check) achglob = themodel->GlobalCheck();
212 Standard_Integer nbfails = achglob->NbFails();
213 if (nbfails > 0) {
214 Comment(Standard_True);
215 SendComment("GLOBAL FAIL MESSAGES, recorded at Read time :");
216 for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
217 SendComment (achglob->Fail(ifail));
218 }
219 Comment(Standard_False);
220 NewLine(Standard_False);
221 }
222
223// .... Sortie des Entites une par une ....
224
225 Standard_Integer nb = themodel->NbEntities();
226 for (Standard_Integer i = 1 ; i <= nb; i ++) {
227// Liste principale : on n envoie pas les Entites dans un Scope
228// Elles le seront par l intermediaire du Scope qui les contient
229 if (!thescopebeg.IsNull()) { if (thescopenext->Value(i) != 0) continue; }
230 SendEntity (i,lib);
231 }
232
233 EndSec();
234 EndFile();
235}
236
237
238// .... DECOUPAGE DU FICHIER EN SECTIONS ....
239
240
241//=======================================================================
242//function : SendHeader
243//purpose :
244//=======================================================================
245
246void StepData_StepWriter::SendHeader ()
247{
248 NewLine(Standard_False);
249 thefile->Append (new TCollection_HAsciiString("HEADER;"));
250 thesect = Standard_True;
251}
252
253
254//=======================================================================
255//function : SendData
256//purpose :
257//=======================================================================
258
259void StepData_StepWriter::SendData ()
260{
9775fa61 261 if (thesect) throw Interface_InterfaceMismatch("StepWriter : Data section");
7fd59977 262 NewLine(Standard_False);
263 thefile->Append (new TCollection_HAsciiString("DATA;"));
264 thesect = Standard_True;
265}
266
267
268//=======================================================================
269//function : EndSec
270//purpose :
271//=======================================================================
272
273void StepData_StepWriter::EndSec ()
274{
275 thefile->Append (new TCollection_HAsciiString("ENDSEC;"));
276 thesect = Standard_False;
277}
278
279
280//=======================================================================
281//function : EndFile
282//purpose :
283//=======================================================================
284
285void StepData_StepWriter::EndFile ()
286{
9775fa61 287 if (thesect) throw Interface_InterfaceMismatch("StepWriter : EndFile");
7fd59977 288 NewLine(Standard_False);
289 thefile->Append (new TCollection_HAsciiString("END-ISO-10303-21;"));
290 thesect = Standard_False;
291}
292
293// .... ENVOI D UNE ENTITE ....
294
295
296//=======================================================================
297//function : SendEntity
298
299//purpose :
300//=======================================================================
301
302void StepData_StepWriter::SendEntity(const Standard_Integer num,
303 const StepData_WriterLib& lib)
304{
305 char lident[20];
306 Handle(Standard_Transient) anent = themodel->Entity(num);
307 Standard_Integer idnum = num , idtrue = 0;
308
309 // themodel->Number(anent) et-ou IdentLabel(anent)
310 if (thelabmode > 0) idtrue = themodel->IdentLabel(anent);
311 if (thelabmode == 1) idnum = idtrue;
312 if (idnum == 0) idnum = num;
313 if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d = ",idnum); //skl 29.01.2003
314 else sprintf(lident,"%d:#%d = ",idnum,idtrue); //skl 29.01.2003
315
316// SendIdent repris , lident vient d etre calcule
317 thecurr.Clear();
318 thecurr.Add (lident);
319 themult = Standard_False;
320
321// .... Traitement du Scope Eventuel
322 if (!thescopebeg.IsNull()) {
323 Standard_Integer numin = thescopebeg->Value(num);
324 if (numin != 0) {
325 SendScope();
326 for (Standard_Integer nument = numin; numin > 0; nument = numin) {
327 SendEntity(nument,lib);
328 numin = thescopenext->Value(nument);
329 }
330 SendEndscope();
331 }
332 }
333
334// .... Envoi de l Entite proprement dite
335
336// Write Entity via Lib
337 thenum = num;
338 Handle(StepData_ReadWriteModule) module; Standard_Integer CN;
339 if (themodel->IsRedefinedContent(num)) {
340// Entite Erreur : Ecrire le Contenu + les Erreurs en Commentaires
341 Handle(Interface_ReportEntity) rep = themodel->ReportEntity(num);
342 DeclareAndCast(StepData_UndefinedEntity,und,rep->Content());
343 if (und.IsNull()) {
344 thechecks.CCheck(num)->AddFail("Erroneous Entity, Content lost");
345 StartEntity(TCollection_AsciiString("!?LOST_DATA"));
346 } else {
347 thechecks.CCheck(num)->AddWarning("Erroneous Entity, equivalent content");
348 if (und->IsComplex()) AddString(" (",2);
349 und->WriteParams(*this);
350 if (und->IsComplex()) { AddString(") ",2); } //thelevel --; }
351 }
352 EndEntity (); // AVANT les Commentaires
353 NewLine(Standard_False);
354 Comment(Standard_True);
355 if (und.IsNull()) SendComment(" ERRONEOUS ENTITY, DATA LOST");
356 SendComment("On Entity above, Fail Messages recorded at Read time :");
357 Handle(Interface_Check) ach = rep->Check();
358 Standard_Integer nbfails = ach->NbFails();
359 for (Standard_Integer ifail = 1; ifail <= nbfails; ifail ++) {
360 SendComment (ach->Fail(ifail));
361 }
362 Comment(Standard_False);
363 NewLine(Standard_False);
364
365// Cas normal
366 }
367 else if (lib.Select(anent,module,CN)) {
368 if (module->IsComplex(CN)) StartComplex();
369 else {
370 TCollection_AsciiString styp;
371 if (thetypmode > 0) styp = module->ShortType(CN);
372 if (styp.Length() == 0) styp = module->StepType(CN);
373 StartEntity (styp);
374 }
375 module->WriteStep(CN,*this,anent);
376 if (module->IsComplex(CN)) EndComplex();
377 EndEntity ();
378 }
379 else {
380 // Pas trouve ci-dessus ... tenter UndefinedEntity
381 DeclareAndCast(StepData_UndefinedEntity,und,anent);
382 if (und.IsNull()) return;
383 if (und->IsComplex()) StartComplex();
384 und->WriteParams(*this);
385 if (und->IsComplex()) EndComplex();
386 EndEntity ();
387 }
388}
389
390// ###########################################################################
391// ## ## ## CONSTITUTION DU TEXTE A ENVOYER ## ## ##
392
393// Passer a la ligne. Ligne vide pas comptee sauf si evenempty == Standard_True
394
395
396//=======================================================================
397//function : NewLine
398//purpose :
399//=======================================================================
400
401void StepData_StepWriter::NewLine (const Standard_Boolean evenempty)
402{
403 if (evenempty || thecurr.Length() > 0) {
404 thefile->Append(thecurr.Moved());
405 }
406 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
407 thecurr.SetInitial(indst); thecurr.Clear();
408}
409
410
411// Regrouper ligne en cours avec precedente; reste en cours sauf si newline
412// == Standard_True, auquel cas on commence une nouvelle ligne
413// Ne fait rien si : total correspondant > StepLong ou debut ou fin d`entite
414
415
416//=======================================================================
417//function : JoinLast
418//purpose :
419//=======================================================================
420
35e08fe8 421void StepData_StepWriter::JoinLast (const Standard_Boolean)
7fd59977 422{
7fd59977 423 thecurr.SetKeep();
424}
425
426
427//=======================================================================
428//function : Indent
429//purpose :
430//=======================================================================
431
432void StepData_StepWriter::Indent (const Standard_Boolean onent)
433{ theindent = onent; }
434
435
436//=======================================================================
437//function : SendIdent
438//purpose :
439//=======================================================================
440
441void StepData_StepWriter::SendIdent(const Standard_Integer ident)
442{
443 char lident[12];
444 sprintf(lident,"#%d =",ident);
445 thecurr.Clear();
446 thecurr.Add (lident);
447 themult = Standard_False;
448}
449
450
451//=======================================================================
452//function : SendScope
453//purpose :
454//=======================================================================
455
456void StepData_StepWriter::SendScope ()
457{ AddString(textscope); }
458
459
460//=======================================================================
461//function : SendEndscope
462//purpose :
463//=======================================================================
464
465void StepData_StepWriter::SendEndscope ()
466{
467 NewLine(Standard_False);
468 thefile->Append(new TCollection_HAsciiString(textendscope));
469}
470
471
472//=======================================================================
473//function : Comment
474//purpose :
475//=======================================================================
476
477void StepData_StepWriter::Comment (const Standard_Boolean mode)
478{
479 if (mode && !thecomm) AddString(textcomm,20);
480 if (!mode && thecomm) AddString(textendcomm);
481 thecomm = mode;
482}
483
484
485//=======================================================================
486//function : SendComment
487//purpose :
488//=======================================================================
489
490void StepData_StepWriter::SendComment(const Handle(TCollection_HAsciiString)& text)
491{
9775fa61 492 if (!thecomm) throw Interface_InterfaceMismatch("StepWriter : Comment");
7fd59977 493 AddString(text->ToCString(),text->Length());
494}
495
496
497//=======================================================================
498//function : SendComment
499//purpose :
500//=======================================================================
501
502void StepData_StepWriter::SendComment (const Standard_CString text)
503{
9775fa61 504 if (!thecomm) throw Interface_InterfaceMismatch("StepWriter : Comment");
60be1f9b 505 AddString(text,(Standard_Integer) strlen(text));
7fd59977 506}
507
508
509//=======================================================================
510//function : StartEntity
511//purpose :
512//=======================================================================
513
514void StepData_StepWriter::StartEntity(const TCollection_AsciiString& atype)
515{
516 if (atype.Length() == 0) return;
517 if (themult) {
9775fa61 518 if (thelevel != 1) throw Interface_InterfaceMismatch("StepWriter : StartEntity"); // decompte de parentheses mauvais ...
7fd59977 519 AddString(textendlist);
520 AddString(" ",1); //skl 29.01.2003
521 }
522 themult = Standard_True;
523 //AddString(" ",1); //skl 29.01.2003
524 AddString(atype);
525 thelevel = 0;
526 theindval = thecurr.Length();
527 thecurr.SetInitial(0);
528 thefirst = Standard_True;
529 OpenSub();
530}
531
532
533//=======================================================================
534//function : StartComplex
535//purpose :
536//=======================================================================
537
538void StepData_StepWriter::StartComplex ()
539{
540 AddString("( ",2); //skl 29.01.2003
541} // thelevel unchanged
542
543
544//=======================================================================
545//function : EndComplex
546//purpose :
547//=======================================================================
548
549void StepData_StepWriter::EndComplex ()
550{ AddString(") ",2); } // thelevel unchanged
551
552
553// .... SendField et ce qui va avec
554
555
556//=======================================================================
557//function : SendField
558//purpose :
559//=======================================================================
560
561void StepData_StepWriter::SendField(const StepData_Field& fild,
562 const Handle(StepData_PDescr)& descr)
563{
564 Standard_Boolean done = Standard_True;
565 Standard_Integer kind = fild.Kind (Standard_False); // valeur interne
566
567 if (kind == 16) {
568 DeclareAndCast(StepData_SelectMember,sm,fild.Transient());
569 SendSelect (sm,descr);
570 return;
571 }
572 switch (kind) {
573// ici les cas simples; ensuite on caste et on voit
574 case 0 : SendUndef(); break;
575 case 1 : Send (fild.Integer ()); break;
576 case 2 : SendBoolean (fild.Boolean ()); break;
577 case 3 : SendLogical (fild.Logical ()); break;
578 case 4 : SendEnum (fild.EnumText ()); break; // enum : descr ?
579 case 5 : Send (fild.Real ()); break;
580 case 6 : Send (fild.String ()); break;
581 case 7 : Send (fild.Entity ()); break;
582 case 8 : done = Standard_False; break;
583 case 9 : SendDerived (); break;
584 default: done = Standard_False; break;
585 }
586 if (done) return;
587
588// Que reste-t-il : les tableaux ...
589 Standard_Integer arity = fild.Arity();
590 if (arity == 0) { SendUndef(); return; } // PAS NORMAL
591 if (arity == 1) {
592 OpenSub();
593 Standard_Integer i,low = fild.Lower(), up = low + fild.Length() - 1;
594 for (i = low; i <= up; i ++) {
595 kind = fild.ItemKind(i);
596 done = Standard_True;
597 switch (kind) {
598 case 0 : SendUndef(); break;
599 case 1 : Send (fild.Integer (i)); break;
600 case 2 : SendBoolean (fild.Boolean (i)); break;
601 case 3 : SendLogical (fild.Logical (i)); break;
602 case 4 : SendEnum (fild.EnumText (i)); break;
603 case 5 : Send (fild.Real (i)); break;
604 case 6 : Send (fild.String (i)); break;
605 case 7 : Send (fild.Entity (i)); break;
606 default: SendUndef(); done = Standard_False; break; // ANORMAL
607 }
608 }
609 CloseSub();
610 return;
611 }
612 if (arity == 2) {
613 OpenSub();
614 Standard_Integer j,low1 = fild.Lower(1), up1 = low1 + fild.Length(1) - 1;
615 for (j = low1; j <= up1; j ++) {
616 Standard_Integer i=0,low2 = fild.Lower(2), up2 = low2 + fild.Length(2) - 1;
617 OpenSub();
618 for (i = low2; i <= up2; i ++) {
619 kind = fild.ItemKind(i,j);
620 done = Standard_True;
621 switch (kind) {
622 case 0 : SendUndef(); break;
623 case 1 : Send (fild.Integer (i,j)); break;
624 case 2 : SendBoolean (fild.Boolean (i,j)); break;
625 case 3 : SendLogical (fild.Logical (i,j)); break;
626 case 4 : SendEnum (fild.EnumText (i,j)); break;
627 case 5 : Send (fild.Real (i,j)); break;
628 case 6 : Send (fild.String (i,j)); break;
629 case 7 : Send (fild.Entity (i,j)); break;
630 default: SendUndef(); done = Standard_False; break; // ANORMAL
631 }
632 }
633 CloseSub();
634 }
635 CloseSub();
636 return;
637 }
638}
639
640
641//=======================================================================
642//function : SendSelect
643//purpose :
644//=======================================================================
645
646void StepData_StepWriter::SendSelect(const Handle(StepData_SelectMember)& sm,
35e08fe8 647 const Handle(StepData_PDescr)& /*descr*/)
7fd59977 648{
649 // Cas du SelectMember. Traiter le Select puis la valeur
650 // NB : traitement actuel non recursif (pas de SELNAME(SELNAME(..)) )
651 Standard_Boolean selname = Standard_False;
652 if (sm.IsNull()) return; // ??
653 if (sm->HasName()) {
654 selname = Standard_True;
655 // SendString (sm->Name());
656 // AddString(textlist); // SANS AJOUT DE PARAMETRE !!
657 OpenTypedSub (sm->Name());
658 }
659 Standard_Integer kind = sm->Kind();
660 switch (kind) {
661 case 0 : SendUndef(); break;
662 case 1 : Send (sm->Integer ()); break;
663 case 2 : SendBoolean (sm->Boolean ()); break;
664 case 3 : SendLogical (sm->Logical ()); break;
665 case 4 : SendEnum (sm->EnumText ()); break; // enum : descr ?
666 case 5 : Send (sm->Real ()); break;
667 case 6 : Send (sm->String ()); break;
668 case 8 : SendArrReal (Handle(StepData_SelectArrReal)::DownCast(sm)->ArrReal()); break;
669 default: break; // ??
670 }
671 if (selname) CloseSub();
672}
673
674
675//=======================================================================
676//function : SendList
677//purpose :
678//=======================================================================
679
680void StepData_StepWriter::SendList(const StepData_FieldList& list,
681 const Handle(StepData_ESDescr)& descr)
682{
683// start entity ?
684 Standard_Integer i, nb = list.NbFields();
685 for (i = 1; i <= nb; i ++) {
686 Handle(StepData_PDescr) pde;
687 if (!descr.IsNull()) pde = descr->Field(i);
688 const StepData_Field fild = list.Field(i);
689 SendField (fild,pde);
690 }
691// end entity ?
692}
693
694// .... Send* de base
695
696
697//=======================================================================
698//function : OpenSub
699//purpose :
700//=======================================================================
701
702void StepData_StepWriter::OpenSub ()
703{
704 AddParam();
705 AddString(textlist);
706 thefirst = Standard_True;
707 thelevel ++;
708}
709
710
711//=======================================================================
712//function : OpenTypedSub
713//purpose :
714//=======================================================================
715
716void StepData_StepWriter::OpenTypedSub (const Standard_CString subtype)
717{
718 AddParam();
60be1f9b 719 if (subtype[0] != '\0') AddString (subtype,(Standard_Integer) strlen(subtype));
7fd59977 720 AddString(textlist);
721 thefirst = Standard_True;
722 thelevel ++;
723}
724
725
726//=======================================================================
727//function : CloseSub
728//purpose :
729//=======================================================================
730
731void StepData_StepWriter::CloseSub ()
732{
733 AddString(textendlist);
734 thefirst = Standard_False; // le parametre suivant une sous-liste n est donc pas 1er
735 thelevel --;
736}
737
738
739//=======================================================================
740//function : AddParam
741//purpose :
742//=======================================================================
743
744void StepData_StepWriter::AddParam ()
745{
746 if (!thefirst) AddString(textparam);
747 thefirst = Standard_False;
748}
749
750
751//=======================================================================
752//function : Send
753//purpose :
754//=======================================================================
755
756void StepData_StepWriter::Send (const Standard_Integer val)
757{
758 char lval[12];
759 AddParam();
760 sprintf(lval,"%d",val);
60be1f9b 761 AddString(lval,(Standard_Integer) strlen(lval));
7fd59977 762}
763
764
765//=======================================================================
766//function : Send
767//purpose :
768//=======================================================================
769
770void StepData_StepWriter::Send (const Standard_Real val)
771{
772// Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
773 char lval[24];
774 Standard_Integer lng = thefloatw.Write(val,lval);
775 AddParam();
776 AddString(lval,lng); // gere le format specifique : si besoin est
777}
778
779// Send(String) : attention, on envoie un Texte ... donc entre ' '
780
781//=======================================================================
782//function : Send
783//purpose :
784//=======================================================================
785
786void StepData_StepWriter::Send (const TCollection_AsciiString& val)
787{
788 AddParam();
789 TCollection_AsciiString aval(val); // on duplique pour trafiquer si besoin
790 Standard_Integer nb = aval.Length(); Standard_Integer nn = nb;
791 aval.AssignCat('\''); // comme cela, Insert(i+1) est OK
792
793// Conversion des Caracteres speciaux
794 for (Standard_Integer i = nb; i > 0; i --) {
795 char uncar = aval.Value(i);
796 if (uncar == '\'') { aval.Insert(i+1,'\''); nn ++; continue; }
797 if (uncar == '\\') { aval.Insert(i+1,'\\'); nn ++; continue; }
798 if (uncar == '\n') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
799 aval.Insert(i+1,'N' ); nn += 2; continue; }
800 if (uncar == '\t') { aval.SetValue(i,'\\'); aval.Insert(i+1,'\\');
801 aval.Insert(i+1,'T' ); nn += 2; continue; }
802 }
803 //:i2 abv 31 Aug 98: ProSTEP TR9: avoid wrapping text or do it at spaces
804 aval.Insert(1,'\'');
805 nn += 2;
806
807//:i2 AddString ("\'",1); nn ++;
808
809// Attention au depassement des 72 caracteres
810 if (thecurr.CanGet(nn)) AddString(aval,0);
811 //:i2
812 else {
813 thefile->Append(thecurr.Moved());
814 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
815 if ( indst+nn <= StepLong ) thecurr.SetInitial(indst);
816 else thecurr.SetInitial(0);
817 if ( thecurr.CanGet(nn) ) AddString(aval,0);
818 else {
819 while ( nn >0 ) {
820 if (nn <= StepLong) {
821 thecurr.Add (aval); // Ca yet, on a tout epuise
822 thecurr.FreezeInitial();
823 break;
824 }
825 Standard_Integer stop = StepLong; // position of last separator
826 for ( ; stop > 0 && aval.Value(stop) != ' '; stop-- );
827 if ( ! stop ) {
828 stop = StepLong;
829 for ( ; stop > 0 && aval.Value(stop) != '\\'; stop-- );
830 if ( ! stop ) {
831 stop = StepLong;
832 for ( ; stop > 0 && aval.Value(stop) != '_'; stop-- );
833 if ( ! stop ) stop = StepLong;
834 }
835 }
836 TCollection_AsciiString bval = aval.Split(stop);
837 thefile->Append(new TCollection_HAsciiString(aval));
838 aval = bval;
839 nn -= stop;
840 }
841 }
842 }
843/* //:i2
844 else {
845 // Il faut tronconner ... lignes limitees a 72 caracteres (StepLong)
846 Standard_Integer ncurr = thecurr.Length();
847 Standard_Integer nbuff = StepLong - ncurr;
848 thecurr.Add (aval.ToCString(),nbuff);
849 thefile->Append(thecurr.Moved());
850 aval.Remove(1,nbuff);
851 nn -= nbuff;
852 while (nn > 0) {
853 if (nn <= StepLong) {
854 thecurr.Add (aval); // Ca yet, on a tout epuise
855 thecurr.FreezeInitial();
856 break;
857 }
858 TCollection_AsciiString bval = aval.Split(StepLong);
859 thefile->Append(new TCollection_HAsciiString(bval));
860 nn -= StepLong;
861 }
862 }
863//:i2 */
864// thecurr.Add('\''); deja mis dans aval au debut
865}
866
867
868//=======================================================================
869//function : Send
870//purpose :
871//=======================================================================
872
873void StepData_StepWriter::Send (const Handle(Standard_Transient)& val)
874{
875 char lident[20];
876// Undefined ?
877 if (val.IsNull()) {
9775fa61 878// throw Interface_InterfaceMismatch("StepWriter : Sending Null Reference");
7fd59977 879 thechecks.CCheck(thenum)->AddFail("Null Reference");
880 SendUndef();
881 Comment(Standard_True);
882 SendComment(" NUL REF ");
883 Comment(Standard_False);
884 return;
885 }
886 Standard_Integer num = themodel->Number(val);
887// String ? (si non repertoriee dans le Modele)
888 if (num == 0) {
889 if (val->IsKind(STANDARD_TYPE(TCollection_HAsciiString))) {
890 DeclareAndCast(TCollection_HAsciiString,strval,val);
891 Send (TCollection_AsciiString(strval->ToCString()));
892 return;
893 }
894// SelectMember ? (toujours, si non repertoriee)
895// mais attention, pas de description attachee
896 else if (val->IsKind(STANDARD_TYPE(StepData_SelectMember))) {
897 DeclareAndCast(StepData_SelectMember,sm,val);
898 Handle(StepData_PDescr) descr; // null
899 SendSelect (sm,descr);
900 }
901// Sinon, PAS NORMAL !
902 else {
903 thechecks.CCheck(thenum)->AddFail("UnknownReference");
904 SendUndef();
905 Comment(Standard_True);
906 SendComment(" UNKNOWN REF ");
907 Comment(Standard_False);
9775fa61 908// throw Interface_InterfaceMismatch("StepWriter : Sending Unknown Reference");
7fd59977 909 }
910 }
911// Cas normal : une bonne Entite, on envoie son Ident.
912 else {
913 Standard_Integer idnum = num, idtrue = 0;
914 if (thelabmode > 0) idtrue = themodel->IdentLabel(val);
915 if (thelabmode == 1) idnum = idtrue;
916 if (idnum == 0) idnum = num;
917 if (thelabmode < 2 || idnum == idtrue) sprintf(lident,"#%d",idnum);
918 else sprintf(lident,"%d:#%d",idnum,idtrue);
919 AddParam();
60be1f9b 920 AddString(lident,(Standard_Integer) strlen(lident));
7fd59977 921 }
922}
923
924
925//=======================================================================
926//function : SendBoolean
927//purpose :
928//=======================================================================
929
930void StepData_StepWriter::SendBoolean (const Standard_Boolean val)
931{
932 if (val) SendString(texttrue);
933 else SendString(textfalse);
934}
935
936
937//=======================================================================
938//function : SendLogical
939//purpose :
940//=======================================================================
941
942void StepData_StepWriter::SendLogical (const StepData_Logical val)
943{
944 if (val == StepData_LTrue) SendString(texttrue);
945 else if (val == StepData_LFalse) SendString(textfalse);
946 else SendString(textunknown);
947}
948
949
950// SendString : attention, on donne l'intitule exact
951
952//=======================================================================
953//function : SendString
954//purpose :
955//=======================================================================
956
957void StepData_StepWriter::SendString (const TCollection_AsciiString& val)
958{
959 AddParam();
960 AddString(val);
961}
962
963// SendString : attention, on donne l'intitule exact
964
965//=======================================================================
966//function : SendString
967//purpose :
968//=======================================================================
969
970void StepData_StepWriter::SendString (const Standard_CString val)
971{
972 AddParam();
60be1f9b 973 AddString(val,(Standard_Integer) strlen(val));
7fd59977 974}
975
976// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
977
978//=======================================================================
979//function : SendEnum
980//purpose :
981//=======================================================================
982
983void StepData_StepWriter::SendEnum (const TCollection_AsciiString& val)
984{
985 if (val.Length() == 1 && val.Value(1) == '$') { SendUndef(); return; }
986 AddParam();
987 TCollection_AsciiString aValue = val;
988 if (aValue.Value(1) != '.') aValue.Prepend('.');
989 if (aValue.Value(aValue.Length()) != '.') aValue+='.';
990 AddString(aValue,2);
991
992}
993
994// SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
995
996//=======================================================================
997//function : SendEnum
998//purpose :
999//=======================================================================
1000
1001void StepData_StepWriter::SendEnum (const Standard_CString val)
1002{
1003
1004 if (val[0] == '$' && val[1] == '\0') { SendUndef(); return; }
1005 TCollection_AsciiString aValue(val);
1006 SendEnum(aValue);
1007}
1008
1009
1010//=======================================================================
1011//function : SendArrReal
1012//purpose :
1013//=======================================================================
1014
1015void StepData_StepWriter::SendArrReal (const Handle(TColStd_HArray1OfReal) &anArr)
1016{
1017 AddString(textlist);
1018 if(anArr->Length()>0) {
1019 // add real
1020 Send(anArr->Value(1));
1021 for( Standard_Integer i=2; i<=anArr->Length(); i++) {
1022// AddString(textparam);
1023 //add real
1024 Send(anArr->Value(i));
1025 }
1026 }
1027 AddString(textendlist);
1028}
1029
1030
1031//=======================================================================
1032//function : SendUndef
1033//purpose :
1034//=======================================================================
1035
1036void StepData_StepWriter::SendUndef ()
1037{
1038 AddParam();
1039 AddString(textundef);
1040}
1041
1042
1043//=======================================================================
1044//function : SendDerived
1045//purpose :
1046//=======================================================================
1047
1048void StepData_StepWriter::SendDerived ()
1049{
1050 AddParam();
1051 AddString(textderived);
1052}
1053
1054
1055// EndEntity : s'il faut mettre ; a la ligne, l'aligner sur debut d'entite ...
1056
1057//=======================================================================
1058//function : EndEntity
1059//purpose :
1060//=======================================================================
1061
1062void StepData_StepWriter::EndEntity ()
1063{
9775fa61 1064 if (thelevel != 1) throw Interface_InterfaceMismatch("StepWriter : EndEntity"); // decompte de parentheses mauvais ...
7fd59977 1065 AddString(textendent);
1066 thelevel = 0; // on garde theindval : sera traite au prochain NewLine
1067 Standard_Boolean indent = theindent; theindent = Standard_False;
1068 NewLine(Standard_False); theindent = indent;
1069 themult = Standard_False;
1070// pour forcer indentation si necessaire
1071}
1072
1073
1074// gestion de la ligne courante (cf aussi NewLine/JoinLine)
1075
1076//=======================================================================
1077//function : AddString
1078//purpose :
1079//=======================================================================
1080
1081void StepData_StepWriter::AddString(const TCollection_AsciiString& astr,
1082 const Standard_Integer more)
1083{
1084 while (!thecurr.CanGet(astr.Length() + more)) {
1085 thefile->Append(thecurr.Moved());
1086 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
1087 thecurr.SetInitial(indst);
1088 }
1089 thecurr.Add(astr);
1090}
1091
1092
1093//=======================================================================
1094//function : AddString
1095//purpose :
1096//=======================================================================
1097
1098void StepData_StepWriter::AddString(const Standard_CString astr,
1099 const Standard_Integer lnstr,
1100 const Standard_Integer more)
1101{
1102 while (!thecurr.CanGet(lnstr + more)) {
1103 thefile->Append(thecurr.Moved());
1104 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
1105 thecurr.SetInitial(indst);
1106 }
1107 thecurr.Add(astr,lnstr);
1108}
1109
1110
1111// ENVOI FINAL
1112
1113
1114//=======================================================================
1115//function : CheckList
1116//purpose :
1117//=======================================================================
1118
1119Interface_CheckIterator StepData_StepWriter::CheckList () const
1120{
1121 return thechecks;
1122}
1123
1124
1125//=======================================================================
1126//function : NbLines
1127//purpose :
1128//=======================================================================
1129
1130Standard_Integer StepData_StepWriter::NbLines () const
1131{ return thefile->Length(); }
1132
1133
1134//=======================================================================
1135//function : Line
1136//purpose :
1137//=======================================================================
1138
1139Handle(TCollection_HAsciiString) StepData_StepWriter::Line
1140 (const Standard_Integer num) const
1141{ return thefile->Value(num); }
1142
1143
1144//=======================================================================
1145//function : Printw
1146//purpose :
1147//=======================================================================
1148
1149Standard_Boolean StepData_StepWriter::Print (Standard_OStream& S)
1150{
1151 Standard_Boolean isGood = (S.good());
1152 Standard_Integer nb = thefile->Length();
1153 for (Standard_Integer i = 1; i <= nb && isGood; i ++)
1154 S << thefile->Value(i)->ToCString() << "\n";
1155
04232180 1156 S<< std::flush;
7fd59977 1157 isGood = (S && S.good());
1158
1159 return isGood;
1160
1161}