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