0024252: GCC warnings on breakage of strict-aliasing rules
[occt.git] / src / XmlMNaming / XmlMNaming_NamedShapeDriver.cxx
1 // Created on: 2001-07-11
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2001-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
8 // under the terms of the GNU Lesser General Public 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 //AGV 150202: Changed prototype LDOM_Node::getOwnerDocument()
17
18 #include <XmlMNaming_NamedShapeDriver.ixx>
19
20 #include <XmlObjMgt.hxx>
21 #include <XmlMNaming_Array1OfShape1.hxx>
22 #include <XmlMNaming_Shape1.hxx>
23
24 #include <TDF_Label.hxx>
25 #include <TNaming_Builder.hxx>
26 #include <TNaming_NamedShape.hxx>
27 #include <TNaming_Iterator.hxx>
28
29 #include <TopoDS_Shape.hxx>
30 #include <BRepTools.hxx>
31 #include <LDOM_Text.hxx>
32 #include <LDOM_OSStream.hxx>
33
34 #include <Standard_SStream.hxx>
35
36 static TNaming_Evolution          EvolutionEnum   (const XmlObjMgt_DOMString&);
37 static const XmlObjMgt_DOMString& EvolutionString (const TNaming_Evolution);
38 static void                       doTranslate     (const TopoDS_Shape&,
39                                                    XmlMNaming_Shape1&,
40                                                    BRepTools_ShapeSet&);
41 static int                        doTranslate     (const XmlMNaming_Shape1&,
42                                                    TopoDS_Shape&,
43                                                    BRepTools_ShapeSet&);
44
45 IMPLEMENT_DOMSTRING (OldsString,    "olds")
46 IMPLEMENT_DOMSTRING (NewsString,    "news")
47 IMPLEMENT_DOMSTRING (StatusString,  "evolution")
48 IMPLEMENT_DOMSTRING (VersionString, "version")
49 IMPLEMENT_DOMSTRING (ShapesString,  "shapes")
50
51 IMPLEMENT_DOMSTRING (EvolPrimitiveString, "primitive")
52 IMPLEMENT_DOMSTRING (EvolGeneratedString, "generated")
53 IMPLEMENT_DOMSTRING (EvolModifyString,    "modify")
54 IMPLEMENT_DOMSTRING (EvolDeleteString,    "delete")
55 IMPLEMENT_DOMSTRING (EvolSelectedString,  "selected")
56 IMPLEMENT_DOMSTRING (EvolReplaceString,   "replace")
57
58 //=======================================================================
59 //function : XmlMNaming_NamedShapeDriver
60 //purpose  : Constructor
61 //=======================================================================
62
63 XmlMNaming_NamedShapeDriver::XmlMNaming_NamedShapeDriver
64                         (const Handle(CDM_MessageDriver&) theMessageDriver)
65      : XmlMDF_ADriver (theMessageDriver, NULL),
66   myShapeSet (Standard_False) // triangles mode
67 {}
68
69 //=======================================================================
70 //function : NewEmpty()
71 //purpose  : 
72 //=======================================================================
73 Handle(TDF_Attribute) XmlMNaming_NamedShapeDriver::NewEmpty () const
74 {
75   return (new TNaming_NamedShape());
76 }
77
78 //=======================================================================
79 //function : Paste()
80 //purpose  : retrieval of TNaming_NamedShape
81 //=======================================================================
82
83 Standard_Boolean XmlMNaming_NamedShapeDriver::Paste
84                                        (const XmlObjMgt_Persistent&  theSource,
85                                         const Handle(TDF_Attribute)& theTarget,
86                                         XmlObjMgt_RRelocationTable&) const
87 {
88   Handle(TNaming_NamedShape) aTarget =
89     Handle(TNaming_NamedShape)::DownCast(theTarget);
90   TDF_Label Label = aTarget -> Label();
91   TNaming_Builder aBld (Label);
92
93   //    Get Version
94   Standard_Integer    aVersion = 0;
95   const XmlObjMgt_Element& anElement = theSource;
96   XmlObjMgt_DOMString aVerString = anElement.getAttribute (::VersionString());
97   if (aVerString != NULL)
98     aVerString.GetInteger (aVersion);
99
100   //    Get Evolution status
101   XmlObjMgt_DOMString aStatus = anElement.getAttribute (::StatusString());
102   TNaming_Evolution evol = EvolutionEnum (aStatus);
103   // apres creation Builder qui a mis la version a 1 :
104   aTarget -> SetVersion (aVersion);
105
106   const XmlMNaming_Array1OfShape1 OldPShapes (anElement, ::OldsString());
107   const XmlMNaming_Array1OfShape1 NewPShapes (anElement, ::NewsString());
108   if (NewPShapes.Length() == 0 && OldPShapes.Length() == 0)
109     return Standard_True;
110
111   TopoDS_Shape anOldShape;
112   TopoDS_Shape aNewShape;
113   BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
114
115   Standard_Integer lower = NewPShapes.Lower();
116   if (OldPShapes.Lower() < lower) lower = OldPShapes.Lower();
117
118   Standard_Integer upper = NewPShapes.Upper();
119   if (OldPShapes.Upper() > upper) upper = OldPShapes.Upper();
120
121   for (Standard_Integer i = lower; i <= upper; i++)
122   {
123     const XmlMNaming_Shape1 aNewPShape  = NewPShapes.Value(i);
124     const XmlMNaming_Shape1 anOldPShape = OldPShapes.Value(i);
125
126     if ( evol != TNaming_PRIMITIVE && anOldPShape.Element() != NULL )
127     {
128       if (::doTranslate (anOldPShape, anOldShape, aShapeSet)) {
129         WriteMessage ("NamedShapeDriver: Error reading a shape from array");
130         return Standard_False;
131       }
132     }
133
134     if (evol != TNaming_DELETE && aNewPShape.Element() != NULL )
135     {
136       if (::doTranslate (aNewPShape, aNewShape, aShapeSet)) {
137         WriteMessage ("NamedShapeDriver: Error reading a shape from array");
138         return Standard_False;
139       }
140     }
141
142     switch (evol)
143     {
144     case TNaming_PRIMITIVE:
145       aBld.Generated(aNewShape);
146       break;
147     case TNaming_GENERATED:
148       aBld.Generated(anOldShape,aNewShape);
149       break;
150     case TNaming_MODIFY:
151       aBld.Modify(anOldShape,aNewShape);
152       break;
153     case TNaming_DELETE:
154       aBld.Delete(anOldShape);
155       break;
156     case TNaming_SELECTED:
157       aBld.Select(aNewShape, anOldShape);
158       break;
159     case TNaming_REPLACE:
160       aBld.Modify(anOldShape,aNewShape);
161       break; // for compatibility
162       //    case TNaming_REPLACE:
163       //      aBld.Replace(anOldShape,aNewShape);
164       //      break;
165     default:
166       Standard_DomainError::Raise("TNaming_Evolution; enum term unknown");
167     }
168     anOldShape.Nullify();
169     aNewShape.Nullify();
170   }
171   return Standard_True;
172 }
173
174 //=======================================================================
175 //function : Paste()
176 //purpose  : storage of TNaming_NamedShape
177 //=======================================================================
178
179 void XmlMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
180                                          XmlObjMgt_Persistent&        theTarget,
181                                          XmlObjMgt_SRelocationTable&) const
182 {
183 //AGV  XmlObjMgt_Document& aDoc =
184 //AGV    (XmlObjMgt_Document&) theTarget.Element().getOwnerDocument();
185   XmlObjMgt_Document aDoc =
186     XmlObjMgt_Document (theTarget.Element().getOwnerDocument());
187
188   Handle(TNaming_NamedShape) aNamedShape =
189     Handle(TNaming_NamedShape)::DownCast(theSource);
190   TNaming_Evolution evol = aNamedShape->Evolution();
191
192   //    Create arrays
193   Standard_Integer NbShapes = 0;
194   TNaming_Iterator SItr (aNamedShape);
195   while (SItr.More()) {
196     NbShapes++;
197     SItr.Next ();
198   }
199
200   BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
201   XmlMNaming_Array1OfShape1 OldPShapes (1,NbShapes), NewPShapes (1,NbShapes);
202
203   OldPShapes.CreateArrayElement (theTarget, ::OldsString());
204   NewPShapes.CreateArrayElement (theTarget, ::NewsString());
205
206   //    Fill arrays
207   Standard_Integer i = 1;
208   TNaming_Iterator SIterator(aNamedShape);
209   while (SIterator.More())
210   {
211     const TopoDS_Shape& OldShape = SIterator.OldShape();
212     const TopoDS_Shape& NewShape = SIterator.NewShape();
213
214     if ( evol != TNaming_PRIMITIVE )
215     {
216       XmlMNaming_Shape1 anOldPShape (aDoc);
217       ::doTranslate (OldShape, anOldPShape, aShapeSet);
218       OldPShapes.SetValue (i, anOldPShape.Element());
219     }
220
221     if (evol != TNaming_DELETE)
222     {
223       XmlMNaming_Shape1 aNewPShape (aDoc);
224       ::doTranslate (NewShape, aNewPShape, aShapeSet);
225       NewPShapes.SetValue (i, aNewPShape.Element());
226     }
227     i++;
228     SIterator.Next();
229   }
230
231   theTarget.Element().setAttribute (::StatusString(), EvolutionString(evol));
232   Standard_Integer aVersion = aNamedShape -> Version();
233   if (aVersion != 0)
234     theTarget.Element().setAttribute (::VersionString(), aVersion);
235 }
236
237 //=======================================================================
238 //function : EvolutionEnum
239 //purpose  : static
240 //=======================================================================
241
242 static const XmlObjMgt_DOMString& EvolutionString(const TNaming_Evolution i)
243 {
244   switch(i) {
245     case TNaming_PRIMITIVE    : return ::EvolPrimitiveString();
246     case TNaming_GENERATED    : return ::EvolGeneratedString();
247     case TNaming_MODIFY       : return ::EvolModifyString();
248     case TNaming_DELETE       : return ::EvolDeleteString();
249     case TNaming_SELECTED     : return ::EvolSelectedString();
250     case TNaming_REPLACE      : return ::EvolModifyString();  //    case TNaming_REPLACE      : return ::EvolReplaceString(); for compatibility
251   default:
252     Standard_DomainError::Raise("TNaming_Evolution; enum term unknown");
253   }
254   static XmlObjMgt_DOMString aNullString;
255   return aNullString; // To avoid compilation error message.
256 }
257
258 //=======================================================================
259 //function : EvolutionEnum
260 //purpose  : static
261 //=======================================================================
262
263 static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString& theString)
264 {
265   TNaming_Evolution aResult = TNaming_PRIMITIVE;
266   if (theString.equals (::EvolPrimitiveString()) == Standard_False) {
267     if (theString.equals (::EvolGeneratedString()))
268       aResult = TNaming_GENERATED;
269     else if (theString.equals (::EvolModifyString()))
270       aResult = TNaming_MODIFY;
271     else if (theString.equals (::EvolDeleteString()))
272       aResult = TNaming_DELETE;
273     else if (theString.equals (::EvolSelectedString()))
274       aResult = TNaming_SELECTED;
275     else if (theString.equals (::EvolReplaceString()))
276       aResult = TNaming_MODIFY; // for compatibility //TNaming_REPLACE;
277     else
278       Standard_DomainError::Raise
279         ("TNaming_Evolution; string value without enum term equivalence");
280   }
281   return aResult;
282 }
283
284 //=======================================================================
285 //function : doTranslate
286 //purpose  : shape storage to XML
287 //=======================================================================
288
289 static void doTranslate (const TopoDS_Shape&            theShape,
290                          XmlMNaming_Shape1&             theResult,
291                          BRepTools_ShapeSet&            theShapeSet)
292 {
293   // Check for empty shape
294   if (theShape.IsNull()) return;
295
296   // Add to shape set both TShape and Location contained in theShape
297   const Standard_Integer aTShapeId = theShapeSet.Add (theShape);
298   const Standard_Integer aLocId =
299     theShapeSet.Locations().Index (theShape.Location());
300
301   // Fill theResult with shape parameters: TShape ID, Location, Orientation
302   theResult.SetShape (aTShapeId, aLocId, theShape.Orientation());
303
304   if (theShape.ShapeType() == TopAbs_VERTEX)
305   {
306     theResult.SetVertex(theShape);
307   }
308 }
309
310 //=======================================================================
311 //function : doTranslate
312 //purpose  : shape retrieval from XML
313 //=======================================================================
314
315 static int doTranslate  (const XmlMNaming_Shape1&       thePShape,
316                          TopoDS_Shape&                  theResult,
317                          BRepTools_ShapeSet&            theShapeSet)
318 {
319   const Standard_Integer aShapeId = thePShape.TShapeId();
320
321   // Read TShape and Orientation
322   if (aShapeId <= 0 || aShapeId > theShapeSet.NbShapes())
323     return 1;
324   theResult.TShape      (theShapeSet.Shape(aShapeId).TShape());
325   theResult.Orientation (thePShape.Orientation());
326   theResult.Location    (theShapeSet.Locations().Location (thePShape.LocId()));
327
328   return 0;
329 }
330
331 //=======================================================================
332 //function : ReadShapeSection
333 //purpose  : 
334 //=======================================================================
335
336 void XmlMNaming_NamedShapeDriver::ReadShapeSection
337                                         (const XmlObjMgt_Element& theElement)
338 {
339   XmlObjMgt_Element anElement =
340     XmlObjMgt::FindChildByName (theElement, ::ShapesString());
341   if (anElement != NULL) {
342     for (LDOM_Node aNode = anElement.getFirstChild();
343          aNode != NULL;
344          aNode = anElement.getNextSibling())
345     {
346       if (aNode.getNodeType() == LDOM_Node::TEXT_NODE) {
347         LDOMString aData = aNode.getNodeValue();
348         #ifdef USE_STL_STREAM
349         std::stringstream aStream (std::string(aData.GetString()));
350         #else
351         istrstream aStream (Standard_CString(aData.GetString()));
352         #endif
353         myShapeSet.Clear();
354         myShapeSet.Read (aStream);
355         break;
356       }
357     }
358   }
359 }
360
361 //=======================================================================
362 //function : WriteShapeSection
363 //purpose  : 
364 //=======================================================================
365
366 void XmlMNaming_NamedShapeDriver::WriteShapeSection
367                                         (XmlObjMgt_Element& theElement)
368 {
369   //  Create "shapes" element and append it as child
370   XmlObjMgt_Document aDoc     = theElement.getOwnerDocument();
371   XmlObjMgt_Element anElement = aDoc.createElement (::ShapesString());
372   theElement.appendChild (anElement);
373
374   //  Add text to the "shapes" element
375   if (myShapeSet.NbShapes() > 0) {
376     myShapeSet.SetFormatNb(2);
377     LDOM_OSStream aStream (1024);
378 //    ostrstream aStream;
379 //    aStream.rdbuf() -> setbuf (0, 16380);
380     myShapeSet.Write (aStream);
381     aStream << ends;
382     char * aStr = (char *)aStream.str();
383     LDOM_Text aText = aDoc.createTextNode (aStr);
384     delete [] aStr;
385     aText.SetValueClear();      // There are no characters '<' and '&' and like
386 //    aStream.rdbuf() -> freeze(0);                     // release the buffer
387     anElement.appendChild (aText);
388   // Clear the shape set to avoid appending to it on the next write
389     BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
390     aShapeSet.Clear();
391   }
392 }
393
394 //=======================================================================
395 //function : Clear
396 //purpose  : 
397 //=======================================================================
398
399 void XmlMNaming_NamedShapeDriver::Clear()
400 {
401   myShapeSet.Clear();
402 }