0031546: Application Framework - Memory leak (100 bytes) on Load / Close OCAF document
[occt.git] / src / DDocStd / DDocStd_ShapeSchemaCommands.cxx
CommitLineData
63bd365e 1// Created on: 2017-03-28
2// Created by: Sergey NIKONOV
3// Copyright (c) 2000-2017 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.
ec964372 15
16#include <DDocStd.hxx>
17#include <DBRep.hxx>
18#include <FSD_File.hxx>
19#include <FSD_CmpFile.hxx>
20#include <FSD_BinaryFile.hxx>
21#include <BRep_Builder.hxx>
22#include <NCollection_Handle.hxx>
23#include <TCollection_AsciiString.hxx>
24#include <TopTools_SequenceOfShape.hxx>
25#include <Storage_BaseDriver.hxx>
26#include <StdStorage.hxx>
27#include <StdStorage_Data.hxx>
28#include <StdStorage_HeaderData.hxx>
29#include <StdStorage_RootData.hxx>
30#include <StdStorage_TypeData.hxx>
31#include <ShapePersistent_TopoDS.hxx>
32
39c8dc70 33//==========================================================
34// ErrorMessage
35//==========================================================
36
37static void DDocStd_StorageErrorMessage (Draw_Interpretor& theDI, const Storage_Error theStatus)
38{
39 switch (theStatus) {
40 case Storage_VSOk:
41 break;
42 case Storage_VSOpenError:
43 theDI << "Storage error: failed to open the stream";
44 break;
45 case Storage_VSModeError:
46 theDI << "Storage error: the stream is opened with a wrong mode for operation ";
47 break;
48 case Storage_VSCloseError:
49 theDI << "Storage error: failed to closing the stream";
50 break;
51 case Storage_VSAlreadyOpen:
52 theDI << "Storage error: stream is already opened";
53 break;
54 case Storage_VSNotOpen:
55 theDI << "Storage error: stream not opened";
56 break;
57 case Storage_VSSectionNotFound:
58 theDI << "Storage error: the section is not found";
59 break;
60 case Storage_VSWriteError:
61 theDI << "Storage error: error during writing";
62 break;
63 case Storage_VSFormatError:
64 theDI << "Storage error: wrong format error occured while reading";
65 break;
66 case Storage_VSUnknownType:
67 theDI << "Storage error: try to read an unknown type";
68 break;
69 case Storage_VSTypeMismatch:
70 theDI << "Storage error: try to read a wrong primitive type (read a char while expecting a real)";
71 break;
72 case Storage_VSInternalError:
73 theDI << "Storage error: internal error";
74 break;
75 case Storage_VSExtCharParityError:
76 theDI << "Storage error: parity error";
77 break;
78 default:
79 theDI << "Storage error: unknown error code";
80 break;
81 }
82}
83
ec964372 84//=======================================================================
85//function : DDocStd_ShapeSchema_Write
86//=======================================================================
87
88static Standard_Integer DDocStd_fsdwrite(Draw_Interpretor& theDI,
89 Standard_Integer theArgNb,
90 const char** theArgs)
91{
92 if (theArgNb < 3)
93 {
94 theDI << "Usage : fsdwrite shapes filename [gen | cmp | bin]\n";
95 theDI << " Arguments:\n";
96 theDI << " shapes : list os shape names\n";
97 theDI << " filename : output file name\n";
98 theDI << " Storage driver:\n";
99 theDI << " gen : FSD_File driver (default)\n";
100 theDI << " cmp : FSD_CmpFile driver\n";
101 theDI << " bin : FSD_BinaryFile driver\n";
102 return 1;
103 }
104
39c8dc70 105 Handle(Storage_BaseDriver) aFileDriver(new FSD_File);
ec964372 106
107 Standard_Boolean hasStorageDriver = Standard_False;
108 Standard_Integer iArgN = theArgNb - 1;
109
110 if (strncmp(theArgs[iArgN], "gen", 3) == 0)
111 {
112 aFileDriver = new FSD_File;
113 hasStorageDriver = Standard_True;
114 }
115 else if (strncmp(theArgs[iArgN], "cmp", 3) == 0)
116 {
117 aFileDriver = new FSD_CmpFile;
118 hasStorageDriver = Standard_True;
119 }
120 else if (strncmp(theArgs[iArgN], "bin", 3) == 0)
121 {
122 aFileDriver = new FSD_BinaryFile;
123 hasStorageDriver = Standard_True;
124 }
125
126 if (hasStorageDriver) --iArgN;
127
128 Storage_Error aStatus = aFileDriver->Open(theArgs[iArgN], Storage_VSWrite);
129 if (aStatus != Storage_VSOk) {
39c8dc70 130 theDI << "Error: cannot open file '" << "' for writing (" << aStatus << ")\n";
131 DDocStd_StorageErrorMessage (theDI, aStatus);
132 return 0;
ec964372 133 }
134
135 TopTools_SequenceOfShape aShapes;
136 NCollection_DataMap<TCollection_AsciiString, Standard_Integer> aShapeNames;
137 for (Standard_Integer i = 1; i < iArgN; ++i)
138 {
139 TopoDS_Shape aShape = DBRep::Get(theArgs[i]);
140 if (aShape.IsNull())
141 {
142 theDI << "Error : null shape " << theArgs[i] << "\n";
143 return 1;
144 }
145 aShapes.Append(aShape);
146 if (aShapeNames.IsBound(theArgs[i]))
147 aShapeNames.ChangeFind(theArgs[i]) += 1;
148 else
149 aShapeNames.Bind(theArgs[i], 1);
150 }
151
152 Handle(StdStorage_Data) aData = new StdStorage_Data;
153
154 aData->HeaderData()->SetApplicationName(TCollection_ExtendedString("DDocStd_ShapeSchema_Write"));
155
156 StdObjMgt_TransientPersistentMap aMap;
157 for (Standard_Integer i = 1; i <= aShapes.Length(); ++i)
158 {
159 TopoDS_Shape aShape = aShapes.Value(i);
160
161 Handle(ShapePersistent_TopoDS::HShape) aPShape =
162 ShapePersistent_TopoDS::Translate(aShape, aMap, ShapePersistent_WithTriangle);
163 if (aPShape.IsNull())
164 {
165 theDI << "Error : couldn't translate shape " << theArgs[i] << "\n";
166 return 1;
167 }
168
169 TCollection_AsciiString aName = theArgs[i];
170 if (aShapeNames.IsBound(aName))
171 {
172 Standard_Integer n = aShapeNames.Find(theArgs[i]);
173 if (n > 1)
174 {
175 aName += "_";
176 aName += n;
177 }
178 }
179
180 Handle(StdStorage_Root) aRoot = new StdStorage_Root(aName, aPShape);
181 aData->RootData()->AddRoot(aRoot);
182 }
183
39c8dc70 184 Storage_Error anError = StdStorage::Write(aFileDriver, aData);
ec964372 185 aFileDriver->Close();
39c8dc70 186 DDocStd_StorageErrorMessage(theDI, anError);
ec964372 187
188 return 0;
189}
190
191//=======================================================================
192//function : DDocStd_ShapeSchema_Read
193//=======================================================================
194
195static Standard_Integer DDocStd_fsdread(Draw_Interpretor& theDI,
196 Standard_Integer theArgNb,
197 const char** theArgs)
198{
199 if (theArgNb < 3)
200 {
201 theDI << "Usage : fsdread filename shape\n";
202 theDI << " Arguments:\n";
203 theDI << " filename : input file name\n";
409095ba 204 theDI << " shape : name of an output shape, or \n";
205 theDI << " reserved name = 'restore_with_names';\n";
206 theDI << " by default root shapes will be put into \n";
207 theDI << " a compound in case of multiple roots in the file;\n";
208 theDI << " if name = restore_with_names, the shapes will be put to\n";
209 theDI << " separate variables according kept names.\n";
ec964372 210 return 1;
211 }
409095ba 212 Standard_Boolean rflag(Standard_False);
213 if (strcmp(theArgs[2],"restore_with_names") == 0)
214 rflag = Standard_True;
ec964372 215 Handle(StdStorage_Data) aData;
216 Storage_Error anError = StdStorage::Read(TCollection_AsciiString(theArgs[1]), aData);
217 if (anError != Storage_VSOk)
218 {
39c8dc70 219 DDocStd_StorageErrorMessage(theDI, anError);
220 return 0;
ec964372 221 }
222
223 TopTools_SequenceOfShape aShapes;
224
225 Handle(StdStorage_TypeData) aTypeData = aData->TypeData();
226 Handle(StdStorage_RootData) aRootData = aData->RootData();
227 Handle(StdStorage_HSequenceOfRoots) aRoots = aRootData->Roots();
228 if (!aRoots.IsNull())
229 {
230 for (StdStorage_HSequenceOfRoots::Iterator anIt(*aRoots); anIt.More(); anIt.Next())
231 {
232 Handle(StdStorage_Root)& aRoot = anIt.ChangeValue();
233 Handle(StdObjMgt_Persistent) aPObject = aRoot->Object();
234 if (!aPObject.IsNull())
235 {
236 Handle(ShapePersistent_TopoDS::HShape) aHShape = Handle(ShapePersistent_TopoDS::HShape)::DownCast(aPObject);
237 if (aHShape) // shapes are expected
238 {
239 TopoDS_Shape aShape = aHShape->Import();
409095ba 240 if(rflag) {
241 if(!aRoot->Name().IsEmpty())
242 DBRep::Set(aRoot->Name().ToCString(), aShape);
243 else {
244 TCollection_AsciiString aNam("name_");
245 aNam += aRoot->Reference();
246 DBRep::Set(aNam.ToCString(), aShape);
247 }
248#ifdef DEBUG_FSDREAD
249 Standard_Integer indx = aRoot->Reference();
250 theDI << "Ref indx = " <<indx << " Name = " << aRoot->Name().ToCString() << "\n";
251#endif
252 } else
253 aShapes.Append(aShape);
ec964372 254 }
255 }
256 }
257 }
258
259 theDI << "Info : " << aTypeData->NumberOfTypes() << " type(s)\n";
260 theDI << " " << aRoots->Length() << " root(s)\n";
ec964372 261
409095ba 262 if (!rflag) {
263 if (aShapes.Length() > 1)
264 {
265 theDI << " " << aShapes.Length() << " shape(s) translated\n";
266 BRep_Builder aB;
267 TopoDS_Compound aC;
268 aB.MakeCompound(aC);
269 for (Standard_Integer i = 1; i <= aShapes.Length(); ++i)
270 aB.Add(aC, aShapes.Value(i));
271 DBRep::Set(theArgs[2], aC);
272 }
273 else
274 DBRep::Set(theArgs[2], aShapes.First());
ec964372 275 }
ec964372 276 return 0;
277}
278
279//=======================================================================
280//function : ShapeSchemaCommands
281//purpose : registers shape schema related commands in Draw interpreter
282//=======================================================================
283
284void DDocStd::ShapeSchemaCommands(Draw_Interpretor& theCommands)
285{
286 static Standard_Boolean done = Standard_False;
287 if (done) return;
288 done = Standard_True;
289
290 const char* g = "Shape persistence commands";
291
292 theCommands.Add("fsdwrite",
293 "fsdrite shape filename [driver]",
294 __FILE__, DDocStd_fsdwrite, g);
295
296 theCommands.Add("fsdread",
409095ba 297 "fsdread filename shape [name | or key 'restore_with_names']",
ec964372 298 __FILE__, DDocStd_fsdread, g);
299
300}