0024870: Provide OCCT RTTI test cases
[occt.git] / src / XmlMFunction / XmlMFunction_ScopeDriver.cxx
1 // Created on: 2008-03-05
2 // Created by: Vlad ROMASHKO
3 // Copyright (c) 2008-2014 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
17 #include <CDM_MessageDriver.hxx>
18 #include <LDOM_MemManager.hxx>
19 #include <Standard_Type.hxx>
20 #include <TColStd_ListIteratorOfListOfInteger.hxx>
21 #include <TColStd_ListOfInteger.hxx>
22 #include <TDF_Attribute.hxx>
23 #include <TDF_Label.hxx>
24 #include <TDF_LabelList.hxx>
25 #include <TDF_ListIteratorOfLabelList.hxx>
26 #include <TDF_Tool.hxx>
27 #include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx>
28 #include <TFunction_Scope.hxx>
29 #include <XmlMFunction_ScopeDriver.hxx>
30 #include <XmlObjMgt.hxx>
31 #include <XmlObjMgt_Document.hxx>
32 #include <XmlObjMgt_Persistent.hxx>
33
34 IMPLEMENT_DOMSTRING (LastIDIndex,    "lastid")
35 IMPLEMENT_DOMSTRING (LastLabelIndex, "lastlabel")
36
37 IMPLEMENT_DOMSTRING (ExtString,      "string")
38
39 //=======================================================================
40 //function : XmlMFunction_ScopeDriver
41 //purpose  : Constructor
42 //=======================================================================
43 XmlMFunction_ScopeDriver::XmlMFunction_ScopeDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
44       : XmlMDF_ADriver (theMsgDriver, NULL)
45 {
46
47 }
48
49 //=======================================================================
50 //function : NewEmpty
51 //purpose  : 
52 //=======================================================================
53 Handle(TDF_Attribute) XmlMFunction_ScopeDriver::NewEmpty() const
54 {
55   return (new TFunction_Scope());
56 }
57
58 //=======================================================================
59 //function : Paste
60 //purpose  : persistent -> transient (retrieve)
61 //=======================================================================
62 Standard_Boolean XmlMFunction_ScopeDriver::Paste(const XmlObjMgt_Persistent&  theSource,
63                                                  const Handle(TDF_Attribute)& theTarget,
64                                                  XmlObjMgt_RRelocationTable&  ) const
65 {
66   Handle(TFunction_Scope) S = Handle(TFunction_Scope)::DownCast(theTarget);
67   TColStd_ListOfInteger   IDs;
68   TDF_LabelList           Labels;
69
70   Standard_Integer aFirstInd, aLastInd, aValue, ind, nbIDs = 0, nbLabels = 0;
71   const XmlObjMgt_Element& anElement = theSource;
72
73   // IDs
74   // ===
75
76   // Read the FirstIndex; if the attribute is absent initialize to 1
77   aFirstInd = 1;
78
79   // Read the LastIndex; the attribute should present
80   if (!anElement.getAttribute(::LastIDIndex()).GetInteger(aLastInd)) 
81   {
82     TCollection_ExtendedString aMessageString =
83       TCollection_ExtendedString("Cannot retrieve the last index"
84                                  " for Scope attribute");
85     WriteMessage (aMessageString);
86     return Standard_False;
87   }
88   nbIDs = aLastInd - aFirstInd + 1;
89
90   if (aFirstInd == aLastInd) 
91   {
92     Standard_Integer anInteger;
93     if (!XmlObjMgt::GetStringValue(anElement).GetInteger(anInteger)) 
94     {
95       TCollection_ExtendedString aMessageString =
96         TCollection_ExtendedString("Cannot retrieve integer member"
97                                    " for Scope attribute as \"");
98       WriteMessage (aMessageString);
99       return Standard_False;
100     }
101     IDs.Append(anInteger);
102   }
103   else 
104   {
105     Standard_CString aValueStr =
106       Standard_CString(XmlObjMgt::GetStringValue(anElement).GetString());
107     
108     for (ind = aFirstInd; ind <= aLastInd; ind++)
109     {
110       if (!XmlObjMgt::GetInteger(aValueStr, aValue)) 
111       {
112         TCollection_ExtendedString aMessageString =
113           TCollection_ExtendedString("Cannot retrieve integer member"
114                                      " for Scope attribute as \"")
115             + aValueStr + "\"";
116         WriteMessage (aMessageString);
117         return Standard_False;
118       }
119       IDs.Append(aValue);
120     }
121   }
122
123
124   // Labels
125   // ======
126
127   aFirstInd = 1;
128
129   // Read the LastIndex; the attribute should present
130   if (!anElement.getAttribute(::LastLabelIndex()).GetInteger(aLastInd)) 
131   {
132     TCollection_ExtendedString aMessageString =
133       TCollection_ExtendedString("Cannot retrieve the last index"
134                                  " for Scope attribute");
135     WriteMessage (aMessageString);
136     return Standard_False;
137   }
138   nbLabels = aLastInd - aFirstInd + 1;
139
140   if (!anElement.hasChildNodes())
141   {
142     TCollection_ExtendedString aMessageString = 
143       TCollection_ExtendedString("Cannot retrieve an array of labels");
144     WriteMessage (aMessageString);
145     return Standard_False;
146   }
147
148   LDOM_Node aCurNode = anElement.getFirstChild()/*.getNextSibling().getNextSibling()*/;
149   LDOM_Element* aCurElement = (LDOM_Element*)&aCurNode;
150   XmlObjMgt_DOMString aValueStr;
151   while (*aCurElement != anElement.getLastChild())
152   {
153     aValueStr = XmlObjMgt::GetStringValue( *aCurElement );
154     if (aValueStr == NULL)
155     {
156       aCurNode = aCurElement->getNextSibling();
157       aCurElement = (LDOM_Element*)&aCurNode;
158       continue;
159     }
160     TCollection_AsciiString anEntry;
161     if (XmlObjMgt::GetTagEntryString (aValueStr, anEntry) == Standard_False)
162     {
163       TCollection_ExtendedString aMessage =
164         TCollection_ExtendedString ("Cannot retrieve reference from \"")
165           + aValueStr + '\"';
166       WriteMessage (aMessage);
167       return Standard_False;
168     }
169     // Find label by entry
170     TDF_Label tLab; // Null label.
171     if (anEntry.Length() > 0)
172     {
173       TDF_Tool::Label(S->Label().Data(), anEntry, tLab, Standard_True);
174     }
175     Labels.Append(tLab);
176     aCurNode = aCurElement->getNextSibling();
177     aCurElement = (LDOM_Element*)&aCurNode;
178   }
179
180   // Last reference
181   aValueStr = XmlObjMgt::GetStringValue( *aCurElement );
182   if (aValueStr == NULL)
183   {
184     WriteMessage ("Cannot retrieve reference string from element");
185     return Standard_False;
186   }
187   TCollection_AsciiString anEntry;
188   if (XmlObjMgt::GetTagEntryString (aValueStr, anEntry) == Standard_False)
189   {
190     TCollection_ExtendedString aMessage =
191       TCollection_ExtendedString ("Cannot retrieve reference from \"")
192         + aValueStr + '\"';
193     WriteMessage (aMessage);
194     return Standard_False;
195   }
196   // Find label by entry
197   TDF_Label tLab; // Null label.
198   if (anEntry.Length() > 0)
199   {
200     TDF_Tool::Label(S->Label().Data(), anEntry, tLab, Standard_True);
201   }
202   Labels.Append(tLab);
203
204   // Check equality of lengths of the list of IDs & Labels.
205   if (nbIDs != nbLabels)
206   {
207     TCollection_ExtendedString aMessage =
208       TCollection_ExtendedString ("Numbers of IDs & Labels are different");
209     WriteMessage (aMessage);
210     return Standard_False;
211   }
212
213   // Set IDs & Labels into the Scope attribute
214   int freeID = 0;
215   TColStd_ListIteratorOfListOfInteger itri(IDs);
216   TDF_ListIteratorOfLabelList         itrl(Labels);
217   for (; itri.More(); itri.Next(), itrl.Next())
218   {
219     int ID = itri.Value();
220     if (ID > freeID)
221       freeID = ID;
222     S->ChangeFunctions().Bind(ID, itrl.Value());
223   }
224   freeID++;
225   S->SetFreeID(freeID);
226
227   return Standard_True;
228 }
229
230 //=======================================================================
231 //function : Paste
232 //purpose  : transient -> persistent (store)
233 //=======================================================================
234 void XmlMFunction_ScopeDriver::Paste (const Handle(TDF_Attribute)& theSource,
235                                       XmlObjMgt_Persistent&        theTarget,
236                                       XmlObjMgt_SRelocationTable&  ) const
237 {
238   Handle(TFunction_Scope) S = Handle(TFunction_Scope)::DownCast(theSource);
239
240   // IDs
241   // ===
242
243   theTarget.Element().setAttribute(::LastIDIndex(), S->GetFunctions().Extent());
244
245   TCollection_AsciiString aValueStr;
246   TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrd(S->GetFunctions());
247   for (; itrd.More(); itrd.Next())
248   {
249     const Standard_Integer ID = itrd.Key1();
250     aValueStr += TCollection_AsciiString(ID);
251     aValueStr += ' ';
252   }
253   aValueStr += "\n";
254
255   XmlObjMgt::SetStringValue (theTarget, aValueStr.ToCString(), Standard_True);
256
257
258   // Labels
259   // ======
260
261   XmlObjMgt_Element& anElement = theTarget;
262   anElement.setAttribute(::LastLabelIndex(), S->GetFunctions().Extent());
263   
264   XmlObjMgt_Document aDoc (anElement.getOwnerDocument());
265   
266   for (itrd.Initialize(S->GetFunctions()); itrd.More(); itrd.Next())
267   {
268     TDF_Label L = itrd.Key2();
269
270     TCollection_AsciiString anEntry;
271     TDF_Tool::Entry(L, anEntry);
272
273     XmlObjMgt_DOMString aDOMString;
274     XmlObjMgt::SetTagEntryString (aDOMString, anEntry);
275     XmlObjMgt_Element aCurTarget = aDoc.createElement( ::ExtString() );
276     XmlObjMgt::SetStringValue (aCurTarget, aDOMString, Standard_True);
277     anElement.appendChild( aCurTarget );
278   }
279 }