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 under
6 // the terms of the GNU Lesser General Public License 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
18 #include <Interface_Check.hxx>
19 #include <Interface_CheckIterator.hxx>
20 #include <Interface_EntityIterator.hxx>
21 #include <Interface_FloatWriter.hxx>
22 #include <Interface_InterfaceMismatch.hxx>
23 #include <Interface_Macros.hxx>
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>
44 // StepLong : longueur maxi d une ligne de fichier Step
47 // Constantes litterales (interessantes, pour les performances ET LA MEMOIRE)
49 static TCollection_AsciiString textscope (" &SCOPE");
50 static TCollection_AsciiString textendscope (" ENDSCOPE");
51 static TCollection_AsciiString textcomm (" /* ");
52 static TCollection_AsciiString textendcomm (" */");
53 static TCollection_AsciiString textlist ("(");
54 static TCollection_AsciiString textendlist (")");
55 static TCollection_AsciiString textendent (");");
56 static TCollection_AsciiString textparam (",");
57 static TCollection_AsciiString textundef ("$");
58 static TCollection_AsciiString textderived ("*");
59 static TCollection_AsciiString texttrue (".T.");
60 static TCollection_AsciiString textfalse (".F.");
61 static TCollection_AsciiString textunknown (".U.");
65 //=======================================================================
66 //function : StepData_StepWriter
68 //=======================================================================
70 StepData_StepWriter::StepData_StepWriter(const Handle(StepData_StepModel)& amodel)
71 : thecurr (StepLong) , thefloatw (12)
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
81 // .... Controle d Envoi des Flottants ....
83 //=======================================================================
84 //function : FloatWriter
86 //=======================================================================
88 Interface_FloatWriter& StepData_StepWriter::FloatWriter ()
89 { return thefloatw; } // s y reporter
92 //=======================================================================
93 //function : LabelMode
95 //=======================================================================
97 Standard_Integer& StepData_StepWriter::LabelMode ()
98 { return thelabmode; }
101 //=======================================================================
102 //function : TypeMode
104 //=======================================================================
106 Standard_Integer& StepData_StepWriter::TypeMode ()
107 { return thetypmode; }
109 // .... Description des Scopes (AVANT Envoi) ....
112 //=======================================================================
113 //function : SetScope
115 //=======================================================================
117 void StepData_StepWriter::SetScope (const Standard_Integer numscope,
118 const Standard_Integer numin)
120 Standard_Integer nb = themodel->NbEntities();
121 if (numscope <= 0 || numscope > nb || numin <= 0 || numin > nb)
122 throw Interface_InterfaceMismatch("StepWriter : SetScope, out of range");
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);
128 else if (thescopenext->Value(numin) != 0) {
130 std::cout << "StepWriter : SetScope (scope : " << numscope << " entity : "
131 << numin << "), Entity already in a Scope"<<std::endl;
133 throw Interface_InterfaceMismatch("StepWriter : SetScope, already set");
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);
143 //=======================================================================
144 //function : IsInScope
146 //=======================================================================
148 Standard_Boolean StepData_StepWriter::IsInScope(const Standard_Integer num) const
150 if (thescopenext.IsNull()) return Standard_False;
151 return (thescopenext->Value(num) != 0);
154 // ###########################################################################
155 // ## ## ## ## ENVOI DES SECTIONS ## ## ## ##
157 // .... Envoi du Modele Complet ....
160 //=======================================================================
161 //function : SendModel
163 //=======================================================================
165 void StepData_StepWriter::SendModel(const Handle(StepData_Protocol)& protocol,
166 const Standard_Boolean headeronly)
168 StepData_WriterLib lib(protocol);
171 thefile->Append (new TCollection_HAsciiString("ISO-10303-21;"));
174 // .... Header : suite d entites sans Ident ....
176 Interface_EntityIterator header = themodel->Header();
178 for (header.Start(); header.More(); header.Next()) {
179 Handle(Standard_Transient) anent = header.Value();
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();
186 TCollection_AsciiString styp;
187 if (thetypmode > 0) styp = module->ShortType(CN);
188 if (styp.Length() == 0) styp = module->StepType(CN);
191 module->WriteStep(CN,*this,anent);
192 if (module->IsComplex(CN)) EndComplex();
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();
204 if (headeronly) return;
206 // Data : Comme Header mais avec des Idents ... sinon le code est le meme
209 // .... Erreurs Globales (silya) ....
211 Handle(Interface_Check) achglob = themodel->GlobalCheck();
212 Standard_Integer nbfails = achglob->NbFails();
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));
219 Comment(Standard_False);
220 NewLine(Standard_False);
223 // .... Sortie des Entites une par une ....
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; }
238 // .... DECOUPAGE DU FICHIER EN SECTIONS ....
241 //=======================================================================
242 //function : SendHeader
244 //=======================================================================
246 void StepData_StepWriter::SendHeader ()
248 NewLine(Standard_False);
249 thefile->Append (new TCollection_HAsciiString("HEADER;"));
250 thesect = Standard_True;
254 //=======================================================================
255 //function : SendData
257 //=======================================================================
259 void StepData_StepWriter::SendData ()
261 if (thesect) throw Interface_InterfaceMismatch("StepWriter : Data section");
262 NewLine(Standard_False);
263 thefile->Append (new TCollection_HAsciiString("DATA;"));
264 thesect = Standard_True;
268 //=======================================================================
271 //=======================================================================
273 void StepData_StepWriter::EndSec ()
275 thefile->Append (new TCollection_HAsciiString("ENDSEC;"));
276 thesect = Standard_False;
280 //=======================================================================
283 //=======================================================================
285 void StepData_StepWriter::EndFile ()
287 if (thesect) throw Interface_InterfaceMismatch("StepWriter : EndFile");
288 NewLine(Standard_False);
289 thefile->Append (new TCollection_HAsciiString("END-ISO-10303-21;"));
290 thesect = Standard_False;
293 // .... ENVOI D UNE ENTITE ....
296 //=======================================================================
297 //function : SendEntity
300 //=======================================================================
302 void StepData_StepWriter::SendEntity(const Standard_Integer num,
303 const StepData_WriterLib& lib)
306 Handle(Standard_Transient) anent = themodel->Entity(num);
307 Standard_Integer idnum = num , idtrue = 0;
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
316 // SendIdent repris , lident vient d etre calcule
318 thecurr.Add (lident);
319 themult = Standard_False;
321 // .... Traitement du Scope Eventuel
322 if (!thescopebeg.IsNull()) {
323 Standard_Integer numin = thescopebeg->Value(num);
326 for (Standard_Integer nument = numin; numin > 0; nument = numin) {
327 SendEntity(nument,lib);
328 numin = thescopenext->Value(nument);
334 // .... Envoi de l Entite proprement dite
336 // Write Entity via Lib
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());
344 thechecks.CCheck(num)->AddFail("Erroneous Entity, Content lost");
345 StartEntity(TCollection_AsciiString("!?LOST_DATA"));
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 --; }
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));
362 Comment(Standard_False);
363 NewLine(Standard_False);
367 else if (lib.Select(anent,module,CN)) {
368 if (module->IsComplex(CN)) StartComplex();
370 TCollection_AsciiString styp;
371 if (thetypmode > 0) styp = module->ShortType(CN);
372 if (styp.Length() == 0) styp = module->StepType(CN);
375 module->WriteStep(CN,*this,anent);
376 if (module->IsComplex(CN)) EndComplex();
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();
390 // ###########################################################################
391 // ## ## ## CONSTITUTION DU TEXTE A ENVOYER ## ## ##
393 // Passer a la ligne. Ligne vide pas comptee sauf si evenempty == Standard_True
396 //=======================================================================
399 //=======================================================================
401 void StepData_StepWriter::NewLine (const Standard_Boolean evenempty)
403 if (evenempty || thecurr.Length() > 0) {
404 thefile->Append(thecurr.Moved());
406 Standard_Integer indst = thelevel * 2; if (theindent) indst += theindval;
407 thecurr.SetInitial(indst); thecurr.Clear();
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
416 //=======================================================================
417 //function : JoinLast
419 //=======================================================================
421 void StepData_StepWriter::JoinLast (const Standard_Boolean)
427 //=======================================================================
430 //=======================================================================
432 void StepData_StepWriter::Indent (const Standard_Boolean onent)
433 { theindent = onent; }
436 //=======================================================================
437 //function : SendIdent
439 //=======================================================================
441 void StepData_StepWriter::SendIdent(const Standard_Integer ident)
444 sprintf(lident,"#%d =",ident);
446 thecurr.Add (lident);
447 themult = Standard_False;
451 //=======================================================================
452 //function : SendScope
454 //=======================================================================
456 void StepData_StepWriter::SendScope ()
457 { AddString(textscope); }
460 //=======================================================================
461 //function : SendEndscope
463 //=======================================================================
465 void StepData_StepWriter::SendEndscope ()
467 NewLine(Standard_False);
468 thefile->Append(new TCollection_HAsciiString(textendscope));
472 //=======================================================================
475 //=======================================================================
477 void StepData_StepWriter::Comment (const Standard_Boolean mode)
479 if (mode && !thecomm) AddString(textcomm,20);
480 if (!mode && thecomm) AddString(textendcomm);
485 //=======================================================================
486 //function : SendComment
488 //=======================================================================
490 void StepData_StepWriter::SendComment(const Handle(TCollection_HAsciiString)& text)
492 if (!thecomm) throw Interface_InterfaceMismatch("StepWriter : Comment");
493 AddString(text->ToCString(),text->Length());
497 //=======================================================================
498 //function : SendComment
500 //=======================================================================
502 void StepData_StepWriter::SendComment (const Standard_CString text)
504 if (!thecomm) throw Interface_InterfaceMismatch("StepWriter : Comment");
505 AddString(text,(Standard_Integer) strlen(text));
509 //=======================================================================
510 //function : StartEntity
512 //=======================================================================
514 void StepData_StepWriter::StartEntity(const TCollection_AsciiString& atype)
516 if (atype.Length() == 0) return;
518 if (thelevel != 1) throw Interface_InterfaceMismatch("StepWriter : StartEntity"); // decompte de parentheses mauvais ...
519 AddString(textendlist);
520 AddString(" ",1); //skl 29.01.2003
522 themult = Standard_True;
523 //AddString(" ",1); //skl 29.01.2003
526 theindval = thecurr.Length();
527 thecurr.SetInitial(0);
528 thefirst = Standard_True;
533 //=======================================================================
534 //function : StartComplex
536 //=======================================================================
538 void StepData_StepWriter::StartComplex ()
540 AddString("( ",2); //skl 29.01.2003
541 } // thelevel unchanged
544 //=======================================================================
545 //function : EndComplex
547 //=======================================================================
549 void StepData_StepWriter::EndComplex ()
550 { AddString(") ",2); } // thelevel unchanged
553 // .... SendField et ce qui va avec
556 //=======================================================================
557 //function : SendField
559 //=======================================================================
561 void StepData_StepWriter::SendField(const StepData_Field& fild,
562 const Handle(StepData_PDescr)& descr)
564 Standard_Boolean done = Standard_True;
565 Standard_Integer kind = fild.Kind (Standard_False); // valeur interne
568 DeclareAndCast(StepData_SelectMember,sm,fild.Transient());
569 SendSelect (sm,descr);
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;
588 // Que reste-t-il : les tableaux ...
589 Standard_Integer arity = fild.Arity();
590 if (arity == 0) { SendUndef(); return; } // PAS NORMAL
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;
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
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;
618 for (i = low2; i <= up2; i ++) {
619 kind = fild.ItemKind(i,j);
620 done = Standard_True;
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
641 //=======================================================================
642 //function : SendSelect
644 //=======================================================================
646 void StepData_StepWriter::SendSelect(const Handle(StepData_SelectMember)& sm,
647 const Handle(StepData_PDescr)& /*descr*/)
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; // ??
654 selname = Standard_True;
655 // SendString (sm->Name());
656 // AddString(textlist); // SANS AJOUT DE PARAMETRE !!
657 OpenTypedSub (sm->Name());
659 Standard_Integer kind = sm->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; // ??
671 if (selname) CloseSub();
675 //=======================================================================
676 //function : SendList
678 //=======================================================================
680 void StepData_StepWriter::SendList(const StepData_FieldList& list,
681 const Handle(StepData_ESDescr)& descr)
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);
694 // .... Send* de base
697 //=======================================================================
700 //=======================================================================
702 void StepData_StepWriter::OpenSub ()
706 thefirst = Standard_True;
711 //=======================================================================
712 //function : OpenTypedSub
714 //=======================================================================
716 void StepData_StepWriter::OpenTypedSub (const Standard_CString subtype)
719 if (subtype[0] != '\0') AddString (subtype,(Standard_Integer) strlen(subtype));
721 thefirst = Standard_True;
726 //=======================================================================
727 //function : CloseSub
729 //=======================================================================
731 void StepData_StepWriter::CloseSub ()
733 AddString(textendlist);
734 thefirst = Standard_False; // le parametre suivant une sous-liste n est donc pas 1er
739 //=======================================================================
740 //function : AddParam
742 //=======================================================================
744 void StepData_StepWriter::AddParam ()
746 if (!thefirst) AddString(textparam);
747 thefirst = Standard_False;
751 //=======================================================================
754 //=======================================================================
756 void StepData_StepWriter::Send (const Standard_Integer val)
760 sprintf(lval,"%d",val);
761 AddString(lval,(Standard_Integer) strlen(lval));
765 //=======================================================================
768 //=======================================================================
770 void StepData_StepWriter::Send (const Standard_Real val)
772 // Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
774 Standard_Integer lng = thefloatw.Write(val,lval);
776 AddString(lval,lng); // gere le format specifique : si besoin est
779 // Send(String) : attention, on envoie un Texte ... donc entre ' '
781 //=======================================================================
784 //=======================================================================
786 void StepData_StepWriter::Send (const TCollection_AsciiString& val)
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
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; }
803 //:i2 abv 31 Aug 98: ProSTEP TR9: avoid wrapping text or do it at spaces
807 //:i2 AddString ("\'",1); nn ++;
809 // Attention au depassement des 72 caracteres
810 if (thecurr.CanGet(nn)) AddString(aval,0);
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);
820 if (nn <= StepLong) {
821 thecurr.Add (aval); // Ca yet, on a tout epuise
822 thecurr.FreezeInitial();
825 Standard_Integer stop = StepLong; // position of last separator
826 for ( ; stop > 0 && aval.Value(stop) != ' '; stop-- );
829 for ( ; stop > 0 && aval.Value(stop) != '\\'; stop-- );
832 for ( ; stop > 0 && aval.Value(stop) != '_'; stop-- );
833 if ( ! stop ) stop = StepLong;
836 TCollection_AsciiString bval = aval.Split(stop);
837 thefile->Append(new TCollection_HAsciiString(aval));
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);
853 if (nn <= StepLong) {
854 thecurr.Add (aval); // Ca yet, on a tout epuise
855 thecurr.FreezeInitial();
858 TCollection_AsciiString bval = aval.Split(StepLong);
859 thefile->Append(new TCollection_HAsciiString(bval));
864 // thecurr.Add('\''); deja mis dans aval au debut
868 //=======================================================================
871 //=======================================================================
873 void StepData_StepWriter::Send (const Handle(Standard_Transient)& val)
878 // throw Interface_InterfaceMismatch("StepWriter : Sending Null Reference");
879 thechecks.CCheck(thenum)->AddFail("Null Reference");
881 Comment(Standard_True);
882 SendComment(" NUL REF ");
883 Comment(Standard_False);
886 Standard_Integer num = themodel->Number(val);
887 // String ? (si non repertoriee dans le Modele)
889 if (val->IsKind(STANDARD_TYPE(TCollection_HAsciiString))) {
890 DeclareAndCast(TCollection_HAsciiString,strval,val);
891 Send (TCollection_AsciiString(strval->ToCString()));
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);
901 // Sinon, PAS NORMAL !
903 thechecks.CCheck(thenum)->AddFail("UnknownReference");
905 Comment(Standard_True);
906 SendComment(" UNKNOWN REF ");
907 Comment(Standard_False);
908 // throw Interface_InterfaceMismatch("StepWriter : Sending Unknown Reference");
911 // Cas normal : une bonne Entite, on envoie son Ident.
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);
920 AddString(lident,(Standard_Integer) strlen(lident));
925 //=======================================================================
926 //function : SendBoolean
928 //=======================================================================
930 void StepData_StepWriter::SendBoolean (const Standard_Boolean val)
932 if (val) SendString(texttrue);
933 else SendString(textfalse);
937 //=======================================================================
938 //function : SendLogical
940 //=======================================================================
942 void StepData_StepWriter::SendLogical (const StepData_Logical val)
944 if (val == StepData_LTrue) SendString(texttrue);
945 else if (val == StepData_LFalse) SendString(textfalse);
946 else SendString(textunknown);
950 // SendString : attention, on donne l'intitule exact
952 //=======================================================================
953 //function : SendString
955 //=======================================================================
957 void StepData_StepWriter::SendString (const TCollection_AsciiString& val)
963 // SendString : attention, on donne l'intitule exact
965 //=======================================================================
966 //function : SendString
968 //=======================================================================
970 void StepData_StepWriter::SendString (const Standard_CString val)
973 AddString(val,(Standard_Integer) strlen(val));
976 // SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
978 //=======================================================================
979 //function : SendEnum
981 //=======================================================================
983 void StepData_StepWriter::SendEnum (const TCollection_AsciiString& val)
985 if (val.Length() == 1 && val.Value(1) == '$') { SendUndef(); return; }
987 TCollection_AsciiString aValue = val;
988 if (aValue.Value(1) != '.') aValue.Prepend('.');
989 if (aValue.Value(aValue.Length()) != '.') aValue+='.';
994 // SendEnum : attention, on envoie un intitule d'Enum ... donc entre . .
996 //=======================================================================
997 //function : SendEnum
999 //=======================================================================
1001 void StepData_StepWriter::SendEnum (const Standard_CString val)
1004 if (val[0] == '$' && val[1] == '\0') { SendUndef(); return; }
1005 TCollection_AsciiString aValue(val);
1010 //=======================================================================
1011 //function : SendArrReal
1013 //=======================================================================
1015 void StepData_StepWriter::SendArrReal (const Handle(TColStd_HArray1OfReal) &anArr)
1017 AddString(textlist);
1018 if(anArr->Length()>0) {
1020 Send(anArr->Value(1));
1021 for( Standard_Integer i=2; i<=anArr->Length(); i++) {
1022 // AddString(textparam);
1024 Send(anArr->Value(i));
1027 AddString(textendlist);
1031 //=======================================================================
1032 //function : SendUndef
1034 //=======================================================================
1036 void StepData_StepWriter::SendUndef ()
1039 AddString(textundef);
1043 //=======================================================================
1044 //function : SendDerived
1046 //=======================================================================
1048 void StepData_StepWriter::SendDerived ()
1051 AddString(textderived);
1055 // EndEntity : s'il faut mettre ; a la ligne, l'aligner sur debut d'entite ...
1057 //=======================================================================
1058 //function : EndEntity
1060 //=======================================================================
1062 void StepData_StepWriter::EndEntity ()
1064 if (thelevel != 1) throw Interface_InterfaceMismatch("StepWriter : EndEntity"); // decompte de parentheses mauvais ...
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
1074 // gestion de la ligne courante (cf aussi NewLine/JoinLine)
1076 //=======================================================================
1077 //function : AddString
1079 //=======================================================================
1081 void StepData_StepWriter::AddString(const TCollection_AsciiString& astr,
1082 const Standard_Integer more)
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);
1093 //=======================================================================
1094 //function : AddString
1096 //=======================================================================
1098 void StepData_StepWriter::AddString(const Standard_CString astr,
1099 const Standard_Integer lnstr,
1100 const Standard_Integer more)
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);
1107 thecurr.Add(astr,lnstr);
1114 //=======================================================================
1115 //function : CheckList
1117 //=======================================================================
1119 Interface_CheckIterator StepData_StepWriter::CheckList () const
1125 //=======================================================================
1126 //function : NbLines
1128 //=======================================================================
1130 Standard_Integer StepData_StepWriter::NbLines () const
1131 { return thefile->Length(); }
1134 //=======================================================================
1137 //=======================================================================
1139 Handle(TCollection_HAsciiString) StepData_StepWriter::Line
1140 (const Standard_Integer num) const
1141 { return thefile->Value(num); }
1144 //=======================================================================
1147 //=======================================================================
1149 Standard_Boolean StepData_StepWriter::Print (Standard_OStream& S)
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";
1157 isGood = (S && S.good());