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