1 // Created on: 1992-02-11
2 // Created by: Christian CAILLET
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 #ifndef _StepData_StepReaderData_HeaderFile
18 #define _StepData_StepReaderData_HeaderFile
19 
20 #include <Standard.hxx>
21 #include <Standard_Type.hxx>
22 #include <Resource_FormatType.hxx>
23 
24 #include <TColStd_Array1OfInteger.hxx>
25 #include <Interface_IndexedMapOfAsciiString.hxx>
26 #include <TColStd_DataMapOfIntegerInteger.hxx>
27 #include <Standard_Integer.hxx>
28 #include <Interface_FileReaderData.hxx>
29 #include <Standard_CString.hxx>
30 #include <Interface_ParamType.hxx>
31 #include <Standard_Boolean.hxx>
32 #include <TColStd_SequenceOfAsciiString.hxx>
33 #include <Standard_Real.hxx>
34 #include <Standard_Type.hxx>
35 #include <StepData_Logical.hxx>
36 class Interface_Check;
37 class TCollection_AsciiString;
38 class StepData_PDescr;
39 class Standard_Transient;
40 class StepData_SelectMember;
41 class StepData_Field;
42 class StepData_ESDescr;
43 class StepData_FieldList;
44 class StepData_SelectType;
45 class TCollection_HAsciiString;
46 class StepData_EnumTool;
47 
48 
49 class StepData_StepReaderData;
50 DEFINE_STANDARD_HANDLE(StepData_StepReaderData, Interface_FileReaderData)
51 
52 //! Specific FileReaderData for Step
53 //! Contains literal description of entities (for each one : type
54 //! as a string, ident, parameter list)
55 //! provides references evaluation, plus access to literal data
56 //! and specific access methods (Boolean, XY, XYZ)
57 class StepData_StepReaderData : public Interface_FileReaderData
58 {
59 
60 public:
61 
62 
63   //! creates StepReaderData correctly dimensionned (necessary at
64   //! creation time, because it contains arrays)
65   //! nbheader is nb of records for Header, nbtotal for Header+Data
66   //! and nbpar gives the total count of parameters
67   Standard_EXPORT StepData_StepReaderData(const Standard_Integer nbheader, const Standard_Integer nbtotal, const Standard_Integer nbpar, const Resource_FormatType theSourceCodePage = Resource_FormatType_UTF8);
68 
69   //! Fills the fields of a record
70   Standard_EXPORT void SetRecord (const Standard_Integer num, const Standard_CString ident, const Standard_CString type, const Standard_Integer nbpar);
71 
72   //! Fills the fields of a parameter of a record. This is a variant
73   //! of AddParam, Adapted to STEP (optimized for specific values)
74   Standard_EXPORT void AddStepParam (const Standard_Integer num, const Standard_CString aval, const Interface_ParamType atype, const Standard_Integer nument = 0);
75 
76   //! Returns Record Type
77   Standard_EXPORT const TCollection_AsciiString& RecordType (const Standard_Integer num) const;
78 
79   //! Returns Record Type as a CString
80   //! was C++ : return const
81   Standard_EXPORT Standard_CString CType (const Standard_Integer num) const;
82 
83   //! Returns record identifier (Positive number)
84   //! If returned ident is not positive : Sub-List or Scope mark
85   Standard_EXPORT Standard_Integer RecordIdent (const Standard_Integer num) const;
86 
87   //! Returns SubList numero designated by a parameter (nump) in a
88   //! record (num), or zero if the parameter does not exist or is
89   //! not a SubList address. Zero too If aslast is True and nump
90   //! is not for the last parameter
91   Standard_EXPORT Standard_Integer SubListNumber (const Standard_Integer num, const Standard_Integer nump, const Standard_Boolean aslast) const;
92 
93   //! Returns True if <num> corresponds to a Complex Type Entity
94   //! (as can be defined by ANDOR Express clause)
95   Standard_EXPORT Standard_Boolean IsComplex (const Standard_Integer num) const;
96 
97   //! Returns the List of Types which correspond to a Complex Type
98   //! Entity. If not Complex, there is just one Type in it
99   //! For a SubList or a Scope mark, <types> remains empty
100   Standard_EXPORT void ComplexType (const Standard_Integer num, TColStd_SequenceOfAsciiString& types) const;
101 
102   //! Returns the Next "Component" for a Complex Type Entity, of
103   //! which <num> is already a Component (the first one or a next one)
104   //! Returns 0 for a Simple Type or for the last Component
105   Standard_EXPORT Standard_Integer NextForComplex (const Standard_Integer num) const;
106 
107   //! Determines the first component which brings a given name, for
108   //! a Complex Type Entity
109   //! <num0> is the very first record of this entity
110   //! <num> is given the last NextNamedForComplex, starts at zero
111   //! it is returned as the newly found number
112   //! Hence, in the normal case, NextNamedForComplex starts by num0
113   //! if <num> is zero, else by NextForComplex(num)
114   //! If the alphabetic order is not respected, it restarts from
115   //! num0 and loops on NextForComplex until finding <name>
116   //! In case of "non-alphabetic order", <ach> is filled with a
117   //! Warning for this name
118   //! In case of "not-found at all", <ach> is filled with a Fail,
119   //! and <num> is returned as zero
120   //!
121   //! Returns True if alphabetic order, False else
122   Standard_EXPORT Standard_Boolean NamedForComplex (const Standard_CString name, const Standard_Integer num0, Standard_Integer& num, Handle(Interface_Check)& ach) const;
123 
124   //! Determines the first component which brings a given name, or
125   //! short name for a Complex Type Entity
126   //! <num0> is the very first record of this entity
127   //! <num> is given the last NextNamedForComplex, starts at zero
128   //! it is returned as the newly found number
129   //! Hence, in the normal case, NextNamedForComplex starts by num0
130   //! if <num> is zero, else by NextForComplex(num)
131   //! If the alphabetic order is not respected, it restarts from
132   //! num0 and loops on NextForComplex until finding <name>
133   //! In case of "non-alphabetic order", <ach> is filled with a
134   //! Warning for this name
135   //! In case of "not-found at all", <ach> is filled with a Fail,
136   //! and <num> is returned as zero
137   //!
138   //! Returns True if alphabetic order, False else
139   Standard_EXPORT Standard_Boolean NamedForComplex (const Standard_CString theName, const Standard_CString theShortName, const Standard_Integer num0, Standard_Integer& num, Handle(Interface_Check)& ach) const;
140 
141   //! Checks Count of Parameters of record <num> to equate <nbreq>
142   //! If this Check is successful, returns True
143   //! Else, fills <ach> with an Error Message then returns False
144   //! <mess> is included in the Error message if given non empty
145   Standard_EXPORT Standard_Boolean CheckNbParams (const Standard_Integer num, const Standard_Integer nbreq, Handle(Interface_Check)& ach, const Standard_CString mess = "") const;
146 
147   //! reads parameter <nump> of record <num> as a sub-list (may be
148   //! typed, see ReadTypedParameter in this case)
149   //! Returns True if OK. Else (not a LIST), returns false and
150   //! feeds Check with appropriate check
151   //! If <optional> is True and Param is not defined, returns True
152   //! with <ach> not filled and <numsub> returned as 0
153   //! Works with SubListNumber with <aslast> false (no specific case
154   //! for last parameter)
155   Standard_EXPORT Standard_Boolean ReadSubList (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Integer& numsub, const Standard_Boolean optional = Standard_False, const Standard_Integer lenmin = 0, const Standard_Integer lenmax = 0) const;
156 
157   //! reads the content of a sub-list into a transient :
158   //! SelectNamed, or HArray1 of Integer,Real,String,Transient ...
159   //! recursive call if list of list ...
160   //! If a sub-list has mixed types, an HArray1OfTransient is
161   //! produced, it may contain SelectMember
162   //! Intended to be called by ReadField
163   //! The returned status is : negative if failed, 0 if empty.
164   //! Else the kind to be recorded in the field
165   Standard_EXPORT Standard_Integer ReadSub (const Standard_Integer numsub, const Standard_CString mess, Handle(Interface_Check)& ach, const Handle(StepData_PDescr)& descr, Handle(Standard_Transient)& val) const;
166 
167   //! Reads parameter <nump> of record <num> into a SelectMember,
168   //! self-sufficient (no Description needed)
169   //! If <val> is already created, it will be filled, as possible
170   //! And if reading does not match its own description, the result
171   //! will be False
172   //! If <val> is not it not yet created, it will be (SelectNamed)
173   //! useful if a field is defined as a SelectMember, directly
174   //! (SELECT with no Entity as member)
175   //! But SelectType also manages SelectMember (for SELECT with
176   //! some members as Entity, some other not)
177   Standard_EXPORT Standard_Boolean ReadMember (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Handle(StepData_SelectMember)& val) const;
178 
179   //! Safe variant for arbitrary type of argument
180   template <class T>
ReadMember(const Standard_Integer num,const Standard_Integer nump,const Standard_CString mess,Handle (Interface_Check)& ach,Handle (T)& val) const181   Standard_Boolean ReadMember (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Handle(T)& val) const
182   {
183     Handle(StepData_SelectMember) aVal = val;
184     return ReadMember (num, nump, mess, ach, aVal) && ! (val = Handle(T)::DownCast(aVal)).IsNull();
185   }
186 
187   //! reads parameter <nump> of record <num> into a Field,
188   //! controlled by a Parameter Descriptor (PDescr), which controls
189   //! its allowed type(s) and value
190   //! <ach> is filled if the read parameter does not match its
191   //! description (but the field is read anyway)
192   //! If the description is not defined, no control is done
193   //! Returns True when done
194   Standard_EXPORT Standard_Boolean ReadField (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const Handle(StepData_PDescr)& descr, StepData_Field& fild) const;
195 
196   //! reads a list of fields controlled by an ESDescr
197   Standard_EXPORT Standard_Boolean ReadList (const Standard_Integer num, Handle(Interface_Check)& ach, const Handle(StepData_ESDescr)& descr, StepData_FieldList& list) const;
198 
199   //! Reads parameter <nump> of record <num> into a Transient Value
200   //! according to the type of the parameter :
201   //! Named for Integer,Boolean,Logical,Enum,Real : SelectNamed
202   //! Immediate Integer,Boolean,Logical,Enum,Real : SelectInt/Real
203   //! Text  : HAsciiString
204   //! Ident : the referenced Entity
205   //! Sub-List not processed, see ReadSub
206   //! This value is controlled by a Parameter Descriptor (PDescr),
207   //! which controls its allowed type and value
208   //! <ach> is filled if the read parameter does not match its
209   //! description (the select is nevertheless created if possible)
210   //!
211   //! Warning : val is in out, hence it is possible to predefine a specific
212   //! SelectMember then to fill it. If <val> is Null or if the
213   //! result is not a SelectMember, val itself is returned a new ref
214   //! For a Select with a Name, <val> must then be a SelectNamed
215   Standard_EXPORT Standard_Boolean ReadAny (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const Handle(StepData_PDescr)& descr, Handle(Standard_Transient)& val) const;
216 
217   //! reads parameter <nump> of record <num> as a sub-list of
218   //! two Reals X,Y. Returns True if OK. Else, returns false and
219   //! feeds Check with appropriate Fails (parameter not a sub-list,
220   //! not two Reals in the sub-list) composed with "mess" which
221   //! gives the name of the parameter
222   Standard_EXPORT Standard_Boolean ReadXY (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Real& X, Standard_Real& Y) const;
223 
224   //! reads parameter <nump> of record <num> as a sub-list of
225   //! three Reals X,Y,Z. Return value and Check managed as by
226   //! ReadXY (demands a sub-list of three Reals)
227   Standard_EXPORT Standard_Boolean ReadXYZ (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const;
228 
229   //! reads parameter <nump> of record <num> as a single Real value.
230   //! Return value and Check managed as by ReadXY (demands a Real)
231   Standard_EXPORT Standard_Boolean ReadReal (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Real& val) const;
232 
233   //! Reads parameter <nump> of record <num> as a single Entity.
234   //! Return value and Check managed as by ReadReal (demands a
235   //! reference to an Entity). In Addition, demands read Entity
236   //! to be Kind of a required Type <atype>.
237   //! Remark that returned status is False and <ent> is Null if
238   //! parameter is not an Entity, <ent> remains Not Null is parameter
239   //! is an Entity but is not Kind of required type
240   Standard_EXPORT Standard_Boolean ReadEntity (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const Handle(Standard_Type)& atype, Handle(Standard_Transient)& ent) const;
241 
242   //! Safe variant for arbitrary type of argument
243   template <class T>
ReadEntity(const Standard_Integer num,const Standard_Integer nump,const Standard_CString mess,Handle (Interface_Check)& ach,const Handle (Standard_Type)& atype,Handle (T)& ent) const244   Standard_Boolean ReadEntity (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const Handle(Standard_Type)& atype, Handle(T)& ent) const
245   {
246     Handle(Standard_Transient) anEnt = ent;
247     return ReadEntity (num, nump, mess, ach, atype, anEnt) && ! (ent = Handle(T)::DownCast(anEnt)).IsNull();
248   }
249 
250   //! Same as above, but a SelectType checks Type Matching, and
251   //! records the read Entity (see method Value from SelectType)
252   Standard_EXPORT Standard_Boolean ReadEntity (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, StepData_SelectType& sel) const;
253 
254   //! reads parameter <nump> of record <num> as a single Integer.
255   //! Return value & Check managed as by ReadXY (demands an Integer)
256   Standard_EXPORT Standard_Boolean ReadInteger (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Integer& val) const;
257 
258   //! reads parameter <nump> of record <num> as a Boolean
259   //! Return value and Check managed as by ReadReal (demands a
260   //! Boolean enum, i.e. text ".T." for True or ".F." for False)
261   Standard_EXPORT Standard_Boolean ReadBoolean (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Boolean& flag) const;
262 
263   //! reads parameter <nump> of record <num> as a Logical
264   //! Return value and Check managed as by ReadBoolean (demands a
265   //! Logical enum, i.e. text ".T.", ".F.", or ".U.")
266   Standard_EXPORT Standard_Boolean ReadLogical (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, StepData_Logical& flag) const;
267 
268   //! reads parameter <nump> of record <num> as a String (text
269   //! between quotes, quotes are removed by the Read operation)
270   //! Return value and Check managed as by ReadXY (demands a String)
271   Standard_EXPORT Standard_Boolean ReadString (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Handle(TCollection_HAsciiString)& val) const;
272 
273   Standard_EXPORT Standard_Boolean ReadEnumParam (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_CString& text) const;
274 
275   //! Fills a check with a fail message if enumeration value does
276   //! match parameter definition
277   //! Just a help to centralize message definitions
278   Standard_EXPORT void FailEnumValue (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach) const;
279 
280   //! Reads parameter <nump> of record <num> as an Enumeration (text
281   //! between dots) and converts it to an integer value, by an
282   //! EnumTool. Returns True if OK, false if : this parameter is not
283   //! enumeration, or is not recognized by the EnumTool (with fail)
284   Standard_EXPORT Standard_Boolean ReadEnum (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const StepData_EnumTool& enumtool, Standard_Integer& val) const;
285 
286   //! Resolves a parameter which can be enclosed in a type def., as
287   //! TYPE(val). The parameter must then be read normally according
288   //! its type.  Parameter to be resolved is <nump> of record <num>
289   //! <mustbetyped> True  demands a typed parameter
290   //! <mustbetyped> False accepts a non-typed parameter as option
291   //! mess and ach as usual
292   //! <numr>,<numrp> are the resolved record and parameter numbers
293   //! = num,nump if no type,  else numrp=1
294   //! <typ> returns the recorded type, or empty string
295   //! Remark : a non-typed list is considered as "non-typed"
296   Standard_EXPORT Standard_Boolean ReadTypedParam (const Standard_Integer num, const Standard_Integer nump, const Standard_Boolean mustbetyped, const Standard_CString mess, Handle(Interface_Check)& ach, Standard_Integer& numr, Standard_Integer& numrp, TCollection_AsciiString& typ) const;
297 
298   //! Checks if parameter <nump> of record <num> is given as Derived
299   //! If this Check is successful (i.e. Param = "*"), returns True
300   //! Else, fills <ach> with a Message which contains <mess> and
301   //! returns False. According to <errstat>, this message is Warning
302   //! if errstat is False (Default), Fail if errstat is True
303   Standard_EXPORT Standard_Boolean CheckDerived (const Standard_Integer num, const Standard_Integer nump, const Standard_CString mess, Handle(Interface_Check)& ach, const Standard_Boolean errstat = Standard_False) const;
304 
305   //! Returns total count of Entities (including Header)
306   Standard_EXPORT virtual Standard_Integer NbEntities() const Standard_OVERRIDE;
307 
308   //! determines the first suitable record following a given one
309   //! that is, skips SCOPE,ENDSCOPE and SUBLIST records
310   //! Note : skips Header records, which are accessed separately
311   Standard_EXPORT Standard_Integer FindNextRecord (const Standard_Integer num) const Standard_OVERRIDE;
312 
313   //! determines reference numbers in EntityNumber fields
314   //! called by Prepare from StepReaderTool to prepare later using
315   //! by a StepModel. This method is attached to StepReaderData
316   //! because it needs a massive amount of data accesses to work
317   //!
318   //! If <withmap> is given False, the basic exploration algorithm
319   //! is activated, otherwise a map is used as far as it is possible
320   //! this option can be used only to test this algorithm
321   Standard_EXPORT void SetEntityNumbers (const Standard_Boolean withmap = Standard_True);
322 
323   //! determine first suitable record of Header
324   //! works as FindNextRecord, but treats only Header records
325   Standard_EXPORT Standard_Integer FindNextHeaderRecord (const Standard_Integer num) const;
326 
327   //! Works as SetEntityNumbers but for Header : more simple because
328   //! there are no Reference, only Sub-Lists
329   Standard_EXPORT void PrepareHeader();
330 
331   //! Returns the Global Check. It can record Fail messages about
332   //! Undefined References (detected by SetEntityNumbers)
333   Standard_EXPORT const Handle(Interface_Check) GlobalCheck() const;
334 
335 
336 
337 
338   DEFINE_STANDARD_RTTIEXT(StepData_StepReaderData,Interface_FileReaderData)
339 
340 protected:
341 
342 
343 
344 
345 private:
346 
347 
348   //! Searches for a Parameter of the record <num>, which refers to
349   //! the Ident <id> (form #nnn). [Used by SetEntityNumbers]
350   //! If found, returns its EntityNumber, else returns Zero.
351   Standard_EXPORT Standard_Integer FindEntityNumber (const Standard_Integer num, const Standard_Integer id) const;
352 
353   //! Prepare string to use in OCCT exchange structure.
354   //! If code page is Resource_FormatType_NoConversion,
355   //! clean only special characters without conversion;
356   //! else convert a string to UTF8 using the code page
357   //! and handle the control directives.
358   Standard_EXPORT void cleanText(const Handle(TCollection_HAsciiString)& theVal) const;
359 
360 private:
361 
362 
363   TColStd_Array1OfInteger theidents;
364   TColStd_Array1OfInteger thetypes;
365   Interface_IndexedMapOfAsciiString thenametypes;
366   TColStd_DataMapOfIntegerInteger themults;
367   Standard_Integer thenbents;
368   Standard_Integer thelastn;
369   Standard_Integer thenbhead;
370   Standard_Integer thenbscop;
371   Handle(Interface_Check) thecheck;
372   Resource_FormatType mySourceCodePage;
373 
374 
375 };
376 
377 
378 
379 
380 
381 
382 
383 #endif // _StepData_StepReaderData_HeaderFile
384