b311480e |
1 | // Created on: 1997-12-09 |
2 | // Created by: Jean-Louis Frenkel |
3 | // Copyright (c) 1997-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
17 | |
7fd59977 |
18 | #include <CDM_Document.hxx> |
7fd59977 |
19 | #include <CDM_MetaData.hxx> |
42cf5bc1 |
20 | #include <CDM_ReferenceIterator.hxx> |
7fd59977 |
21 | #include <OSD_Path.hxx> |
7fd59977 |
22 | #include <PCDM.hxx> |
42cf5bc1 |
23 | #include <PCDM_BaseDriverPointer.hxx> |
24 | #include <PCDM_ReadWriter_1.hxx> |
25 | #include <PCDM_Reference.hxx> |
7fd59977 |
26 | #include <PCDM_TypeOfFileDriver.hxx> |
83ae3591 |
27 | #include <Message_Messenger.hxx> |
42cf5bc1 |
28 | #include <Standard_ErrorHandler.hxx> |
29 | #include <Standard_Type.hxx> |
30 | #include <Storage_Data.hxx> |
31 | #include <Storage_HeaderData.hxx> |
32 | #include <Storage_Schema.hxx> |
33 | #include <TCollection_AsciiString.hxx> |
34 | #include <TCollection_ExtendedString.hxx> |
35 | #include <TColStd_SequenceOfAsciiString.hxx> |
36 | #include <TColStd_SequenceOfExtendedString.hxx> |
37 | #include <UTL.hxx> |
7fd59977 |
38 | |
92efcf78 |
39 | IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReadWriter_1,PCDM_ReadWriter) |
40 | |
7fd59977 |
41 | #define START_REF "START_REF" |
42 | #define END_REF "END_REF" |
43 | #define START_EXT "START_EXT" |
44 | #define END_EXT "END_EXT" |
45 | #define MODIFICATION_COUNTER "MODIFICATION_COUNTER: " |
46 | #define REFERENCE_COUNTER "REFERENCE_COUNTER: " |
47 | |
48 | //======================================================================= |
49 | //function : PCDM_ReadWriter_1 |
50 | //purpose : |
51 | //======================================================================= |
52 | |
53 | PCDM_ReadWriter_1::PCDM_ReadWriter_1() {} |
54 | static Standard_Integer RemoveExtraSeparator(TCollection_AsciiString& aString) { |
55 | |
56 | Standard_Integer i, j, len ; |
57 | |
58 | len = aString.Length() ; |
57c28b61 |
59 | #ifdef _WIN32 |
7fd59977 |
60 | // Case of network path, such as \\MACHINE\dir |
61 | for (i = j = 2 ; j <= len ; i++,j++) { |
62 | #else |
63 | for (i = j = 1 ; j <= len ; i++,j++) { |
64 | #endif |
65 | Standard_Character c = aString.Value(j) ; |
66 | aString.SetValue(i,c) ; |
67 | if (c == '/') |
68 | while(j < len && aString.Value(j+1) == '/') j++ ; |
69 | } |
70 | len = i-1 ; |
71 | if (aString.Value(len) == '/') len-- ; |
72 | aString.Trunc(len) ; |
73 | return len ; |
74 | } |
75 | static TCollection_AsciiString AbsolutePath( |
76 | const TCollection_AsciiString& aDirPath, |
77 | const TCollection_AsciiString& aRelFilePath) |
78 | { |
79 | TCollection_AsciiString EmptyString = "" ; |
57c28b61 |
80 | #ifdef _WIN32 |
7fd59977 |
81 | if (aRelFilePath.Search(":") == 2 || |
82 | (aRelFilePath.Search("\\") == 1 && aRelFilePath.Value(2) == '\\')) |
83 | #else |
84 | if(aRelFilePath.Search("/") == 1) |
85 | #endif |
86 | return aRelFilePath ; |
87 | |
88 | TCollection_AsciiString DirPath = aDirPath, RelFilePath = aRelFilePath ; |
89 | Standard_Integer i,len ; |
90 | |
57c28b61 |
91 | #ifdef _WIN32 |
7fd59977 |
92 | if(DirPath.Search(":") != 2 && |
93 | (DirPath.Search("\\") != 1 || DirPath.Value(2) != '\\')) |
94 | #else |
95 | if (DirPath.Search("/") != 1 ) |
96 | #endif |
97 | return EmptyString ; |
98 | |
57c28b61 |
99 | #ifdef _WIN32 |
7fd59977 |
100 | DirPath.ChangeAll('\\','/') ; |
101 | RelFilePath.ChangeAll('\\','/') ; |
102 | #endif |
103 | |
104 | RemoveExtraSeparator(DirPath) ; |
105 | len = RemoveExtraSeparator(RelFilePath) ; |
106 | |
107 | while (RelFilePath.Search("../") == 1) { |
108 | if (len == 3) |
109 | return EmptyString ; |
110 | RelFilePath = RelFilePath.SubString(4,len) ; |
111 | len -= 3 ; |
112 | if (DirPath.IsEmpty()) |
113 | return EmptyString ; |
114 | i = DirPath.SearchFromEnd("/") ; |
115 | if (i < 0) |
116 | return EmptyString ; |
117 | DirPath.Trunc(i-1) ; |
118 | } |
119 | TCollection_AsciiString retx; |
120 | retx= DirPath; |
121 | retx+= "/"; |
122 | retx+=RelFilePath ; |
123 | return retx; |
124 | } |
125 | |
126 | static TCollection_AsciiString GetDirFromFile(const TCollection_ExtendedString& aFileName) { |
d9ff84e8 |
127 | TCollection_AsciiString theCFile(aFileName); |
7fd59977 |
128 | TCollection_AsciiString theDirectory; |
129 | Standard_Integer i=theCFile.SearchFromEnd("/"); |
57c28b61 |
130 | #ifdef _WIN32 |
7fd59977 |
131 | // if(i==-1) i=theCFile.SearchFromEnd("\\"); |
132 | if(theCFile.SearchFromEnd("\\") > i) |
133 | i=theCFile.SearchFromEnd("\\"); |
134 | #endif |
135 | if(i!=-1) theDirectory=theCFile.SubString(1,i); |
136 | return theDirectory; |
137 | } |
138 | //======================================================================= |
139 | //function : Version |
140 | //purpose : |
141 | //======================================================================= |
142 | |
143 | TCollection_AsciiString PCDM_ReadWriter_1::Version() const { |
144 | return "PCDM_ReadWriter_1"; |
145 | } |
146 | //======================================================================= |
147 | //function : WriteReferenceCounter |
148 | //purpose : |
149 | //======================================================================= |
150 | |
151 | void PCDM_ReadWriter_1::WriteReferenceCounter(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const { |
152 | TCollection_AsciiString ligne(REFERENCE_COUNTER); |
153 | ligne+=aDocument->ReferenceCounter(); |
154 | aData->AddToUserInfo(ligne); |
155 | } |
156 | //======================================================================= |
157 | //function : WriteReferences |
158 | //purpose : |
159 | //======================================================================= |
160 | |
161 | void PCDM_ReadWriter_1::WriteReferences(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument,const TCollection_ExtendedString& theReferencerFileName) const { |
162 | |
163 | Standard_Integer theNumber = aDocument->ToReferencesNumber(); |
164 | if(theNumber > 0) { |
165 | |
166 | aData->AddToUserInfo(START_REF); |
167 | |
168 | CDM_ReferenceIterator it(aDocument); |
169 | |
170 | TCollection_ExtendedString ligne; |
171 | |
172 | TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(theReferencerFileName); |
173 | |
174 | for (;it.More();it.Next()) { |
175 | ligne = TCollection_ExtendedString(it.ReferenceIdentifier()); |
176 | ligne += " "; |
177 | ligne += TCollection_ExtendedString(it.Document()->Modifications()); |
178 | ligne += " "; |
179 | |
d9ff84e8 |
180 | TCollection_AsciiString thePath(it.Document()->MetaData()->FileName()); |
7fd59977 |
181 | TCollection_AsciiString theRelativePath; |
182 | if(!theAbsoluteDirectory.IsEmpty()) { |
183 | theRelativePath=OSD_Path::RelativePath(theAbsoluteDirectory,thePath); |
184 | if(!theRelativePath.IsEmpty()) thePath=theRelativePath; |
185 | } |
d9ff84e8 |
186 | ligne += TCollection_ExtendedString(thePath); |
7fd59977 |
187 | UTL::AddToUserInfo(aData,ligne); |
188 | } |
189 | aData->AddToUserInfo(END_REF); |
190 | } |
191 | } |
192 | |
193 | //======================================================================= |
194 | //function : WriteExtensions |
195 | //purpose : |
196 | //======================================================================= |
197 | |
198 | void PCDM_ReadWriter_1::WriteExtensions(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const { |
199 | |
200 | TColStd_SequenceOfExtendedString theExtensions; |
201 | aDocument->Extensions(theExtensions); |
202 | Standard_Integer theNumber = theExtensions.Length(); |
203 | if(theNumber > 0) { |
204 | |
205 | aData->AddToUserInfo(START_EXT); |
206 | for (Standard_Integer i=1; i<=theNumber; i++) { |
207 | UTL::AddToUserInfo(aData,theExtensions(i)); |
208 | } |
209 | aData->AddToUserInfo(END_EXT); |
210 | } |
211 | } |
212 | //======================================================================= |
213 | //function : WriteVersion |
214 | //purpose : |
215 | //======================================================================= |
216 | |
217 | void PCDM_ReadWriter_1::WriteVersion(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const { |
218 | TCollection_AsciiString ligne(MODIFICATION_COUNTER); |
219 | ligne+=aDocument->Modifications(); |
220 | aData->AddToUserInfo(ligne); |
221 | } |
222 | //======================================================================= |
223 | //function : ReadReferenceCounter |
224 | //purpose : |
225 | //======================================================================= |
226 | |
83ae3591 |
227 | Standard_Integer PCDM_ReadWriter_1::ReadReferenceCounter(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
228 | |
229 | static Standard_Integer theReferencesCounter ; |
230 | theReferencesCounter=0; |
231 | static Standard_Integer i ; |
232 | |
39c8dc70 |
233 | Handle(Storage_BaseDriver) theFileDriver; |
d9ff84e8 |
234 | TCollection_AsciiString aFileNameU(aFileName); |
235 | if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown) |
236 | return theReferencesCounter; |
7fd59977 |
237 | |
238 | static Standard_Boolean theFileIsOpen ; |
239 | theFileIsOpen=Standard_False; |
240 | |
241 | try { |
242 | OCC_CATCH_SIGNALS |
39c8dc70 |
243 | PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead); |
7fd59977 |
244 | theFileIsOpen=Standard_True; |
245 | |
246 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
247 | Storage_HeaderData hd; |
39c8dc70 |
248 | hd.Read (theFileDriver); |
7ed7467d |
249 | const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo(); |
7fd59977 |
250 | |
251 | for ( i =1; i<= refUserInfo.Length() ; i++) { |
252 | if(refUserInfo(i).Search(REFERENCE_COUNTER) != -1) { |
253 | try { OCC_CATCH_SIGNALS theReferencesCounter=refUserInfo(i).Token(" ",2).IntegerValue();} |
a738b534 |
254 | catch (Standard_Failure const&) { |
04232180 |
255 | // std::cout << "warning: could not read the reference counter in " << aFileName << std::endl; |
7fd59977 |
256 | TCollection_ExtendedString aMsg("Warning: "); |
257 | aMsg = aMsg.Cat("could not read the reference counter in ").Cat(aFileName).Cat("\0"); |
258 | if(!theMsgDriver.IsNull()) |
83ae3591 |
259 | theMsgDriver->Send(aMsg.ToExtString()); |
7fd59977 |
260 | } |
261 | } |
262 | } |
263 | |
264 | } |
a738b534 |
265 | catch (Standard_Failure const&) {} |
7fd59977 |
266 | |
39c8dc70 |
267 | if(theFileIsOpen) |
268 | { |
269 | theFileDriver->Close(); |
270 | } |
7fd59977 |
271 | |
7fd59977 |
272 | return theReferencesCounter; |
273 | } |
274 | |
275 | //======================================================================= |
276 | //function : ReadReferences |
277 | //purpose : |
278 | //======================================================================= |
279 | |
83ae3591 |
280 | void PCDM_ReadWriter_1::ReadReferences(const TCollection_ExtendedString& aFileName, PCDM_SequenceOfReference& theReferences, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
281 | |
282 | TColStd_SequenceOfExtendedString ReadReferences; |
283 | |
284 | ReadUserInfo(aFileName,START_REF,END_REF,ReadReferences, theMsgDriver); |
285 | |
286 | Standard_Integer theReferenceIdentifier; |
287 | TCollection_ExtendedString theFileName; |
288 | Standard_Integer theDocumentVersion; |
289 | |
290 | TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(aFileName); |
291 | |
292 | for (Standard_Integer i=1; i<=ReadReferences.Length(); i++) { |
293 | Standard_Integer pos=ReadReferences(i).Search(" "); |
294 | if(pos != -1) { |
295 | TCollection_ExtendedString theRest=ReadReferences(i).Split(pos); |
296 | theReferenceIdentifier=UTL::IntegerValue(ReadReferences(i)); |
297 | |
298 | Standard_Integer pos2=theRest.Search(" "); |
299 | |
300 | theFileName=theRest.Split(pos2); |
301 | theDocumentVersion=UTL::IntegerValue(theRest); |
302 | |
d9ff84e8 |
303 | TCollection_AsciiString thePath(theFileName); |
7fd59977 |
304 | TCollection_AsciiString theAbsolutePath; |
305 | if(!theAbsoluteDirectory.IsEmpty()) { |
306 | theAbsolutePath=AbsolutePath(theAbsoluteDirectory,thePath); |
307 | if(!theAbsolutePath.IsEmpty()) thePath=theAbsolutePath; |
308 | } |
309 | if(!theMsgDriver.IsNull()) { |
04232180 |
310 | // std::cout << "reference found; ReferenceIdentifier: " << theReferenceIdentifier << "; File:" << thePath << ", version:" << theDocumentVersion; |
7fd59977 |
311 | TCollection_ExtendedString aMsg("Warning: "); |
312 | aMsg = aMsg.Cat("reference found; ReferenceIdentifier: ").Cat(theReferenceIdentifier).Cat("; File:").Cat(thePath).Cat(", version:").Cat(theDocumentVersion).Cat("\0"); |
83ae3591 |
313 | theMsgDriver->Send(aMsg.ToExtString()); |
7fd59977 |
314 | } |
d9ff84e8 |
315 | TCollection_ExtendedString aPathW(thePath); |
316 | theReferences.Append(PCDM_Reference (theReferenceIdentifier,aPathW,theDocumentVersion)); |
7fd59977 |
317 | |
318 | } |
319 | } |
320 | |
321 | } |
322 | |
323 | //======================================================================= |
324 | //function : ReadExtensions |
325 | //purpose : |
326 | //======================================================================= |
327 | |
83ae3591 |
328 | void PCDM_ReadWriter_1::ReadExtensions(const TCollection_ExtendedString& aFileName, TColStd_SequenceOfExtendedString& theExtensions, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
329 | |
330 | ReadUserInfo(aFileName,START_EXT,END_EXT,theExtensions, theMsgDriver); |
331 | } |
332 | |
333 | |
334 | //======================================================================= |
335 | //function : ReadUserInfo |
336 | //purpose : |
337 | //======================================================================= |
338 | |
339 | void PCDM_ReadWriter_1::ReadUserInfo(const TCollection_ExtendedString& aFileName, |
340 | const TCollection_AsciiString& Start, |
341 | const TCollection_AsciiString& End, |
342 | TColStd_SequenceOfExtendedString& theUserInfo, |
39c8dc70 |
343 | const Handle(Message_Messenger)&) |
344 | { |
7fd59977 |
345 | static Standard_Integer i ; |
39c8dc70 |
346 | Handle(Storage_BaseDriver) theFileDriver; |
d9ff84e8 |
347 | TCollection_AsciiString aFileNameU(aFileName); |
348 | if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown) |
349 | return; |
7fd59977 |
350 | |
39c8dc70 |
351 | PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead); |
7fd59977 |
352 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
353 | Storage_HeaderData hd; |
39c8dc70 |
354 | hd.Read (theFileDriver); |
7ed7467d |
355 | const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo(); |
7fd59977 |
356 | |
357 | Standard_Integer debut=0,fin=0; |
358 | |
359 | for ( i =1; i<= refUserInfo.Length() ; i++) { |
360 | TCollection_ExtendedString theLine=refUserInfo(i); |
361 | if(refUserInfo(i)== Start) debut=i; |
362 | if(refUserInfo(i)== End) fin=i; |
363 | } |
364 | if(debut != 0) { |
365 | for (i=debut+1 ; i<fin; i++) { |
d9ff84e8 |
366 | TCollection_ExtendedString aInfoW(refUserInfo(i)); |
367 | theUserInfo.Append(aInfoW); |
7fd59977 |
368 | } |
369 | } |
370 | theFileDriver->Close(); |
7fd59977 |
371 | } |
372 | |
373 | //======================================================================= |
374 | //function : ReadDocumentVersion |
375 | //purpose : |
376 | //======================================================================= |
377 | |
83ae3591 |
378 | Standard_Integer PCDM_ReadWriter_1::ReadDocumentVersion(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
379 | |
380 | static Standard_Integer theVersion ; |
381 | theVersion=-1; |
382 | |
39c8dc70 |
383 | Handle(Storage_BaseDriver) theFileDriver; |
d9ff84e8 |
384 | TCollection_AsciiString aFileNameU(aFileName); |
385 | if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown) |
386 | return theVersion; |
7fd59977 |
387 | |
388 | static Standard_Boolean theFileIsOpen ; |
389 | theFileIsOpen =Standard_False; |
390 | |
391 | try { |
392 | OCC_CATCH_SIGNALS |
39c8dc70 |
393 | PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead); |
7fd59977 |
394 | theFileIsOpen=Standard_True; |
395 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
396 | Storage_HeaderData hd; |
39c8dc70 |
397 | hd.Read (theFileDriver); |
7ed7467d |
398 | const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo(); |
7fd59977 |
399 | |
400 | static Standard_Integer i ; |
401 | for ( i =1; i<= refUserInfo.Length() ; i++) { |
402 | if(refUserInfo(i).Search(MODIFICATION_COUNTER) != -1) { |
403 | try { OCC_CATCH_SIGNALS theVersion=refUserInfo(i).Token(" ",2).IntegerValue();} |
a738b534 |
404 | catch (Standard_Failure const&) { |
04232180 |
405 | // std::cout << "warning: could not read the version in " << aFileName << std::endl; |
7fd59977 |
406 | TCollection_ExtendedString aMsg("Warning: "); |
407 | aMsg = aMsg.Cat("could not read the version in ").Cat(aFileName).Cat("\0"); |
408 | if(!theMsgDriver.IsNull()) |
83ae3591 |
409 | theMsgDriver->Send(aMsg.ToExtString()); |
7fd59977 |
410 | } |
411 | |
412 | } |
413 | } |
414 | } |
415 | |
a738b534 |
416 | catch (Standard_Failure const&) {} |
7fd59977 |
417 | |
39c8dc70 |
418 | if(theFileIsOpen) |
419 | { |
420 | theFileDriver->Close(); |
421 | } |
422 | |
7fd59977 |
423 | return theVersion; |
424 | } |