0031481: Data Exchange - provide parser of STEP EXPRESS schema for generation of...
[occt.git] / src / Express / Express_Entity.cxx
1 // Created:     Tue Nov  2 14:40:06 1999
2 // Author:      Andrey BETENEV
3 // Copyright (c) 1999-2020 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Express_Entity.hxx>
17
18 #include <Express.hxx>
19 #include <Express_Alias.hxx>
20 #include <Express_Boolean.hxx>
21 #include <Express_ComplexType.hxx>
22 #include <Express_Enum.hxx>
23 #include <Express_Field.hxx>
24 #include <Express_HSequenceOfEntity.hxx>
25 #include <Express_HSequenceOfField.hxx>
26 #include <Express_Integer.hxx>
27 #include <Express_Logical.hxx>
28 #include <Express_NamedType.hxx>
29 #include <Express_Number.hxx>
30 #include <Express_Real.hxx>
31 #include <Express_Select.hxx>
32 #include <Express_String.hxx>
33 #include <Express_Type.hxx>
34 #include <Message.hxx>
35 #include <OSD_Directory.hxx>
36 #include <OSD_FileSystem.hxx>
37 #include <OSD_Path.hxx>
38 #include <OSD_Protection.hxx>
39
40 IMPLEMENT_STANDARD_RTTIEXT(Express_Entity, Express_Item)
41
42 //=======================================================================
43 // function : Express_Entity
44 // purpose  :
45 //=======================================================================
46
47 Express_Entity::Express_Entity (const Standard_CString theName,
48                                 const Handle(TColStd_HSequenceOfHAsciiString)& theInherit,
49                                 const Handle(Express_HSequenceOfField)& theFields)
50 : Express_Item (theName), mySupers (theInherit), myFields (theFields)
51 {
52   // make empty lists to avoid checking every time
53   myInherit = new Express_HSequenceOfEntity;
54   if (mySupers.IsNull())
55   {
56     mySupers = new TColStd_HSequenceOfHAsciiString;
57   }
58   if (myFields.IsNull())
59   {
60     myFields = new Express_HSequenceOfField;
61   }
62   myIsAbstract = Standard_False;
63 }
64
65 //=======================================================================
66 // function : SuperTypes
67 // purpose  :
68 //=======================================================================
69
70 const Handle(TColStd_HSequenceOfHAsciiString)& Express_Entity::SuperTypes() const
71 {
72   return mySupers;
73 }
74
75 //=======================================================================
76 // function : Inherit
77 // purpose  :
78 //=======================================================================
79
80 const Handle(Express_HSequenceOfEntity)& Express_Entity::Inherit() const
81 {
82   return myInherit;
83 }
84
85 //=======================================================================
86 // function : Fields
87 // purpose  :
88 //=======================================================================
89
90 const Handle(Express_HSequenceOfField)& Express_Entity::Fields() const
91 {
92   return myFields;
93 }
94 //=======================================================================
95 // function : NbFields
96 // purpose  :
97 //=======================================================================
98
99 Standard_Integer Express_Entity::NbFields (const Standard_Boolean theInherited) const
100 {
101   Standard_Integer aNb = myFields->Length();
102   if (theInherited)
103   {
104     for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
105     {
106       aNb += myInherit->Value (i)->NbFields (theInherited);
107     }
108   }
109   return aNb;
110 }
111
112 //=======================================================================
113 // function : WriteGetMethod
114 // purpose  :
115 //=======================================================================
116
117 static void writeGetMethod (
118         Standard_OStream& theOS,
119         const TCollection_AsciiString& theName,
120         const TCollection_AsciiString& theField,
121         const TCollection_AsciiString& theType,
122         const Standard_Boolean isHandle,
123         const Standard_Boolean /*isSimple*/)
124 {
125   const TCollection_AsciiString& aMethod = theField;
126   Express::WriteMethodStamp (theOS, aMethod);
127   theOS << (isHandle ? "Handle(" : "") << theType << (isHandle ? ") " : " ") << theName << "::" << aMethod << "() const\n"
128            "{\n"
129            "  return my" << theField << ";\n"
130            "}\n";
131 }
132
133 //=======================================================================
134 // function : WriteSetMethod
135 // purpose  :
136 //=======================================================================
137
138 static void writeSetMethod (
139         Standard_OStream& theOS,
140         const TCollection_AsciiString& theName,
141         const TCollection_AsciiString& theField,
142         const TCollection_AsciiString& theType,
143         const Standard_Boolean isHandle,
144         const Standard_Boolean isSimple)
145 {
146   TCollection_AsciiString aMethod = "Set";
147   aMethod += theField;
148   Express::WriteMethodStamp (theOS, aMethod);
149   theOS << "void " << theName << "::" << aMethod << " (const " << (isHandle ? "Handle(" : "") << theType << (isHandle ? ")" : "") <<
150            (isSimple ? "" : "&") << " the" << theField << ")\n"
151            "{\n"
152            "  my" << theField << " = the" << theField << ";\n"
153            "}\n";
154 }
155
156 //=======================================================================
157 // function : WriteSpaces
158 // purpose  :
159 //=======================================================================
160
161 static inline void writeSpaces (Standard_OStream& theOS, Standard_Integer theNum)
162 {
163   for (Standard_Integer i = 0; i < theNum; i++)
164     theOS << " ";
165 }
166
167 //=======================================================================
168 // function : GenerateClass
169 // purpose  :
170 //=======================================================================
171
172 Standard_Boolean Express_Entity::GenerateClass() const
173 {
174   const TCollection_AsciiString aCPPName = CPPName();
175   Message::SendInfo() << "Generating ENTITY " << aCPPName;
176
177   // create a package directory (if not yet exist)
178   OSD_Protection aProt (OSD_RWXD, OSD_RWXD, OSD_RX, OSD_RX);
179   TCollection_AsciiString aPack = GetPackageName();
180   OSD_Path aPath (aPack);
181   OSD_Directory aDir (aPath);
182   aDir.Build (aProt);
183   aPack += "/";
184   aPack += aCPPName;
185   const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
186
187   //===============================
188   // Step 1: generating HXX
189   TCollection_AsciiString anInheritName;
190   {
191     // Open HXX file
192     std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".hxx"), std::ios::out | std::ios::binary);
193     Standard_OStream& anOS = *aStreamPtr;
194
195     // write header
196     Express::WriteFileStamp (anOS);
197
198     // write include protection and "standard" includes
199     anOS << "#ifndef _" << aCPPName << "_HeaderFile_\n"
200             "#define _" << aCPPName << "_HeaderFile_\n"
201             "\n"
202             "#include <Standard.hxx>\n"
203             "#include <Standard_Type.hxx>\n";
204     if (myInherit->Length() < 1)
205     {
206       anInheritName = "Standard_Transient";
207       anOS << "#include <" << anInheritName << ".hxx>\n";
208     }
209     else
210     {
211       // first inherited class will be actually inherited
212       Handle(Express_Entity) anEntity = myInherit->Value (1);
213       anInheritName = anEntity->CPPName();
214       // make warning if there are more than one inherits
215       if (myInherit->Length() > 1)
216       {
217         Message::SendWarning() << "Warning: ENTITY " << Name() << " defined with multiple inheritance;";
218         Message::SendWarning() << "Warning: only first base class " << anInheritName << " is actually inherited, others are made fields";
219       }
220     }
221     // write other includes (inherits and used types)
222     writeIncludes (anOS);
223
224     // write HANDLE MACRO
225     anOS << "\n"
226             "DEFINE_STANDARD_HANDLE(" << aCPPName << ", " << anInheritName << ")\n"
227             "\n";
228
229     // write start of declaration (inheritance)
230     anOS << "//! Representation of STEP entity " << Name() << "\n"
231             "class " << aCPPName << " : public " << anInheritName << "\n"
232             "{\n"
233             "\n"
234             "public :\n"
235             "\n";
236
237     // write constructor
238     anOS << "  //! default constructor\n"
239             "  Standard_EXPORT " << aCPPName << "();\n"
240             "\n";
241
242     // write Init methods
243     if (myInherit->Length() > 1 || myFields->Length() > 0)
244     {
245       anOS << "  //! Initialize all fields (own and inherited)\n"
246               "  Standard_EXPORT void Init (";
247       makeInit (anOS, 29, Standard_True, 0);
248       anOS << ");\n"
249               "\n";
250     }
251
252     // write methods Get/Set
253     for (Standard_Integer i = 2; i <= myInherit->Length(); i++)
254     {
255       Handle(Express_Entity) anEntity = myInherit->Value (i);
256       const TCollection_AsciiString& aName = anEntity->Name();
257       const TCollection_AsciiString& anEntityCPPName = anEntity->CPPName();
258       anOS << "  //! Returns data for supertype " << aName << "\n"
259               "  Standard_EXPORT Handle(" << anEntityCPPName << ") " << aName << "() const;\n"
260               "  //! Sets data for supertype " << aName << "\n"
261               "  Standard_EXPORT void Set" << aName << " (const Handle(" << anEntityCPPName << ")& the" << aName << ");\n"
262               "\n";
263     }
264     for (Standard_Integer i = 1; i <= myFields->Length(); i++)
265     {
266       Handle(Express_Field) aField = myFields->Value (i);
267       Handle(Express_Type) aFieldType = aField->Type();
268       TCollection_AsciiString aFieldCPPName = aFieldType->CPPName();
269       anOS << "  //! Returns field " << aField->Name() << "\n";
270       if (aFieldType->IsHandle())
271       {
272         anOS << "  Standard_EXPORT Handle(" << aFieldCPPName << ") " << aField->Name() << "() const;\n";
273       }
274       else
275       {
276         anOS << "  Standard_EXPORT " << aFieldCPPName << " " << aField->Name() << "() const;\n";
277       }
278       anOS << "\n"
279               "  //! Sets field " << aField->Name() << "\n";
280       if (aFieldType->IsHandle())
281       {
282         anOS << "  Standard_EXPORT void Set" << aField->Name() << " (const Handle("
283              << aFieldCPPName << ")& the" << aField->Name() << ");\n";
284       }
285       else
286       {
287         anOS << "  Standard_EXPORT void Set" << aField->Name() << " (const "
288              << aFieldCPPName << (aFieldType->IsSimple() ? "" : "&")
289              << " the" << aField->Name() << ");\n";
290       }
291       if (aField->IsOptional())
292       {
293         anOS << "\n"
294                 "  //! Returns True if optional field " << aField->Name() << " is defined\n"
295                 "  Standard_EXPORT Standard_Boolean Has" << aField->Name() << "() const;\n";
296       }
297       anOS << "\n";
298
299       // prepare additional methods for HArray1 field (NbField() and <field_elem> FieldValue(int num))
300       Standard_Integer aFindPos = aFieldCPPName.Search ("_HArray");
301       if (aFindPos > -1)
302       {
303         TCollection_AsciiString aNamePack = aFieldCPPName.SubString (1, aFindPos);
304         TCollection_AsciiString aNameClass;
305         if (aNamePack.IsEqual ("TColStd_"))
306         {
307           Standard_Integer aFindPos2 = aFieldCPPName.Search ("Integer");
308           if (aFindPos2 > -1)
309           {
310             aNameClass = "Standard_Integer";
311           }
312           else
313           {
314             aFindPos2 = aFieldCPPName.Search ("Real");
315             if (aFindPos2 > -1)
316             {
317               aNameClass = "Standard_Real";
318             }
319             else
320             {
321               aNameClass = "Standard_Boolean";
322             }
323           }
324         }
325         else
326         {
327           if (aNamePack.IsEqual ("Interface_"))
328           {
329             aNameClass = "Handle(TCollection_HAsciiString)";
330           }
331           else
332           {
333             aNameClass = "Handle(";
334             aNameClass += aNamePack;
335             aNameClass += aFieldCPPName.SubString (aFindPos + 10, aFieldCPPName.Length());
336             aNameClass += ")";
337           }
338         }
339         anOS << "  //! Returns number of " << aField->Name() << "\n"
340                 "  Standard_EXPORT Standard_Integer Nb" << aField->Name() << "() const;\n"
341                 "\n"
342                 "  //! Returns value of " << aField->Name() << " by its num\n"
343                 "  Standard_EXPORT " << aNameClass << " " << aField->Name() << "Value (const Standard_Integer theNum) const;\n"
344                 "\n";
345       }
346     }
347
348     anOS << "  DEFINE_STANDARD_RTTIEXT(" << aCPPName << ", " << anInheritName << ")\n"
349             "\n";
350
351     // write fields section
352     if (myInherit->Length() > 1 || myFields->Length() > 0)
353     {
354       anOS << "private:\n"
355               "\n";
356       for (Standard_Integer i = 2; i <= myInherit->Length(); i++)
357       {
358         Handle(Express_Entity) anEntity = myInherit->Value (i);
359         anOS << "  Handle(" << anEntity->CPPName() << ") my" << anEntity->Name() << "; //!< supertype\n";
360       }
361       for (Standard_Integer i = 1; i <= myFields->Length(); i++)
362       {
363         Handle(Express_Field) aField = myFields->Value (i);
364         Handle(Express_Type) aFieldType = aField->Type();
365         if (aFieldType->IsHandle())
366         {
367           anOS << "  Handle(" << aFieldType->CPPName() << ") my" << aField->Name() << ";";
368         }
369         else
370         {
371           anOS << "  " << aFieldType->CPPName() << " my" << aField->Name() << ";";
372         }
373         if (aField->IsOptional())
374         {
375           anOS << " //!< optional";
376         }
377         anOS << "\n";
378       }
379       // optional fields: flag 'is field set'
380       for (Standard_Integer i = 1; i <= myFields->Length(); i++)
381       {
382         Handle(Express_Field) aField = myFields->Value (i);
383         if (!aField->IsOptional())
384         {
385           continue;
386         }
387         anOS << "  Standard_Boolean myHas" << aField->Name() << "; //!< flag \"is "
388              << aField->Name() << " defined\"\n";
389       }
390       anOS << "\n";
391     }
392
393     // write end
394     anOS << "};\n"
395             "\n"
396             "#endif // _" << aCPPName << "_HeaderFile_\n";
397     aStreamPtr.reset();
398   }
399   //===============================
400   // Step 2: generating CXX
401   {
402     // Open CXX file
403     std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".cxx"), std::ios::out | std::ios::binary);
404     Standard_OStream& anOS = *aStreamPtr;
405
406     // write header
407     Express::WriteFileStamp (anOS);
408
409     // write include section
410     anOS << "#include <" << aCPPName << ".hxx>\n"
411             "\n"
412             "IMPLEMENT_STANDARD_RTTIEXT(" << aCPPName << ", " << anInheritName << ")\n";
413
414     // write constructor
415     Express::WriteMethodStamp (anOS, aCPPName);
416     anOS << aCPPName << "::" << aCPPName << "()\n"
417             "{\n";
418     for (Standard_Integer i = 1; i <= myFields->Length(); i++)
419     {
420       Handle(Express_Field) aField = myFields->Value (i);
421       if (aField->IsOptional())
422         anOS << "  myHas" << aField->Name() << " = Standard_False;\n";
423     }
424     anOS << "}\n";
425
426     // write method Init()
427     if (myInherit->Length() > 1 || myFields->Length() > 0)
428     {
429       Express::WriteMethodStamp (anOS, "Init");
430       anOS << "void " << aCPPName << "::Init (";
431       makeInit (anOS, 13 + aCPPName.Length(), Standard_True, 1);
432       anOS << ")\n"
433               "{";
434       makeInit (anOS, -2, Standard_True, 3);
435       anOS << "\n"
436               "}\n";
437     }
438
439     // write "methods" section
440     for (Standard_Integer i = 2; i <= myInherit->Length(); i++)
441     {
442       Handle(Express_Entity) anEntity = myInherit->Value (i);
443       const TCollection_AsciiString& anEntityCPPName = anEntity->CPPName();
444       writeGetMethod (anOS, aCPPName, anEntity->Name(), anEntityCPPName, Standard_True, Standard_False);
445       writeSetMethod (anOS, aCPPName, anEntity->Name(), anEntityCPPName, Standard_True, Standard_False);
446     }
447     for (Standard_Integer i = 1; i <= myFields->Length(); i++)
448     {
449       Handle(Express_Field) aField = myFields->Value (i);
450       Handle(Express_Type) aFieldType = aField->Type();
451       TCollection_AsciiString aFieldCPPName = aFieldType->CPPName();
452       writeGetMethod (anOS, aCPPName, aField->Name(), aFieldCPPName, aFieldType->IsHandle(), aFieldType->IsSimple());
453       writeSetMethod (anOS, aCPPName, aField->Name(), aFieldCPPName, aFieldType->IsHandle(), aFieldType->IsSimple());
454       if (aField->IsOptional())
455       {
456         TCollection_AsciiString aMethod = "Has";
457         aMethod += aField->Name();
458         Express::WriteMethodStamp (anOS, aMethod);
459         anOS << "Standard_Boolean " << aCPPName << "::" << aMethod << "() const\n"
460                 "{\n"
461                 "  return myHas" << aField->Name() << ";\n"
462                 "}\n";
463       }
464
465       // prepare additional methods for HArray1 field
466       Standard_Integer aFindPos = aFieldCPPName.Search ("_HArray1");
467       if (aFindPos > -1)
468       {
469         TCollection_AsciiString aNamePack = aFieldCPPName.SubString (1, aFindPos);
470         TCollection_AsciiString aNameClass ("");
471         if (aNamePack.IsEqual ("TColStd_"))
472         {
473           Standard_Integer aFindPos2 = aFieldCPPName.Search ("Integer");
474           if (aFindPos2 > -1)
475           {
476             aNameClass = "Standard_Integer";
477           }
478           else
479           {
480             aFindPos2 = aFieldCPPName.Search ("Real");
481             if (aFindPos2 > -1)
482             {
483               aNameClass = "Standard_Real";
484             }
485             else
486             {
487               aNameClass = "Standard_Boolean";
488             }
489           }
490         }
491         else
492         {
493           if (aNamePack.IsEqual ("Interface_"))
494           {
495             aNameClass = "Handle(TCollection_HAsciiString)";
496           }
497           else
498           {
499             aNameClass = "Handle(";
500             aNameClass += aNamePack;
501             aNameClass += aFieldCPPName.SubString (aFindPos + 10, aFieldCPPName.Length());
502             aNameClass += ")";
503           }
504         }
505         // write method ::NbField()
506         anOS << "\n";
507         TCollection_AsciiString aMethodName = "Nb";
508         aMethodName += aField->Name();
509         Express::WriteMethodStamp (anOS, aMethodName);
510         anOS << "Standard_Integer " << aCPPName << "::Nb" << aField->Name() << "() const;\n"
511                 "{\n"
512                 "  if (my" << aField->Name() << ".IsNull())\n"
513                 "  {\n"
514                 "    return 0;\n"
515                 "  }\n"
516                 "  return my" << aField->Name() << "->Length();\n"
517                 "}\n";
518         // write method ::FieldValue(num)
519         anOS << "\n";
520         aMethodName = aField->Name();
521         aMethodName += "Value";
522         Express::WriteMethodStamp (anOS, aMethodName);
523         anOS << aNameClass << " " << aCPPName << "::" << aField->Name() << "Value (const Standard_Integer theNum) const;\n"
524                 "{\n"
525                 "  return my" << aField->Name() << "->Value (theNum);\n"
526                 "}\n";
527       }
528     }
529
530     // close
531     aStreamPtr.reset();
532
533     if (AbstractFlag())
534     {
535       // generation of RW class is not needed
536       return Standard_True;
537     }
538   }
539   //===============================
540   // Step 3: generating HXX for Reader/Writer class
541   TCollection_AsciiString aRWCPPName;
542   {
543     // Open HXX file
544     aRWCPPName = "RW";
545     aRWCPPName += GetPackageName();
546     aRWCPPName += "_RW";
547     aRWCPPName += Name();
548
549     aPack = "RW";
550     aPack += GetPackageName();
551     OSD_Path aRWPath (aPack);
552     OSD_Directory aRWDir (aRWPath);
553     aRWDir.Build (aProt);
554     aPack += "/";
555     aPack += aRWCPPName;
556
557     std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".hxx"), std::ios::out | std::ios::binary);
558     Standard_OStream& anOS = *aStreamPtr;
559
560     // write header
561     Express::WriteFileStamp (anOS);
562
563     anOS << "#ifndef _" << aRWCPPName << "_HeaderFile_\n"
564             "#define _" << aRWCPPName << "_HeaderFile_\n"
565             "\n";
566
567     // write includes
568     anOS << "#include <Standard.hxx>\n"
569             "#include <Standard_DefineAlloc.hxx>\n"
570             "#include <Standard_Handle.hxx>\n"
571             "\n"
572             "class StepData_StepReaderData;\n"
573             "class Interface_Check;\n"
574             "class StepData_StepWriter;\n"
575             "class Interface_EntityIterator;\n"
576             "class " << aCPPName << ";\n"
577             "\n";
578
579     // write start of declaration (inheritance)
580     anOS << "//! Read & Write tool for " << Name() << "\n"
581             "class " << aRWCPPName << "\n"
582             "{\n"
583             "\n"
584             "public:\n"
585             "\n"
586             "  DEFINE_STANDARD_ALLOC\n"
587             "\n";
588
589     // default constructor
590     anOS << "  Standard_EXPORT " << aRWCPPName << "();\n"
591             "\n";
592
593     // read step
594     anOS << "  Standard_EXPORT void ReadStep (const Handle(StepData_StepReaderData)& theData,\n"
595             "                                 const Standard_Integer theNum,\n"
596             "                                 Handle(Interface_Check)& theCheck,\n"
597             "                                 const Handle(" << aCPPName << ")& theEnt) const;\n"
598             "\n";
599
600     // write step
601     anOS << "  Standard_EXPORT void WriteStep (StepData_StepWriter& theSW,\n"
602             "                                  const Handle(" << aCPPName << ")& theEnt) const;\n"
603             "\n";
604
605     // share
606     anOS << "  Standard_EXPORT void Share (const Handle(" << aCPPName << ")& theEnt,\n"
607             "                              Interface_EntityIterator& theIter) const;\n"
608             "\n";
609
610     // write end
611     anOS << "};\n"
612             "\n"
613             "#endif // _" << aRWCPPName << "_HeaderFile_\n";
614     aStreamPtr.reset();
615   }
616   //===============================
617   // Step 4: generating CXX for Read/Write tool
618   {
619     // Open CXX file
620     std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".cxx"), std::ios::out | std::ios::binary);
621     Standard_OStream& anOS = *aStreamPtr;
622
623     // write header
624     Express::WriteFileStamp (anOS);
625
626     // write include section
627     anOS << "#include <" << aRWCPPName << ".hxx>\n";
628     anOS << "#include <" << aCPPName << ".hxx>\n";
629     anOS << "#include <Interface_EntityIterator.hxx>\n"
630             "#include <StepData_StepReaderData.hxx>\n"
631             "#include <StepData_StepWriter.hxx>\n";
632     // write constructor
633     Express::WriteMethodStamp (anOS, aRWCPPName);
634     anOS << aRWCPPName << "::" << aRWCPPName << "() {}\n"
635             "\n";
636
637     // write method ReadStep
638     Express::WriteMethodStamp (anOS, "ReadStep");
639     if (aRWCPPName.Length() < 40)
640     {
641       anOS << "void " << aRWCPPName << "::ReadStep (const Handle(StepData_StepReaderData)& theData,\n";
642       writeSpaces (anOS, 17 + aRWCPPName.Length());
643       anOS << "const Standard_Integer theNum,\n";
644       writeSpaces (anOS, 17 + aRWCPPName.Length());
645       anOS << "Handle(Interface_Check)& theCheck,\n";
646       writeSpaces (anOS, 17 + aRWCPPName.Length());
647       anOS << "const Handle(" << aCPPName << ")& theEnt) const\n";
648     }
649     else
650     {
651       anOS << "void " << aRWCPPName << "::ReadStep (\n"
652               "  const Handle(StepData_StepReaderData)& theData,\n"
653               "  const Standard_Integer theNum,\n"
654               "  Handle(Interface_Check)& theCheck,\n"
655               "  const Handle(" << aCPPName << ")& theEnt) const\n";
656     }
657     anOS << "{\n";
658     Standard_Integer aNbFields = NbFields (Standard_True);
659
660     anOS << "  // Check number of parameters\n"
661             "  if (!theData->CheckNbParams (theNum, " << aNbFields << ", theCheck, \"" << Express::ToStepName (Name()) << "\"))\n"
662             "  {\n"
663             "    return;\n"
664             "  }\n";
665     writeRWReadCode (anOS, 1, Standard_True); // write code for reading inherited and own fields
666     anOS << "\n"
667             "  // Initialize entity\n"
668             "  theEnt->Init (";
669     makeInit (anOS, 15, Standard_True, 4);
670     anOS << ");\n"
671             "}\n";
672
673     // write method WriteStep
674     Express::WriteMethodStamp (anOS, "WriteStep");
675     if (aRWCPPName.Length() < 40)
676     {
677       anOS << "void " << aRWCPPName << "::WriteStep (StepData_StepWriter& theSW,\n";
678       writeSpaces (anOS, 18 + aRWCPPName.Length());
679       anOS << "const Handle(" << aCPPName << ")& theEnt) const\n";
680     }
681     else
682     {
683       anOS << "void " << aRWCPPName << "::WriteStep (\n"
684               "  StepData_StepWriter& theSW,\n"
685               "  const Handle(" << aCPPName << ")& theEnt) const\n";
686     }
687     anOS << "{\n";
688
689     writeRWWriteCode (anOS, 0, Standard_True); // write code for writing inherited and own fields
690     anOS << "}\n";
691
692     // write method Share
693     Express::WriteMethodStamp (anOS, "Share");
694     std::ostringstream aStringOS;
695     Standard_Integer aNnFileds2 = writeRWShareCode (aStringOS, 1, Standard_True); // write code for filling graph of references
696     if (aRWCPPName.Length() < 40)
697     {
698       anOS << "void " << aRWCPPName << "::Share (const Handle(" << aCPPName << ")&" << ((aNnFileds2 > 1) ? "theEnt," : ",") << "\n";
699       writeSpaces (anOS, 14 + aRWCPPName.Length());
700       if (aNnFileds2 > 1)
701       {
702         anOS << "Interface_EntityIterator& theIter) const\n";
703       }
704       else
705       {
706         anOS << "Interface_EntityIterator&) const\n";
707       }
708     }
709     else
710     {
711       anOS << "void " << aRWCPPName << "::Share(\n"
712               "  const Handle(" << aCPPName << ")&" << ((aNnFileds2 > 1) ? "theEnt," : ",") << "\n";
713       if (aNnFileds2 > 1)
714       {
715         anOS << "Interface_EntityIterator& theIter) const\n";
716       }
717       else
718       {
719         anOS << "Interface_EntityIterator&) const\n";
720       }
721     }
722     anOS << "{\n";
723     if (aNnFileds2 > 1)
724     {
725       anOS << aStringOS.str();
726     }
727     anOS << "}\n";
728     if (CheckFlag())
729     {
730       Express::WriteMethodStamp (anOS, "Check");
731       anOS << "void " << aRWCPPName << "::Check (const Handle(Standard_Transient)& entt,\n";
732       writeSpaces (anOS, 18 + aRWCPPName.Length());
733       anOS << "const Interface_ShareTool& shares,\n";
734       writeSpaces (anOS, 18 + aRWCPPName.Length());
735       anOS << "Interface_Check& check) const\n"
736               "{\n";
737       // DownCast entity to it's type
738       anOS << "  Handle(" << aCPPName << ") ent = Handle(" << aCPPName << ")::DownCast(entt);\n"
739               "}\n";
740     }
741     if (FillSharedFlag())
742     {
743       Express::WriteMethodStamp (anOS, "FillShared");
744       anOS << "void " << aRWCPPName << "::Share(const Handle(Interface_InterfaceModel)& model,\n";
745       writeSpaces (anOS, 18 + aRWCPPName.Length());
746       anOS << "const Handle(Standard_Transient)& entt,\n";
747       writeSpaces (anOS, 18 + aRWCPPName.Length());
748       anOS << "Interface_EntityIterator& iter) const\n"
749               "{\n";
750       // DownCast entity to it's type
751       anOS << "  Handle(" << aCPPName << ") ent = Handle(" << aCPPName << ")::DownCast(entt)\n"
752               "}\n";
753     }
754
755     // close
756     aStreamPtr.reset();
757   }
758   //===============================
759   // Step 5: adding method for registration of entities and include
760   {
761     Standard_Integer anIndex = Express_Item::Index();
762     TCollection_AsciiString aRegDir = "Registration";
763     OSD_Path aPathReg (aRegDir);
764     OSD_Directory aDirReg (aRegDir);
765     aDirReg.Build (aProt);
766     aRegDir += "/";
767
768     // write file with includes
769     {
770       TCollection_AsciiString aPackNameInc = "inc.txt";
771       std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameInc), std::ios::out | std::ios::binary | std::ios::app);
772       Standard_OStream& anOS = *aStreamPtr;
773       anOS << "#include <" << aCPPName << ".hxx>\n";
774       aStreamPtr.reset();
775     }
776     // write file with RW includes
777     {
778       TCollection_AsciiString aPackNameRWInc = "rwinc.txt";
779       std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameRWInc), std::ios::out | std::ios::binary | std::ios::app);
780       Standard_OStream& anOS = *aStreamPtr;
781       anOS << "#include <" << aRWCPPName << ".hxx>\n";
782       aStreamPtr.reset();
783     }
784
785     // generate data for entity registration
786     if (anIndex > 0)
787     {
788       // StepAP214_Protocol.cxx
789       {
790         TCollection_AsciiString aPackNameProtocol = "protocol.txt";
791         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameProtocol), std::ios::out | std::ios::binary | std::ios::app);
792         Standard_OStream& anOS = *aStreamPtr;
793         anOS << "types.Bind (STANDARD_TYPE(" << aCPPName << "), " << anIndex << ");\n";
794         aStreamPtr.reset();
795       }
796       // RWStepAP214_GeneralModule.cxx
797       // FillSharedCase
798       {
799         TCollection_AsciiString aPackNameFillShared = "fillshared.txt";
800         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameFillShared), std::ios::out | std::ios::binary | std::ios::app);
801         Standard_OStream& anOS = *aStreamPtr;
802         anOS << "  case " << anIndex << ":\n"
803                 "  {\n"
804                 "    DeclareAndCast (" << aCPPName << ", anent, ent);\n"
805                 "    " << aRWCPPName << " aTool;\n"
806                 "    aTool.Share(anent, iter);\n"
807                 "  }\n"
808                 "  break;\n";
809         aStreamPtr.reset();
810       }
811       // NewVoid
812       {
813         TCollection_AsciiString aPackNameNewVoid = "newvoid.txt";
814         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameNewVoid), std::ios::out | std::ios::binary | std::ios::app);
815         Standard_OStream& anOS = *aStreamPtr;
816         anOS << "  case " << anIndex << ":\n"
817                 "    ent = new " << aCPPName << ";\n"
818                 "  break;\n";
819         aStreamPtr.reset();
820       }
821       // CategoryNumber
822       {
823         TCollection_AsciiString aPackNameCategory = "category.txt";
824         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameCategory), std::ios::out | std::ios::binary | std::ios::app);
825         Standard_OStream& anOS = *aStreamPtr;
826         anOS << "  case " << anIndex << ": return " << Category() << ";\n";
827         aStreamPtr.reset();
828       }
829       // RWStepAP214_ReadWriteModule.cxx
830       // Reco
831       {
832         TCollection_AsciiString aRecoName = Express::ToStepName (Name());
833         aRecoName.UpperCase();
834         TCollection_AsciiString aPackNameReco = "reco.txt";
835         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameReco), std::ios::out | std::ios::binary | std::ios::app);
836         Standard_OStream& anOS = *aStreamPtr;
837         anOS << "  static TCollection_AsciiString Reco_" << Name() << " (\"" << aRecoName << "\");\n";
838         aStreamPtr.reset();
839       }
840       // type bind
841       {
842         TCollection_AsciiString aPackNameTypeBind = "typebind.txt";
843         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameTypeBind), std::ios::out | std::ios::binary | std::ios::app);
844         Standard_OStream& anOS = *aStreamPtr;
845         anOS << "  typenums.Bind (Reco_" << Name() << ", " << anIndex << ");\n";
846         aStreamPtr.reset();
847       }
848       // StepType
849       {
850         TCollection_AsciiString aPackNameStepType = "steptype.txt";
851         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameStepType), std::ios::out | std::ios::binary | std::ios::app);
852         Standard_OStream& anOS = *aStreamPtr;
853         anOS << "  case " << anIndex << ": return Reco_" << Name() << ";\n";
854         aStreamPtr.reset();
855       }
856       // ReadStep
857       {
858         TCollection_AsciiString aPackNameReadStep = "readstep.txt";
859         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameReadStep), std::ios::out | std::ios::binary | std::ios::app);
860         Standard_OStream& anOS = *aStreamPtr;
861         anOS << "  case " << anIndex << ":\n"
862                 "  {\n"
863                 "    DeclareAndCast (" << aCPPName << ", anent, ent);\n"
864                 "    " << aRWCPPName << " aTool;\n"
865                 "    aTool.ReadStep (data, num, ach, anent);\n"
866                 "  }\n"
867                 "  break;\n";
868         aStreamPtr.reset();
869       }
870       // WriteStep
871       {
872         TCollection_AsciiString aPackNameWriteStep = "writestep.txt";
873         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aRegDir.Cat (aPackNameWriteStep), std::ios::out | std::ios::binary | std::ios::app);
874         Standard_OStream& anOS = *aStreamPtr;
875         anOS << "  case " << anIndex << ":\n"
876                 "  {\n"
877                 "    DeclareAndCast (" << aCPPName << ", anent, ent);\n"
878                 "    " << aRWCPPName << " aTool;\n"
879                 "    aTool.WriteStep (SW, anent);\n"
880                 "  }\n"
881                 "  break;\n";
882         aStreamPtr.reset();
883       }
884       Express_Item::SetIndex (anIndex + 1);
885     }
886   }
887   return Standard_True;
888 }
889
890 //=======================================================================
891 // function : PropagateUse
892 // purpose  :
893 //=======================================================================
894
895 void Express_Entity::PropagateUse() const
896 {
897   const TCollection_AsciiString& aPack = GetPackageName();
898   const TCollection_AsciiString& aName = Name();
899
900   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
901   {
902     Handle(Express_Entity) anEntity = myInherit->Value (i);
903     anEntity->Use2 (aName, aPack);
904   }
905   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
906   {
907     Handle(Express_Type) aType = myFields->Value (i)->Type();
908     aType->Use2 (aName, aPack);
909   }
910 }
911
912 //=======================================================================
913 // function : WriteIncludes
914 // purpose  :
915 //=======================================================================
916
917 Standard_Boolean Express_Entity::writeIncludes (Standard_OStream& theOS) const
918 {
919   DataMapOfStringInteger aDict;
920
921   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
922   {
923     Handle(Express_Entity) anEntity = myInherit->Value (i);
924     anEntity->Use();
925     const TCollection_AsciiString& anEntityCPPName = anEntity->CPPName();
926     if (aDict.IsBound (anEntityCPPName))
927     {
928       continue; // avoid duplicating
929     }
930     aDict.Bind (anEntityCPPName, 1);
931     theOS << "#include <" << anEntityCPPName << ".hxx>\n";
932   }
933   // write includes for own fields
934   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
935   {
936     Handle(Express_Type) aType = myFields->Value (i)->Type();
937     aType->Use();
938     const TCollection_AsciiString aTypeCPPName = aType->CPPName();
939     if (aDict.IsBound (aTypeCPPName))
940     {
941       continue; // avoid duplicating
942     }
943     aDict.Bind (aTypeCPPName, 1);
944     if (aType->IsStandard())
945     {
946       continue;
947     }
948     theOS << "#include <" << aTypeCPPName << ".hxx>\n";
949     const TCollection_AsciiString& aPack = GetPackageName();
950     // check that last include is for array
951     TCollection_AsciiString aStrForSearch = aPack;
952     aStrForSearch += "_HArray";
953     Standard_Integer aFindPos = aTypeCPPName.Search (aStrForSearch.ToCString());
954     if (aFindPos > -1)
955     {
956       // prepare file names
957       aFindPos = aPack.Length();
958       const TCollection_AsciiString& aNameHA = aTypeCPPName;
959       TCollection_AsciiString aNameA = aNameHA.SubString (1, aFindPos + 1);
960       aNameA += aNameHA.SubString (aFindPos + 3, aNameHA.Length());
961       TCollection_AsciiString aNameClass = aNameHA.SubString (aFindPos + 11, aNameHA.Length());
962       const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
963       // create a package directory (if not yet exist)
964       OSD_Protection aProt (OSD_RWXD, OSD_RWXD, OSD_RX, OSD_RX);
965       OSD_Path aPath (aPack);
966       OSD_Directory aDir (aPath);
967       aDir.Build (aProt);
968       // create hxx files for Array1
969       {
970         // Open HXX file
971         TCollection_AsciiString aFileName = aPack;
972         aFileName += "/";
973         aFileName += aNameA;
974         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aFileName.Cat (".hxx"), std::ios::out | std::ios::binary);
975         Standard_OStream& anOS = *aStreamPtr;
976         // write header
977         Express::WriteFileStamp (anOS);
978         anOS << "\n"
979                 "#ifndef " << aNameA << "_HeaderFile\n"
980                 "#define " << aNameA << "_HeaderFile\n"
981                 "\n"
982                 "#include <" << aPack << "_" << aNameClass << ".hxx>\n"
983                 "#include <NCollection_" << aNameHA.SubString (aFindPos + 3, aFindPos + 8) << ".hxx>\n"
984                 "\n"
985                 "typedef NCollection_" << aNameHA.SubString (aFindPos + 3, aFindPos + 8) << "<Handle(" << aPack << "_" << aNameClass << ")> " << aNameA << ";\n"
986                 "\n"
987                 "#endif\n";
988         aStreamPtr.reset();
989       }
990       // create hxx files for HArray1
991       {
992         // Open HXX file
993         TCollection_AsciiString aFileName = aPack;
994         aFileName += "/";
995         aFileName += aNameHA;
996         std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aFileName.Cat (".hxx"), std::ios::out | std::ios::binary);
997         Standard_OStream& anOS = *aStreamPtr;
998         // write header
999         Express::WriteFileStamp (anOS);
1000         anOS << "\n"
1001                 "#ifndef " << aNameHA << "_HeaderFile\n"
1002                 "#define " << aNameHA << "_HeaderFile\n"
1003                 "\n"
1004                 "#include <" << aNameA << ".hxx>\n"
1005                 "#include <NCollection_" << aNameHA.SubString (aFindPos + 2, aFindPos + 8) << ".hxx>\n"
1006                 "\n"
1007                 "DEFINE_HARRAY" << aNameHA.SubString (aFindPos + 8, aFindPos + 8) << "(" << aNameHA << ", " << aNameA << ");\n"
1008                 "\n"
1009                 "#endif\n";
1010         aStreamPtr.reset();
1011       }
1012     }
1013   }
1014
1015   return Standard_True;
1016 }
1017
1018 //=======================================================================
1019 // function : typeToSTEPName
1020 // purpose  : auxiliary for WriteRWReadField
1021 //=======================================================================
1022
1023 static TCollection_AsciiString typeToSTEPName (const Handle(Express_Type)& theType)
1024 {
1025   TCollection_AsciiString aCPPName = theType->CPPName();
1026   TCollection_AsciiString aCls = aCPPName.Token ("_", 2);
1027   if (aCls.Length() < 1)
1028   {
1029     aCls = aCPPName;
1030   }
1031   return Express::ToStepName (aCls);
1032 }
1033
1034 //=======================================================================
1035 // function : WriteRWReadField
1036 // purpose  :
1037 //=======================================================================
1038
1039 static void writeRWReadField (Standard_OStream& theOS,
1040                               const TCollection_AsciiString& theIndex,
1041                               const TCollection_AsciiString& theSTEPName,
1042                               const TCollection_AsciiString& theVarName,
1043                               const Handle(Express_Type)& theVarType,
1044                               const Standard_Integer theLevel,
1045                               const Standard_Boolean isOptional)
1046 {
1047   // indent
1048   TCollection_AsciiString anIdent ("  ");
1049   Standard_Integer aLevel = 0;
1050   for (; aLevel < theLevel; aLevel++)
1051   {
1052     anIdent += "  ";
1053   }
1054   aLevel += 2;
1055
1056   // name of variable identifying number of parameter in data
1057   TCollection_AsciiString aParam ("theNum");
1058   if (theLevel > 0)
1059   {
1060     aParam = TCollection_AsciiString ("aNum");
1061     aParam += TCollection_AsciiString (theLevel);
1062   }
1063
1064   // decode aliased types
1065   Handle(Express_Type) aType = theVarType;
1066   const TCollection_AsciiString aTypeCPPName = aType->CPPName();
1067   while (aType->IsKind (STANDARD_TYPE(Express_NamedType)))
1068   {
1069     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1070     if (!aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Alias)))
1071     {
1072       break;
1073     }
1074     Handle(Express_Alias) anAlias = Handle(Express_Alias)::DownCast (aNamedType->Item());
1075     aType = anAlias->Type();
1076   }
1077
1078   // declare variable
1079   if (aType->IsHandle())
1080   {
1081     theOS << anIdent << "Handle(" << aTypeCPPName << ") a";
1082   }
1083   else
1084   {
1085     theOS << anIdent << aTypeCPPName << " a";
1086   }
1087   theOS << theVarName << ";\n";
1088
1089   if (isOptional)
1090   {
1091     theOS << anIdent << "Standard_Boolean has" << theVarName << " = Standard_True;\n" <<
1092              anIdent << "if (theData->IsParamDefined (" << aParam << ", " << theIndex << "))\n" <<
1093              anIdent << "{\n";
1094     anIdent += "  ";
1095     aLevel++;
1096   }
1097
1098   // read variable depending on its type
1099   if (aType->IsKind (STANDARD_TYPE(Express_NamedType)))
1100   {
1101     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1102     if (aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Entity)))
1103     {
1104       theOS << anIdent << "theData->ReadEntity (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck,\n" <<
1105                anIdent << "  STANDARD_TYPE(" << aNamedType->CPPName() << "), a" << theVarName << ");\n";
1106     }
1107     else if (aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Select)))
1108     {
1109       theOS << anIdent << "theData->ReadEntity (" << aParam << ", " << theIndex << ", \"" << theSTEPName <<
1110                "\", theCheck, a" << theVarName << ");\n";
1111     }
1112     else if (aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Enum)))
1113     {
1114       theOS << anIdent << "if (theData->ParamType(" << aParam << ", " << theIndex << ") == Interface_ParamEnum)\n" <<
1115                anIdent << "{\n" <<
1116                anIdent << "  Standard_CString text = theData->ParamCValue(" << aParam << ", " << theIndex << ");\n";
1117       Handle(Express_Enum) anEnum = Handle(Express_Enum)::DownCast (aNamedType->Item());
1118       TCollection_AsciiString aPrefix = Express::EnumPrefix (anEnum->Name());
1119       Handle(TColStd_HSequenceOfHAsciiString) aNames = anEnum->Names();
1120       TCollection_AsciiString anEnumPack = anEnum->GetPackageName();
1121       for (Standard_Integer i = 1; i <= aNames->Length(); i++)
1122       {
1123         TCollection_AsciiString anEnumName = Express::ToStepName (aNames->Value (i)->String());
1124         anEnumName.UpperCase();
1125         theOS << anIdent << (i == 1 ? "  if     " : "  else if") << " (strcmp (text, \"." << anEnumName << ".\")) a" <<
1126               theVarName << " = " << anEnumPack << "_" << aPrefix << aNames->Value (i)->String() << ";\n";
1127       }
1128       theOS << anIdent << "  else\n" <<
1129                anIdent << "  {\n" <<
1130                anIdent << "    theCheck->AddFail (\"Parameter #" << theIndex << " (" << theSTEPName << ") has not allowed value\");\n" <<
1131                anIdent << "  }\n" <<
1132                anIdent << "}\n" <<
1133                anIdent << "else\n" <<
1134                anIdent << "{\n" <<
1135                anIdent << "  theCheck->AddFail (\"Parameter #" << theIndex << " (" << theSTEPName << ") is not enumeration\");\n" <<
1136                anIdent << "}\n";
1137     }
1138   }
1139   else if (aType->IsKind (STANDARD_TYPE(Express_ComplexType)))
1140   {
1141     Handle(Express_ComplexType) aComplex = Handle(Express_ComplexType)::DownCast (aType);
1142     theOS << anIdent << "Standard_Integer aSub" << theIndex << " = 0;\n" <<
1143              anIdent << "if (theData->ReadSubList (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, aSub" << theIndex << "))\n" <<
1144              anIdent << "{\n" <<
1145              anIdent << "  Standard_Integer aNb" << theLevel << " = theData->NbParams (aSub" << theIndex << ");\n";
1146     TCollection_AsciiString anIterI = theLevel;
1147     anIterI.Prepend ("i");
1148     TCollection_AsciiString aVar = theLevel;
1149     aVar.Prepend ("nIt");
1150     if (aComplex->Type()->IsKind (STANDARD_TYPE(Express_ComplexType)))
1151     {
1152       // array 2
1153       Handle(Express_ComplexType) aComplex2 = Handle(Express_ComplexType)::DownCast (aComplex->Type());
1154       TCollection_AsciiString anIterJ = theLevel;
1155       anIterJ.Prepend ("j");
1156       theOS << anIdent << "  Standard_Integer nbj" << theLevel << " = theData->NbParams (theData->ParamNumber (aSub" << theIndex << ", 1));\n" <<
1157                anIdent << "  a" << theVarName << " = new " << aTypeCPPName << "(1, aNb" << theLevel << ", 1, nbj" << theLevel << ");\n" <<
1158                anIdent << "  for (Standard_Integer " << anIterI << " = 1; " << anIterI << " <= aNb" << theLevel << "; " << anIterI << "++)\n" <<
1159                anIdent << "  {\n" <<
1160                anIdent << "    Standard_Integer subj" << theIndex << " = 0;\n" <<
1161                anIdent << "    if ( theData->ReadSubList (aSub" << theIndex << ", " << anIterI << ", \"sub-part(" << theSTEPName << ")\", theCheck, subj" << theIndex << ") ) {\n" <<
1162                anIdent << "      Standard_Integer aNum" << aLevel + 2 << " = subj" << theIndex << ";\n" <<
1163                anIdent << "      for (Standard_Integer " << anIterJ << " = 1; " << anIterJ << " <= nbj" << theLevel << "; " << anIterJ << "++)\n" <<
1164                anIdent << "      {\n";
1165       TCollection_AsciiString aSubName = typeToSTEPName (aComplex2->Type());
1166       writeRWReadField (theOS, anIterJ, aSubName, aVar, aComplex2->Type(), aLevel + 2, Standard_False);
1167       theOS << anIdent << "        a" << theVarName << "->SetValue(" << anIterI << "," << anIterJ << ", a" << aVar << ");\n" <<
1168                anIdent << "      }\n" <<
1169                anIdent << "    }\n";
1170     }
1171     else
1172     {
1173       // simple array
1174       theOS << anIdent << "  a" << theVarName << " = new " << aTypeCPPName << "(1, aNb" << theLevel << ");\n" <<
1175                anIdent << "  Standard_Integer aNum" << aLevel << " = aSub" << theIndex << ";\n" <<
1176                anIdent << "  for (Standard_Integer " << anIterI << " = 1; " << anIterI << " <= aNb" << theLevel << "; " << anIterI << "++)\n" <<
1177                anIdent << "  {\n";
1178       TCollection_AsciiString aSubName = typeToSTEPName (aComplex->Type());
1179       writeRWReadField (theOS, anIterI, aSubName, aVar, aComplex->Type(), aLevel, Standard_False);
1180       theOS << anIdent << "    a" << theVarName << "->SetValue(" << anIterI << ", a" << aVar << ");\n";
1181     }
1182     theOS << anIdent << "  }\n" <<
1183              anIdent << "}\n";
1184   }
1185   else if (aType->IsKind (STANDARD_TYPE(Express_String)))
1186   {
1187     if (theSTEPName.Length() + theVarName.Length() < 70)
1188     {
1189       theOS << anIdent << "theData->ReadString (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, a" << theVarName << ");\n";
1190     }
1191     else
1192     {
1193       theOS << anIdent << "theData->ReadString (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck,\n" <<
1194                anIdent << "  a" << theVarName << ");\n";
1195     }
1196   }
1197   else if (aType->IsKind (STANDARD_TYPE(Express_Logical)))
1198   {
1199     theOS << anIdent << "theData->ReadLogical (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, a" << theVarName << ");\n";
1200   }
1201   else if (aType->IsKind (STANDARD_TYPE(Express_Boolean)))
1202   {
1203     theOS << anIdent << "theData->ReadBoolean (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, a" << theVarName << ");\n";
1204   }
1205   else if (aType->IsKind (STANDARD_TYPE(Express_Number)) || aType->IsKind (STANDARD_TYPE(Express_Integer)))
1206   {
1207     theOS << anIdent << "theData->ReadInteger (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, a" << theVarName << ");\n";
1208   }
1209   else if (aType->IsKind (STANDARD_TYPE(Express_Real)))
1210   {
1211     theOS << anIdent << "theData->ReadReal (" << aParam << ", " << theIndex << ", \"" << theSTEPName << "\", theCheck, a" << theVarName << ");\n";
1212   }
1213
1214   if (isOptional)
1215   {
1216     anIdent.Remove (1, 2);
1217     theOS << anIdent << "}\n" <<
1218              anIdent << "else\n" <<
1219              anIdent << "{\n" <<
1220              anIdent << "  has" << theVarName << " = Standard_False;\n" <<
1221              anIdent << "  a" << theVarName;
1222     if (aType->IsHandle())
1223     {
1224       theOS << ".Nullify();";
1225     }
1226     else if (aType->IsStandard())
1227     {
1228       theOS << " = 0;";
1229     }
1230     else
1231     {
1232       theOS << " = " << aTypeCPPName << "();";
1233     }
1234     theOS << "\n";
1235     theOS << anIdent << "}\n";
1236   }
1237 }
1238
1239 //=======================================================================
1240 // function : WriteRWReadCode
1241 // purpose  :
1242 //=======================================================================
1243
1244 Standard_Integer Express_Entity::writeRWReadCode (Standard_OStream& theOS,
1245                                                   const Standard_Integer theStart,
1246                                                   const Standard_Integer theOwn) const
1247 {
1248   Standard_Integer aNum = theStart;
1249
1250   // write code for reading inherited fields
1251   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
1252   {
1253     aNum = myInherit->Value (i)->writeRWReadCode (theOS, aNum, Standard_False);
1254   }
1255
1256   // write code for reading own fields
1257   if (myFields->Length() > 0)
1258   {
1259     if (aNum > 0)
1260       theOS << "\n";
1261     theOS << "  // " << (theOwn ? "Own" : "Inherited") << " fields of " << Name() << "\n";
1262   }
1263
1264   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
1265   {
1266     Handle(Express_Field) aField = myFields->Value (i);
1267     TCollection_AsciiString aSTEPName = Express::ToStepName (aField->Name());
1268     if (!theOwn)
1269     {
1270       aSTEPName.Prepend (Express::ToStepName (Name().Cat (".")));
1271     }
1272     TCollection_AsciiString aVarName (aField->Name());
1273     if (!theOwn)
1274     {
1275       aVarName.Prepend (Name().Cat ("_"));
1276     }
1277     theOS << "\n";
1278     writeRWReadField (theOS, TCollection_AsciiString (aNum), aSTEPName, aVarName, aField->Type(), 0, aField->IsOptional());
1279     aNum++;
1280   }
1281
1282   return aNum;
1283 }
1284
1285 //=======================================================================
1286 // function : WriteRWWriteField
1287 // purpose  :
1288 //=======================================================================
1289
1290 static void writeRWWriteField (Standard_OStream& theOS,
1291                                const TCollection_AsciiString& theVarName,
1292                                const Handle(Express_Type)& theVarType,
1293                                const Standard_Integer theIndex,
1294                                const Standard_Integer theLevel)
1295 {
1296   // indent
1297   TCollection_AsciiString anIdent ("  ");
1298   Standard_Integer aLevel = 0;
1299   for (; aLevel < theLevel; aLevel++)
1300   {
1301     anIdent += "  ";
1302   }
1303   aLevel++;
1304
1305   // decode aliased types
1306   Handle(Express_Type) aType = theVarType;
1307   while (aType->IsKind (STANDARD_TYPE(Express_NamedType)))
1308   {
1309     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1310     if (!aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Alias)))
1311     {
1312       break;
1313     }
1314     Handle(Express_Alias) anAlias = Handle(Express_Alias)::DownCast (aNamedType->Item());
1315     aType = anAlias->Type();
1316   }
1317
1318   // write variable depending on its type
1319   if (aType->IsKind (STANDARD_TYPE(Express_ComplexType)))
1320   {
1321     Handle(Express_ComplexType) aComplex = Handle(Express_ComplexType)::DownCast (aType);
1322     aType = aComplex->Type();
1323     TCollection_AsciiString aVar (theLevel);
1324     aVar.Prepend ("aVar");
1325     theOS << anIdent << "theSW.OpenSub();\n" <<
1326              anIdent << "for (Standard_Integer i" << theIndex << " = 1; i" << theIndex << " <= ";
1327     if (aType->IsKind (STANDARD_TYPE(Express_ComplexType)))
1328     {
1329       // array 2
1330       Handle(Express_ComplexType) complex2 = Handle(Express_ComplexType)::DownCast (aType);
1331       aType = complex2->Type();
1332       theOS << theVarName << "->RowLength(); i" << theIndex << "++)\n" <<
1333                anIdent << "{\n" <<
1334                anIdent << "  theSW.NewLine(Standard_False);\n" <<
1335                anIdent << "  theSW.OpenSub();\n" <<
1336                anIdent << "  for (Standard_Integer j" << theIndex << " = 1; j" << theIndex << " <= " << theVarName << "->ColLength(); j" << theIndex << "++)\n" <<
1337                anIdent << "  {\n" <<
1338                anIdent << "  " << (aType->IsHandle() ? "  Handle(" : "  ") << aType->CPPName() << (aType->IsHandle() ? ") " : " ") << aVar << " = " << theVarName << "->Value (i" << theIndex << ", j" << theIndex << ");\n";
1339       writeRWWriteField (theOS, aVar, aType, theIndex + 1, aLevel + 1);
1340       theOS << anIdent << "  }\n" <<
1341                anIdent << "  theSW.CloseSub();\n";
1342     }
1343     else
1344     {
1345       // simple array
1346       theOS << theVarName << "->Length(); i" << theIndex << "++)\n" <<
1347                anIdent << "{\n" <<
1348                anIdent << (aType->IsHandle() ? "  Handle(" : "  ") << aType->CPPName() << (aType->IsHandle() ? ") " : " ") << aVar << " = " << theVarName << "->Value (i" << theIndex << ");\n";
1349       writeRWWriteField (theOS, aVar, aType, theIndex + 1, aLevel);
1350     }
1351     theOS << anIdent << "}\n" <<
1352              anIdent << "theSW.CloseSub();\n";
1353   }
1354   else if (aType->IsKind (STANDARD_TYPE(Express_Boolean)))
1355   {
1356     theOS << anIdent << "theSW.SendBoolean (" << theVarName << ");\n";
1357   }
1358   else if (aType->IsKind (STANDARD_TYPE(Express_Logical)))
1359   {
1360     theOS << anIdent << "theSW.SendLogical (" << theVarName << ");\n";
1361   }
1362   else
1363   {
1364     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1365     if (!aNamedType.IsNull() && aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Enum)))
1366     {
1367       Handle(Express_Enum) anEnum = Handle(Express_Enum)::DownCast (aNamedType->Item());
1368       TCollection_AsciiString aPrefix = Express::EnumPrefix (anEnum->Name());
1369       Handle(TColStd_HSequenceOfHAsciiString) aNames = anEnum->Names();
1370       TCollection_AsciiString anEnumPack = anEnum->GetPackageName();
1371       theOS << anIdent << "switch (" << theVarName << ")\n";
1372       theOS << anIdent << "{\n";
1373       for (Standard_Integer i = 1; i <= aNames->Length(); i++)
1374       {
1375         TCollection_AsciiString anEnumName = Express::ToStepName (aNames->Value (i)->String());
1376         anEnumName.UpperCase();
1377         theOS << anIdent << "  case " << anEnumPack << "_" << aPrefix << aNames->Value (i)->String() << ": theSW.SendEnum (\"." << anEnumName << ".\"); break;\n";
1378       }
1379       theOS << anIdent << "}\n";
1380     }
1381     else
1382     {
1383       theOS << anIdent << "theSW.Send (" << theVarName;
1384       if (!aNamedType.IsNull() && aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Select)))
1385       {
1386         theOS << ".Value()";
1387       }
1388       theOS << ");\n";
1389     }
1390   }
1391 }
1392
1393 //=======================================================================
1394 // function : WriteRWWriteCode
1395 // purpose  :
1396 //=======================================================================
1397
1398 Standard_Integer Express_Entity::writeRWWriteCode (Standard_OStream& theOS,
1399                                                    const Standard_Integer theStart,
1400                                                    const Standard_Integer theOwn) const
1401 {
1402   Standard_Integer aNum = theStart;
1403
1404   // write code for writing inherited fields
1405   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
1406   {
1407     aNum = myInherit->Value (i)->writeRWWriteCode (theOS, aNum, (i > 1 ? -1 : 1));
1408   }
1409
1410   // write code for writing own fields
1411   if (myFields->Length() > 0)
1412   {
1413     theOS << "\n"
1414              "  // " << (theOwn == 1 ? "Own" : "Inherited") << " fields of " << Name() << "\n";
1415   }
1416
1417   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
1418   {
1419     Handle(Express_Field) aField = myFields->Value (i);
1420     TCollection_AsciiString aVarName (aField->Name());
1421     if (!theOwn)
1422     {
1423       aVarName.Prepend (CPPName().Cat ("::"));
1424     }
1425     else if (theOwn == -1)
1426     {
1427       // inherited base class implemented as field
1428       aVarName.Prepend (Name().Cat ("()->"));
1429     }
1430     aVarName.Prepend ("theEnt->");
1431     aVarName += "()";
1432     theOS << "\n";
1433
1434     if (aField->IsOptional())
1435     {
1436       theOS << "  if (theEnt->";
1437       if (!theOwn)
1438       {
1439         theOS << CPPName() << "::";
1440       }
1441       else if (theOwn == -1)
1442       {
1443         theOS << Name() << "()->";
1444       }
1445       theOS << "Has" << aField->Name() << "())\n";
1446       theOS << "  {\n";
1447     }
1448     writeRWWriteField (theOS, aVarName, aField->Type(), aNum, (aField->IsOptional() ? 1 : 0));
1449     if (aField->IsOptional())
1450     {
1451       theOS << "  }\n"
1452                "  else\n"
1453                "  {\n"
1454                "    theSW.SendUndef();\n"
1455                "  }\n";
1456     }
1457     aNum++;
1458   }
1459
1460   return aNum;
1461 }
1462
1463 //=======================================================================
1464 // function : WriteRWShareField
1465 // purpose  :
1466 //=======================================================================
1467
1468 static Standard_Boolean writeRWShareField (Standard_OStream& theOS,
1469                                            const TCollection_AsciiString& theVarName,
1470                                            const Handle(Express_Type)& theVarType,
1471                                            const Standard_Integer theIndex,
1472                                            const Standard_Integer theLevel)
1473 {
1474   // indent
1475   TCollection_AsciiString anIdent ("  ");
1476   Standard_Integer aLevel = 0;
1477   for (; aLevel < theLevel; aLevel++)
1478   {
1479     anIdent += "  ";
1480   }
1481   aLevel++;
1482
1483   // decode aliased types
1484   Handle(Express_Type) aType = theVarType;
1485   while (aType->IsKind (STANDARD_TYPE(Express_NamedType)))
1486   {
1487     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1488     if (!aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Alias)))
1489     {
1490       break;
1491     }
1492     Handle(Express_Alias) anAlias = Handle(Express_Alias)::DownCast (aNamedType->Item());
1493     aType = anAlias->Type();
1494   }
1495
1496   // write variable depending on its type
1497   if (aType->IsKind (STANDARD_TYPE(Express_ComplexType)))
1498   {
1499     Handle(Express_ComplexType) aComplex = Handle(Express_ComplexType)::DownCast (aType);
1500     aType = aComplex->Type();
1501     TCollection_AsciiString aVar (theLevel);
1502     aVar.Prepend ("aVar");
1503     std::ostringstream aStringOS;
1504     if (!writeRWShareField (aStringOS, aVar, aType, theIndex + 1, aLevel))
1505     {
1506       return Standard_False;
1507     }
1508     theOS << anIdent << "for (Standard_Integer i" << theIndex << " = 1; i" << theIndex << " <= " << theVarName << "->Length(); i" << theIndex << "++)\n" <<
1509              anIdent << "{\n" <<
1510              anIdent << (aType->IsHandle() ? "  Handle(" : "  ") << aType->CPPName() << (aType->IsHandle() ? ") " : " ") << aVar << " = " << theVarName << "->Value (i" << theIndex << ");\n";
1511     theOS << aStringOS.str();
1512     theOS << anIdent << "}\n";
1513     return Standard_True;
1514   }
1515   if (aType->IsKind (STANDARD_TYPE(Express_NamedType)))
1516   {
1517     Handle(Express_NamedType) aNamedType = Handle(Express_NamedType)::DownCast (aType);
1518     if (aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Entity)))
1519     {
1520       theOS << anIdent << "theIter.AddItem (" << theVarName << ");\n";
1521       return Standard_True;
1522     }
1523     if (aNamedType->Item()->IsKind (STANDARD_TYPE(Express_Select)))
1524     {
1525       theOS << anIdent << "theIter.AddItem (" << theVarName << ".Value());\n";
1526       return Standard_True;
1527     }
1528   }
1529
1530   return Standard_False;
1531 }
1532
1533 //=======================================================================
1534 // function : WriteRWShareCode
1535 // purpose  :
1536 //=======================================================================
1537
1538 Standard_Integer Express_Entity::writeRWShareCode (Standard_OStream& theOS,
1539                                                    const Standard_Integer theStart,
1540                                                    const Standard_Integer theOwn) const
1541 {
1542   Standard_Integer aNum = theStart;
1543
1544   // write code for sharing inherited fields
1545   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
1546   {
1547     aNum = myInherit->Value (i)->writeRWShareCode (theOS, aNum, (i > 1 ? -1 : Standard_False));
1548   }
1549
1550   // write code for sharing own fields
1551   if (myFields->Length() > 0)
1552   {
1553     theOS << "\n"
1554              "  // " << (theOwn == 1 ? "Own" : "Inherited") << " fields of " << Name() << "\n";
1555   }
1556
1557   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
1558   {
1559     Handle(Express_Field) aField = myFields->Value (i);
1560     TCollection_AsciiString aVarName (aField->Name());
1561     if (!theOwn)
1562     {
1563       aVarName.Prepend (CPPName().Cat ("::"));
1564     }
1565     else if (theOwn == -1)
1566     {
1567       // inherited base class implemented as field
1568       aVarName.Prepend (Name().Cat ("()->"));
1569     }
1570     aVarName.Prepend ("theEnt->");
1571     aVarName += "()";
1572
1573     std::ostringstream aStringOS;
1574     if (!writeRWShareField (aStringOS, aVarName, aField->Type(), aNum, (aField->IsOptional() ? 1 : 0)))
1575     {
1576       continue;
1577     }
1578     aNum++;
1579     theOS << "\n";
1580     if (aField->IsOptional())
1581     {
1582       theOS << "  if (theEnt->";
1583       if (!theOwn)
1584         theOS << CPPName() << "::";
1585       else if (theOwn == -1)
1586         theOS << Name() << "()->";
1587       theOS << "Has" << aField->Name() << "())\n"
1588                "  {\n";
1589     }
1590     theOS << aStringOS.str();
1591     if (aField->IsOptional())
1592     {
1593       theOS << "  }\n";
1594     }
1595   }
1596
1597   return aNum;
1598 }
1599
1600 //=======================================================================
1601 // function : MakeInit
1602 // purpose  :
1603 //=======================================================================
1604
1605 Standard_Integer Express_Entity::makeInit (Standard_OStream& theOS,
1606                                            const Standard_Integer theShift,
1607                                            const Standard_Integer theOwn,
1608                                            const Standard_Integer theMode) const
1609 {
1610   Standard_Integer aShift = theShift;
1611
1612   // write code for inherited fields
1613   for (Standard_Integer i = 1; i <= myInherit->Length(); i++)
1614   {
1615     Handle(Express_Entity) anEntity = myInherit->Value (i);
1616     const TCollection_AsciiString& anEntityCPPName = anEntity->CPPName();
1617     if (theMode == 3)
1618     {
1619       Standard_Integer aShift2 = 0;
1620       if (i > 1)
1621       {
1622         theOS << "\n  my" << anEntity->Name() << " = new " << anEntityCPPName << ";"
1623                  "\n  my" << anEntity->Name() << "->Init (";
1624         aShift2 = 12 + anEntity->Name().Length();
1625       }
1626       else
1627       {
1628         theOS << "\n  " << anEntityCPPName << "::Init (";
1629         aShift2 = 10 + anEntityCPPName.Length();
1630       }
1631       anEntity->makeInit (theOS, aShift2, Standard_False, 2);
1632       theOS << ");";
1633     }
1634     else
1635     {
1636       aShift = anEntity->makeInit (theOS, aShift, (i > 1 ? -1 : Standard_False), theMode);
1637     }
1638   }
1639
1640   // write code for own fields
1641   for (Standard_Integer i = 1; i <= myFields->Length(); i++)
1642   {
1643     Handle(Express_Field) aField = myFields->Value (i);
1644     Handle(Express_Type) aFieldType = aField->Type();
1645     TCollection_AsciiString aVarName(aField->Name());
1646     if (theOwn != 1)
1647     {
1648       aVarName.Prepend (Name().Cat ("_"));
1649     }
1650
1651     // make CR and indent
1652     TCollection_AsciiString aSpaces = "";
1653     for (Standard_Integer aSpaceNum = 0; aSpaceNum < abs (aShift); aSpaceNum++)
1654     {
1655       aSpaces += " ";
1656     }
1657     Standard_Character aDelim = (theMode == 0 ? ',' : (theMode == 3 ? '\n' : ','));
1658     if (aShift < 0)
1659     {
1660       if (i == 1 && myInherit->Length() == 0 && theMode == 3)
1661       {
1662         theOS << aDelim << aSpaces;
1663       }
1664       else if (theMode == 4)
1665       {
1666         theOS << ", ";
1667       }
1668       else
1669       {
1670         theOS << aDelim << "\n" << aSpaces;
1671       }
1672     }
1673     else
1674     {
1675       aShift = -aShift;
1676     }
1677
1678     if (aField->IsOptional())
1679     {
1680       if (theMode == 0)
1681       {
1682         theOS << "const Standard_Boolean theHas" << aVarName << ",\n" << aSpaces;
1683       }
1684       else if (theMode == 1)
1685       {
1686         theOS << "const Standard_Boolean theHas" << aVarName << ",\n" << aSpaces;
1687       }
1688       else if (theMode == 2)
1689       {
1690         theOS << "has" << aVarName << ",\n" << aSpaces;
1691       }
1692       else if (theMode == 4)
1693       {
1694         theOS << "has" << aVarName << ", ";
1695       }
1696     }
1697
1698     // write field
1699     if (theMode == 0 || theMode == 1)
1700     {
1701       theOS << "const " << (aFieldType->IsHandle() ? "Handle(" : "") << aFieldType->CPPName() << (aFieldType->IsHandle() ? ")" : "") <<
1702                (aFieldType->IsSimple() ? " the" : "& the") << aVarName;
1703     }
1704     else if (theMode == 2)
1705     {
1706       theOS << "the" << aVarName;
1707     }
1708     else if (theMode == 4)
1709     {
1710       theOS << "a" << aVarName;
1711     }
1712     else
1713     {
1714       if (aField->IsOptional())
1715       {
1716         theOS << "myHas" << aField->Name() << " = theHas" << aVarName << ";\n"
1717                  "  if (myHas" << aField->Name() << ")\n"
1718                  "  {\n"
1719                  "    my" << aField->Name() << " = the" << aVarName << ";\n"
1720                  "  }\n"
1721                  "  else\n"
1722                  "  {\n"
1723                  "    my" << aField->Name();
1724         if (aFieldType->IsHandle())
1725         {
1726           theOS << ".Nullify();";
1727         }
1728         else if (aFieldType->IsStandard())
1729         {
1730           theOS << " = 0;";
1731         }
1732         else
1733         {
1734           theOS << " = " << aFieldType->CPPName() << "();";
1735         }
1736         theOS << "\n  }";
1737       }
1738       else
1739       {
1740         theOS << "my" << aField->Name() << " = the" << aVarName << ";";
1741       }
1742     }
1743     if (aShift > 0)
1744     {
1745       aShift = -aShift;
1746     }
1747   }
1748
1749   return aShift;
1750 }
1751
1752 //=======================================================================
1753 // function : SetAbstractFlag
1754 // purpose  :
1755 //=======================================================================
1756
1757 void Express_Entity::SetAbstractFlag (const Standard_Boolean isAbstract)
1758 {
1759   myIsAbstract = isAbstract;
1760 }
1761
1762 //=======================================================================
1763 // function : AbstractFlag
1764 // purpose  :
1765 //=======================================================================
1766
1767 Standard_Boolean Express_Entity::AbstractFlag() const
1768 {
1769   return myIsAbstract;
1770 }