0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / PCDM / PCDM_ReaderFilter.cxx
1 // Copyright (c) 2021 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <PCDM_ReaderFilter.hxx>
16
17 IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReaderFilter,Standard_Transient)
18
19 PCDM_ReaderFilter::PCDM_ReaderFilter (const Handle(Standard_Type)& theSkipped) : myAppend (AppendMode_Forbid)
20 {
21   mySkip.Add(theSkipped->Name());
22 }
23
24 PCDM_ReaderFilter::PCDM_ReaderFilter (const TCollection_AsciiString& theEntryToRead) : myAppend (AppendMode_Forbid)
25 {
26   mySubTrees.Append(theEntryToRead);
27 }
28
29 PCDM_ReaderFilter::PCDM_ReaderFilter (const AppendMode theAppend) : myAppend (theAppend)
30 {}
31
32 void PCDM_ReaderFilter::Clear()
33 {
34   mySkip.Clear();
35   myRead.Clear();
36   mySubTrees.Clear();
37 }
38
39 PCDM_ReaderFilter::~PCDM_ReaderFilter()
40 {
41   ClearTree();
42 }
43
44 Standard_Boolean PCDM_ReaderFilter::IsPassed (const Handle(Standard_Type)& theAttributeID) const
45 {
46   return IsPassedAttr(theAttributeID->Name());
47 }
48
49 Standard_Boolean PCDM_ReaderFilter::IsPassedAttr (const TCollection_AsciiString& theAttributeType) const
50 {
51   return myRead.IsEmpty() ? !mySkip.Contains (theAttributeType) :
52                              myRead.Contains (theAttributeType);
53 }
54
55 Standard_Boolean PCDM_ReaderFilter::IsPassed (const TCollection_AsciiString& theEntry) const
56 {
57   if (mySubTrees.IsEmpty())
58     return true;
59   for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
60   {
61     if (theEntry.StartsWith (anEntry.Value()))
62     {
63       if (theEntry.Length() > anEntry.Value().Length() &&
64           theEntry.Value (anEntry.Value().Length() + 1) != ':')  // case when theEntry="0:10" should not match "0:1"
65         continue;
66       return true;
67     }
68   }
69   return false;
70 }
71
72 Standard_Boolean PCDM_ReaderFilter::IsSubPassed (const TCollection_AsciiString& theEntry) const
73 {
74   if (mySubTrees.IsEmpty() || theEntry.Length() == 2) // root is always passed if any sub is defined
75     return true;
76   for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
77   {
78     if (theEntry.Length() < anEntry.Value().Length() &&
79         anEntry.Value().Value (theEntry.Length() + 1) == ':' && // case when theEntry="0:1" should not match "0:10"
80         anEntry.Value().StartsWith (theEntry))
81       return true;
82   }
83   return false;
84 }
85
86 Standard_Boolean PCDM_ReaderFilter::IsPartTree()
87 {
88   return !(mySubTrees.IsEmpty() || (mySubTrees.Size() == 1 && mySubTrees.First().Length() < 3));
89 }
90
91 void PCDM_ReaderFilter::StartIteration()
92 {
93   myCurrent = &myTree;
94   myCurrentDepth = 0;
95   ClearTree();
96   myTree.Bind(-1, NULL);
97   if (mySubTrees.IsEmpty())
98     return;
99   // create an iteration-tree by the mySubTrees entries
100   for (NCollection_List<TCollection_AsciiString>::Iterator aTreeIter (mySubTrees); aTreeIter.More(); aTreeIter.Next())
101   {
102     TagTree* aMap = &myTree;
103     TCollection_AsciiString aTagStr, anEntry = aTreeIter.Value();
104     for (Standard_Integer aTagIndex = 2; !anEntry.IsEmpty(); ++aTagIndex) // skip the root tag
105     {
106       aTagStr = anEntry.Token(":", aTagIndex);
107       if (aTagStr.IsEmpty())
108         break;
109       Standard_Integer aTag = aTagStr.IntegerValue();
110       if (aMap->IsBound (aTag))
111       {
112         aMap = (TagTree*)aMap->Find (aTag);
113       }
114       else
115       {
116         TagTree* aNewMap = new TagTree;
117         aNewMap->Bind (-1, aMap); // to be able to iterate up, keep father map in the child
118         aMap->Bind (aTag, aNewMap);
119         aMap = aNewMap;
120       }
121     }
122     aMap->Bind (-2, NULL); // identifier that this node is in subtrees definition
123   }
124 }
125
126 void PCDM_ReaderFilter::Up()
127 {
128   if (myCurrentDepth == 0)
129     myCurrent = (TagTree*)myCurrent->Find(-1);
130   else
131     myCurrentDepth--;
132 }
133
134 void PCDM_ReaderFilter::Down (const int& theTag)
135 {
136   if (myCurrentDepth== 0)
137   {
138     if (myCurrent->IsBound (theTag))
139       myCurrent= (TagTree*)myCurrent->Find (theTag);
140     else
141       ++myCurrentDepth;
142   }
143   else
144     ++myCurrentDepth;
145 }
146
147 Standard_Boolean PCDM_ReaderFilter::IsPassed() const
148 {
149   return myCurrent->IsBound(-2);
150 }
151
152 Standard_Boolean PCDM_ReaderFilter::IsSubPassed() const
153 {
154   return myCurrentDepth == 0;
155 }
156
157 void PCDM_ReaderFilter::ClearSubTree (const Standard_Address theMap)
158 {
159   if (theMap)
160   {
161     TagTree* aMap = (TagTree*)theMap;
162     for (TagTree::Iterator aTagIter (*aMap); aTagIter.More(); aTagIter.Next())
163       if (aTagIter.Key() != -1)
164         ClearSubTree (aTagIter.Value());
165     delete aMap;
166   }
167 }
168
169 void PCDM_ReaderFilter::ClearTree()
170 {
171   for (TagTree::Iterator aTagIter (myTree); aTagIter.More(); aTagIter.Next())
172     if (aTagIter.Key() != -1)
173       ClearSubTree (aTagIter.Value());
174   myTree.Clear();
175 }