1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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>
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>
35 // StepLong : longueur maxi d une ligne de fichier Step
38 // Constantes litterales (interessantes, pour les performances ET LA MEMOIRE)
40 static TCollection_AsciiString textscope (" &SCOPE");
41 static TCollection_AsciiString textendscope (" ENDSCOPE");
42 static TCollection_AsciiString textcomm (" /* ");
43 static TCollection_AsciiString textendcomm (" */");
44 static TCollection_AsciiString textlist ("(");
45 static TCollection_AsciiString textendlist (")");
46 static TCollection_AsciiString textendent (");");
47 static TCollection_AsciiString textparam (",");
48 static TCollection_AsciiString textundef ("$");
49 static TCollection_AsciiString textderived ("*");
50 static TCollection_AsciiString texttrue (".T.");
51 static TCollection_AsciiString textfalse (".F.");
52 static TCollection_AsciiString textunknown (".U.");
56 //=======================================================================
57 //function : StepData_StepWriter
59 //=======================================================================
61 StepData_StepWriter::StepData_StepWriter(const Handle(StepData_StepModel)& amodel)
62 : thecurr (StepLong) , thefloatw (12)
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
72 // .... Controle d Envoi des Flottants ....
74 //=======================================================================
75 //function : FloatWriter
77 //=======================================================================
79 Interface_FloatWriter& StepData_StepWriter::FloatWriter ()
80 { return thefloatw; } // s y reporter
83 //=======================================================================
84 //function : LabelMode
86 //=======================================================================
88 Standard_Integer& StepData_StepWriter::LabelMode ()
89 { return thelabmode; }
92 //=======================================================================
95 //=======================================================================
97 Standard_Integer& StepData_StepWriter::TypeMode ()
98 { return thetypmode; }
100 // .... Description des Scopes (AVANT Envoi) ....
103 //=======================================================================
104 //function : SetScope
106 //=======================================================================
108 void StepData_StepWriter::SetScope (const Standard_Integer numscope,
109 const Standard_Integer numin)
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);
119 else if (thescopenext->Value(numin) != 0) {
121 cout << "StepWriter : SetScope (scope : " << numscope << " entity : "
122 << numin << "), Entity already in a Scope"<<endl;
124 Interface_InterfaceMismatch::Raise("StepWriter : SetScope, already set");
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);
134 //=======================================================================
135 //function : IsInScope
137 //=======================================================================
139 Standard_Boolean StepData_StepWriter::IsInScope(const Standard_Integer num) const
141 if (thescopenext.IsNull()) return Standard_False;
142 return (thescopenext->Value(num) != 0);
145 // ###########################################################################
146 // ## ## ## ## ENVOI DES SECTIONS ## ## ## ##
148 // .... Envoi du Modele Complet ....
151 //=======================================================================
152 //function : SendModel
154 //=======================================================================
156 void StepData_StepWriter::SendModel(const Handle(StepData_Protocol)& protocol,
157 const Standard_Boolean headeronly)
159 StepData_WriterLib lib(protocol);
162 thefile->Append (new TCollection_HAsciiString("ISO-10303-21;"));
165 // .... Header : suite d entites sans Ident ....
167 Interface_EntityIterator header = themodel->Header();
169 for (header.Start(); header.More(); header.Next()) {
170 Handle(Standard_Transient) anent = header.Value();
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();
177 TCollection_AsciiString styp;
178 if (thetypmode > 0) styp = module->ShortType(CN);
179 if (styp.Length() == 0) styp = module->StepType(CN);
182 module->WriteStep(CN,*this,anent);
183 if (module->IsComplex(CN)) EndComplex();
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();
195 if (headeronly) return;
197 // Data : Comme Header mais avec des Idents ... sinon le code est le meme
200 // .... Erreurs Globales (silya) ....
202 Handle(Interface_Check) achglob = themodel->GlobalCheck();
203 Standard_Integer nbfails = achglob->NbFails();
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));
210 Comment(Standard_False);
211 NewLine(Standard_False);
214 // .... Sortie des Entites une par une ....
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; }
229 // .... DECOUPAGE DU FICHIER EN SECTIONS ....
232 //=======================================================================
233 //function : SendHeader
235 //=======================================================================
237 void StepData_StepWriter::SendHeader ()
239 NewLine(Standard_False);
240 thefile->Append (new TCollection_HAsciiString("HEADER;"));
241 thesect = Standard_True;
245 //=======================================================================
246 //function : SendData
248 //=======================================================================
250 void StepData_StepWriter::SendData ()
252 if (thesect) Interface_InterfaceMismatch::Raise("StepWriter : Data section");
253 NewLine(Standard_False);
254 thefile->Append (new TCollection_HAsciiString("DATA;"));
255 thesect = Standard_True;
259 //=======================================================================
262 //=======================================================================
264 void StepData_StepWriter::EndSec ()
266 thefile->Append (new TCollection_HAsciiString("ENDSEC;"));
267 thesect = Standard_False;
271 //=======================================================================
274 //=======================================================================
276 void StepData_StepWriter::EndFile ()
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;
284 // .... ENVOI D UNE ENTITE ....
287 //=======================================================================
288 //function : SendEntity
291 //=======================================================================
293 void StepData_StepWriter::SendEntity(const Standard_Integer num,
294 const StepData_WriterLib& lib)
297 Handle(Standard_Transient) anent = themodel->Entity(num);
298 Standard_Integer idnum = num , idtrue = 0;
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
307 // SendIdent repris , lident vient d etre calcule
309 thecurr.Add (lident);
310 themult = Standard_False;
312 // .... Traitement du Scope Eventuel
313 if (!thescopebeg.IsNull()) {
314 Standard_Integer numin = thescopebeg->Value(num);
317 for (Standard_Integer nument = numin; numin > 0; nument = numin) {
318 SendEntity(nument,lib);
319 numin = thescopenext->Value(nument);
325 // .... Envoi de l Entite proprement dite
327 // Write Entity via Lib
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());
335 thechecks.CCheck(num)->AddFail("Erroneous Entity, Content lost");
336 StartEntity(TCollection_AsciiString("!?LOST_DATA"));
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 --; }
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));
353 Comment(Standard_False);
354 NewLine(Standard_False);
358 else if (lib.Select(anent,module,CN)) {
359 if (module->IsComplex(CN)) StartComplex();
361 TCollection_AsciiString styp;
362 if (thetypmode > 0) styp = module->ShortType(CN);
363 if (styp.Length() == 0) styp = module->StepType(CN);
366 module->WriteStep(CN,*this,anent);
367 if (module->IsComplex(CN)) EndComplex();
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();
381 // ###########################################################################
382 // ## ## ## CONSTITUTION DU TEXTE A ENVOYER ## ## ##
384 // Passer a la ligne. Ligne vide pas comptee sauf si evenempty == Standard_True
387 //=======================================================================
390 //=======================================================================
392 void StepData_StepWriter::NewLine (const Standard_Boolean evenempty)
394 if (evenempty || thecurr.Length() > 0) {
395 thefile->Append(thecurr.Moved());
397 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
398 thecurr.SetInitial(indst); thecurr.Clear();
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
407 //=======================================================================
408 //function : JoinLast
410 //=======================================================================
412 void StepData_StepWriter::JoinLast (const Standard_Boolean)
418 //=======================================================================
421 //=======================================================================
423 void StepData_StepWriter::Indent (const Standard_Boolean onent)
424 { theindent = onent; }
427 //=======================================================================
428 //function : SendIdent
430 //=======================================================================
432 void StepData_StepWriter::SendIdent(const Standard_Integer ident)
435 sprintf(lident,"#%d =",ident);
437 thecurr.Add (lident);
438 themult = Standard_False;
442 //=======================================================================
443 //function : SendScope
445 //=======================================================================
447 void StepData_StepWriter::SendScope ()
448 { AddString(textscope); }
451 //=======================================================================
452 //function : SendEndscope
454 //=======================================================================
456 void StepData_StepWriter::SendEndscope ()
458 NewLine(Standard_False);
459 thefile->Append(new TCollection_HAsciiString(textendscope));
463 //=======================================================================
466 //=======================================================================
468 void StepData_StepWriter::Comment (const Standard_Boolean mode)
470 if (mode && !thecomm) AddString(textcomm,20);
471 if (!mode && thecomm) AddString(textendcomm);
476 //=======================================================================
477 //function : SendComment
479 //=======================================================================
481 void StepData_StepWriter::SendComment(const Handle(TCollection_HAsciiString)& text)
483 if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
484 AddString(text->ToCString(),text->Length());
488 //=======================================================================
489 //function : SendComment
491 //=======================================================================
493 void StepData_StepWriter::SendComment (const Standard_CString text)
495 if (!thecomm) Interface_InterfaceMismatch::Raise("StepWriter : Comment");
496 AddString(text,(Standard_Integer) strlen(text));
500 //=======================================================================
501 //function : StartEntity
503 //=======================================================================
505 void StepData_StepWriter::StartEntity(const TCollection_AsciiString& atype)
507 if (atype.Length() == 0) return;
509 if (thelevel != 1) Interface_InterfaceMismatch::Raise
510 ("StepWriter : StartEntity"); // decompte de parentheses mauvais ...
511 AddString(textendlist);
512 AddString(" ",1); //skl 29.01.2003
514 themult = Standard_True;
515 //AddString(" ",1); //skl 29.01.2003
518 theindval = thecurr.Length();
519 thecurr.SetInitial(0);
520 thefirst = Standard_True;
525 //=======================================================================
526 //function : StartComplex
528 //=======================================================================
530 void StepData_StepWriter::StartComplex ()
532 AddString("( ",2); //skl 29.01.2003
533 } // thelevel unchanged
536 //=======================================================================
537 //function : EndComplex
539 //=======================================================================
541 void StepData_StepWriter::EndComplex ()
542 { AddString(") ",2); } // thelevel unchanged
545 // .... SendField et ce qui va avec
548 //=======================================================================
549 //function : SendField
551 //=======================================================================
553 void StepData_StepWriter::SendField(const StepData_Field& fild,
554 const Handle(StepData_PDescr)& descr)
556 Standard_Boolean done = Standard_True;
557 Standard_Integer kind = fild.Kind (Standard_False); // valeur interne
560 DeclareAndCast(StepData_SelectMember,sm,fild.Transient());
561 SendSelect (sm,descr);
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;
580 // Que reste-t-il : les tableaux ...
581 Standard_Integer arity = fild.Arity();
582 if (arity == 0) { SendUndef(); return; } // PAS NORMAL
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;
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
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;
610 for (i = low2; i <= up2; i ++) {
611 kind = fild.ItemKind(i,j);
612 done = Standard_True;
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
633 //=======================================================================
634 //function : SendSelect
636 //=======================================================================
638 void StepData_StepWriter::SendSelect(const Handle(StepData_SelectMember)& sm,
639 const Handle(StepData_PDescr)& /*descr*/)
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; // ??
646 selname = Standard_True;
647 // SendString (sm->Name());
648 // AddString(textlist); // SANS AJOUT DE PARAMETRE !!
649 OpenTypedSub (sm->Name());
651 Standard_Integer kind = sm->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; // ??
663 if (selname) CloseSub();
667 //=======================================================================
668 //function : SendList
670 //=======================================================================
672 void StepData_StepWriter::SendList(const StepData_FieldList& list,
673 const Handle(StepData_ESDescr)& descr)
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);
686 // .... Send* de base
689 //=======================================================================
692 //=======================================================================
694 void StepData_StepWriter::OpenSub ()
698 thefirst = Standard_True;
703 //=======================================================================
704 //function : OpenTypedSub
706 //=======================================================================
708 void StepData_StepWriter::OpenTypedSub (const Standard_CString subtype)
711 if (subtype[0] != '\0') AddString (subtype,(Standard_Integer) strlen(subtype));
713 thefirst = Standard_True;
718 //=======================================================================
719 //function : CloseSub
721 //=======================================================================
723 void StepData_StepWriter::CloseSub ()
725 AddString(textendlist);
726 thefirst = Standard_False; // le parametre suivant une sous-liste n est donc pas 1er
731 //=======================================================================
732 //function : AddParam
734 //=======================================================================
736 void StepData_StepWriter::AddParam ()
738 if (!thefirst) AddString(textparam);
739 thefirst = Standard_False;
743 //=======================================================================
746 //=======================================================================
748 void StepData_StepWriter::Send (const Standard_Integer val)
752 sprintf(lval,"%d",val);
753 AddString(lval,(Standard_Integer) strlen(lval));
757 //=======================================================================
760 //=======================================================================
762 void StepData_StepWriter::Send (const Standard_Real val)
764 // Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
766 Standard_Integer lng = thefloatw.Write(val,lval);
768 AddString(lval,lng); // gere le format specifique : si besoin est
771 // Send(String) : attention, on envoie un Texte ... donc entre ' '
773 //=======================================================================
776 //=======================================================================
778 void StepData_StepWriter::Send (const TCollection_AsciiString& val)
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
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; }
795 //:i2 abv 31 Aug 98: ProSTEP TR9: avoid wrapping text or do it at spaces
799 //:i2 AddString ("\'",1); nn ++;
801 // Attention au depassement des 72 caracteres
802 if (thecurr.CanGet(nn)) AddString(aval,0);
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);
812 if (nn <= StepLong) {
813 thecurr.Add (aval); // Ca yet, on a tout epuise
814 thecurr.FreezeInitial();
817 Standard_Integer stop = StepLong; // position of last separator
818 for ( ; stop > 0 && aval.Value(stop) != ' '; stop-- );
821 for ( ; stop > 0 && aval.Value(stop) != '\\'; stop-- );
824 for ( ; stop > 0 && aval.Value(stop) != '_'; stop-- );
825 if ( ! stop ) stop = StepLong;
828 TCollection_AsciiString bval = aval.Split(stop);
829 thefile->Append(new TCollection_HAsciiString(aval));
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);
845 if (nn <= StepLong) {
846 thecurr.Add (aval); // Ca yet, on a tout epuise
847 thecurr.FreezeInitial();
850 TCollection_AsciiString bval = aval.Split(StepLong);
851 thefile->Append(new TCollection_HAsciiString(bval));
856 // thecurr.Add('\''); deja mis dans aval au debut
860 //=======================================================================
863 //=======================================================================
865 void StepData_StepWriter::Send (const Handle(Standard_Transient)& val)
870 // Interface_InterfaceMismatch::Raise("StepWriter : Sending Null Reference");
871 thechecks.CCheck(thenum)->AddFail("Null Reference");
873 Comment(Standard_True);
874 SendComment(" NUL REF ");
875 Comment(Standard_False);
878 Standard_Integer num = themodel->Number(val);
879 // String ? (si non repertoriee dans le Modele)
881 if (val->IsKind(STANDARD_TYPE(TCollection_HAsciiString))) {
882 DeclareAndCast(TCollection_HAsciiString,strval,val);
883 Send (TCollection_AsciiString(strval->ToCString()));
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);
893 // Sinon, PAS NORMAL !
895 thechecks.CCheck(thenum)->AddFail("UnknownReference");
897 Comment(Standard_True);
898 SendComment(" UNKNOWN REF ");
899 Comment(Standard_False);
900 // Interface_InterfaceMismatch::Raise("StepWriter : Sending Unknown Reference");
903 // Cas normal : une bonne Entite, on envoie son Ident.
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);
912 AddString(lident,(Standard_Integer) strlen(lident));
917 //=======================================================================
918 //function : SendBoolean
920 //=======================================================================
922 void StepData_StepWriter::SendBoolean (const Standard_Boolean val)
924 if (val) SendString(texttrue);
925 else SendString(textfalse);
929 //=======================================================================
930 //function : SendLogical
932 //=======================================================================
934 void StepData_StepWriter::SendLogical (const StepData_Logical val)
936 if (val == StepData_LTrue) SendString(texttrue);
937 else if (val == StepData_LFalse) SendString(textfalse);
938 else SendString(textunknown);
942 // SendString : attention, on donne l'intitule exact
944 //=======================================================================
945 //function : SendString
947 //=======================================================================
949 void StepData_StepWriter::SendString (const TCollection_AsciiString& val)
955 // SendString : attention, on donne l'intitule exact
957 //=======================================================================
958 //function : SendString
960 //=======================================================================
962 void StepData_StepWriter::SendString (const Standard_CString val)
965 AddString(val,(Standard_Integer) strlen(val));
968 // SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
970 //=======================================================================
971 //function : SendEnum
973 //=======================================================================
975 void StepData_StepWriter::SendEnum (const TCollection_AsciiString& val)
977 if (val.Length() == 1 && val.Value(1) == '$') { SendUndef(); return; }
979 TCollection_AsciiString aValue = val;
980 if (aValue.Value(1) != '.') aValue.Prepend('.');
981 if (aValue.Value(aValue.Length()) != '.') aValue+='.';
986 // SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
988 //=======================================================================
989 //function : SendEnum
991 //=======================================================================
993 void StepData_StepWriter::SendEnum (const Standard_CString val)
996 if (val[0] == '$' && val[1] == '\0') { SendUndef(); return; }
997 TCollection_AsciiString aValue(val);
1002 //=======================================================================
1003 //function : SendArrReal
1005 //=======================================================================
1007 void StepData_StepWriter::SendArrReal (const Handle(TColStd_HArray1OfReal) &anArr)
1009 AddString(textlist);
1010 if(anArr->Length()>0) {
1012 Send(anArr->Value(1));
1013 for( Standard_Integer i=2; i<=anArr->Length(); i++) {
1014 // AddString(textparam);
1016 Send(anArr->Value(i));
1019 AddString(textendlist);
1023 //=======================================================================
1024 //function : SendUndef
1026 //=======================================================================
1028 void StepData_StepWriter::SendUndef ()
1031 AddString(textundef);
1035 //=======================================================================
1036 //function : SendDerived
1038 //=======================================================================
1040 void StepData_StepWriter::SendDerived ()
1043 AddString(textderived);
1047 // EndEntity : s'il faut mettre ; a la ligne, l'aligner sur debut d'entite ...
1049 //=======================================================================
1050 //function : EndEntity
1052 //=======================================================================
1054 void StepData_StepWriter::EndEntity ()
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
1067 // gestion de la ligne courante (cf aussi NewLine/JoinLine)
1069 //=======================================================================
1070 //function : AddString
1072 //=======================================================================
1074 void StepData_StepWriter::AddString(const TCollection_AsciiString& astr,
1075 const Standard_Integer more)
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);
1086 //=======================================================================
1087 //function : AddString
1089 //=======================================================================
1091 void StepData_StepWriter::AddString(const Standard_CString astr,
1092 const Standard_Integer lnstr,
1093 const Standard_Integer more)
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);
1100 thecurr.Add(astr,lnstr);
1107 //=======================================================================
1108 //function : CheckList
1110 //=======================================================================
1112 Interface_CheckIterator StepData_StepWriter::CheckList () const
1118 //=======================================================================
1119 //function : NbLines
1121 //=======================================================================
1123 Standard_Integer StepData_StepWriter::NbLines () const
1124 { return thefile->Length(); }
1127 //=======================================================================
1130 //=======================================================================
1132 Handle(TCollection_HAsciiString) StepData_StepWriter::Line
1133 (const Standard_Integer num) const
1134 { return thefile->Value(num); }
1137 //=======================================================================
1140 //=======================================================================
1142 Standard_Boolean StepData_StepWriter::Print (Standard_OStream& S)
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";
1150 isGood = (S && S.good());