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