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