0028691: Storage of Ocaf documents in XML file format in old document version
[occt.git] / src / XmlMDataStd / XmlMDataStd_TreeNodeDriver.cxx
CommitLineData
b311480e 1// Created on: 2001-08-24
2// Created by: Alexnder GRIGORIEV
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
42cf5bc1 16
17#include <CDM_MessageDriver.hxx>
f7b4312f 18#include <NCollection_LocalArray.hxx>
42cf5bc1 19#include <Standard_Type.hxx>
7fd59977 20#include <TDataStd_TreeNode.hxx>
42cf5bc1 21#include <TDF_Attribute.hxx>
22#include <XmlMDataStd_TreeNodeDriver.hxx>
7fd59977 23#include <XmlObjMgt.hxx>
42cf5bc1 24#include <XmlObjMgt_Persistent.hxx>
c2f5b821 25#include <XmlLDrivers.hxx>
7fd59977 26
92efcf78 27IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_TreeNodeDriver,XmlMDF_ADriver)
7fd59977 28IMPLEMENT_DOMSTRING (TreeIdString, "treeid")
29IMPLEMENT_DOMSTRING (ChildrenString, "children")
30
31//=======================================================================
32//function : XmlMDataStd_TreeNodeDriver
33//purpose : Constructor
34//=======================================================================
35
36XmlMDataStd_TreeNodeDriver::XmlMDataStd_TreeNodeDriver
37 (const Handle(CDM_MessageDriver)& theMsgDriver)
38 : XmlMDF_ADriver (theMsgDriver, NULL)
39{}
40
41//=======================================================================
42//function : NewEmpty
43//purpose :
44//=======================================================================
45Handle(TDF_Attribute) XmlMDataStd_TreeNodeDriver::NewEmpty() const
46{
47 return (new TDataStd_TreeNode());
48}
49
50//=======================================================================
51//function : Paste
52//purpose :
53//=======================================================================
54Standard_Boolean XmlMDataStd_TreeNodeDriver::Paste
55 (const XmlObjMgt_Persistent& theSource,
56 const Handle(TDF_Attribute)& theTarget,
57 XmlObjMgt_RRelocationTable& theRelocTable) const
58{
59 Handle(TDataStd_TreeNode) aT = Handle(TDataStd_TreeNode)::DownCast(theTarget);
60 const XmlObjMgt_Element& anElement = theSource;
61
62 // tree id
e9947e12 63 Standard_GUID aGUID;
7fd59977 64 XmlObjMgt_DOMString aGUIDStr = anElement.getAttribute(::TreeIdString());
e9947e12 65 if (aGUIDStr.Type() == XmlObjMgt_DOMString::LDOM_NULL)
66 aGUID = TDataStd_TreeNode::GetDefaultTreeID();
67 else
68 aGUID = Standard_GUID(Standard_CString(aGUIDStr.GetString()));
7fd59977 69 aT->SetTreeID(aGUID);
70
71 // children
72 Handle(TDataStd_TreeNode) aTChild;
73
74 XmlObjMgt_DOMString aChildrenStr = anElement.getAttribute(::ChildrenString());
75 if (aChildrenStr != NULL) // void list is allowed
76 {
77 Standard_CString aChildren = Standard_CString(aChildrenStr.GetString());
78 Standard_Integer aNb = 0;
79 if (!XmlObjMgt::GetInteger(aChildren, aNb)) return Standard_False;
80
81 while (aNb > 0)
82 {
83 // Find or create TreeNode attribute with the given ID
84 if (theRelocTable.IsBound(aNb))
85 {
86 aTChild = Handle(TDataStd_TreeNode)::DownCast(theRelocTable.Find(aNb));
87 if (aTChild.IsNull())
88 return Standard_False;
89 }
90 else
91 {
92 aTChild = new TDataStd_TreeNode;
93 theRelocTable.Bind(aNb, aTChild);
94 }
95
96 // Add the child to the current tree
97 aTChild->SetTreeID(aGUID);
98 aT->Append(aTChild);
99
100 // Get next child ID
101 if (!XmlObjMgt::GetInteger(aChildren, aNb)) aNb = 0;
102 }
103 }
104 return Standard_True;
105}
106
107//=======================================================================
108//function : Paste
109//purpose :
110//=======================================================================
111void XmlMDataStd_TreeNodeDriver::Paste
112 (const Handle(TDF_Attribute)& theSource,
113 XmlObjMgt_Persistent& theTarget,
114 XmlObjMgt_SRelocationTable& theRelocTable) const
115{
116 Handle(TDataStd_TreeNode) aS = Handle(TDataStd_TreeNode)::DownCast(theSource);
117
7fd59977 118 // tree id
c2f5b821 119 // A not default ID is skipped for storage version 8 and newer.
120 if (aS->ID() != TDataStd_TreeNode::GetDefaultTreeID() ||
121 XmlLDrivers::StorageVersion() < 8)
e9947e12 122 {
123 Standard_Character aGuidStr [40];
124 Standard_PCharacter pGuidStr=aGuidStr;
125 aS->ID().ToCString (pGuidStr);
126 theTarget.Element().setAttribute(::TreeIdString(), aGuidStr);
127 }
7fd59977 128
f7b4312f 129 // Find number of children.
130 int nbChildren = aS->NbChildren();
131
132 // Allocate 11 digits for each ID (an integer) of the child + a space.
133 Standard_Integer iChar = 0;
134 NCollection_LocalArray<Standard_Character> str;
135 if (nbChildren)
136 str.Allocate(11 * nbChildren + 1);
7fd59977 137
138 // form the string of numbers for the list of children
f7b4312f 139 Handle(TDataStd_TreeNode) aF = aS->First();
7fd59977 140 while (!aF.IsNull())
141 {
e9947e12 142 Standard_Integer aNb = theRelocTable.FindIndex(aF);
7fd59977 143 if (aNb == 0)
144 {
145 aNb = theRelocTable.Add(aF);
146 }
f7b4312f 147
148 // Add number to the long string.
149 iChar += Sprintf(&(str[iChar]), "%d ", aNb);
7fd59977 150
151 // next child
152 aF = aF->Next();
153 }
154
f7b4312f 155 if (nbChildren)
156 {
157 theTarget.Element().setAttribute(::ChildrenString(), (Standard_Character*)str);
158 }
7fd59977 159}