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 | |
233 | PCDM_BaseDriverPointer 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 |
243 | PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead); |
244 | theFileIsOpen=Standard_True; |
245 | |
246 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
247 | Storage_HeaderData hd; |
248 | hd.Read (*theFileDriver); |
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();} |
254 | catch (Standard_Failure) { |
255 | // cout << "warning: could not read the reference counter in " << aFileName << endl; |
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 | } |
265 | catch (Standard_Failure) {} |
266 | |
267 | if(theFileIsOpen) theFileDriver->Close(); |
268 | |
269 | delete theFileDriver; |
270 | return theReferencesCounter; |
271 | } |
272 | |
273 | //======================================================================= |
274 | //function : ReadReferences |
275 | //purpose : |
276 | //======================================================================= |
277 | |
83ae3591 |
278 | void PCDM_ReadWriter_1::ReadReferences(const TCollection_ExtendedString& aFileName, PCDM_SequenceOfReference& theReferences, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
279 | |
280 | TColStd_SequenceOfExtendedString ReadReferences; |
281 | |
282 | ReadUserInfo(aFileName,START_REF,END_REF,ReadReferences, theMsgDriver); |
283 | |
284 | Standard_Integer theReferenceIdentifier; |
285 | TCollection_ExtendedString theFileName; |
286 | Standard_Integer theDocumentVersion; |
287 | |
288 | TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(aFileName); |
289 | |
290 | for (Standard_Integer i=1; i<=ReadReferences.Length(); i++) { |
291 | Standard_Integer pos=ReadReferences(i).Search(" "); |
292 | if(pos != -1) { |
293 | TCollection_ExtendedString theRest=ReadReferences(i).Split(pos); |
294 | theReferenceIdentifier=UTL::IntegerValue(ReadReferences(i)); |
295 | |
296 | Standard_Integer pos2=theRest.Search(" "); |
297 | |
298 | theFileName=theRest.Split(pos2); |
299 | theDocumentVersion=UTL::IntegerValue(theRest); |
300 | |
d9ff84e8 |
301 | TCollection_AsciiString thePath(theFileName); |
7fd59977 |
302 | TCollection_AsciiString theAbsolutePath; |
303 | if(!theAbsoluteDirectory.IsEmpty()) { |
304 | theAbsolutePath=AbsolutePath(theAbsoluteDirectory,thePath); |
305 | if(!theAbsolutePath.IsEmpty()) thePath=theAbsolutePath; |
306 | } |
307 | if(!theMsgDriver.IsNull()) { |
308 | // cout << "reference found; ReferenceIdentifier: " << theReferenceIdentifier << "; File:" << thePath << ", version:" << theDocumentVersion; |
309 | TCollection_ExtendedString aMsg("Warning: "); |
310 | aMsg = aMsg.Cat("reference found; ReferenceIdentifier: ").Cat(theReferenceIdentifier).Cat("; File:").Cat(thePath).Cat(", version:").Cat(theDocumentVersion).Cat("\0"); |
83ae3591 |
311 | theMsgDriver->Send(aMsg.ToExtString()); |
7fd59977 |
312 | } |
d9ff84e8 |
313 | TCollection_ExtendedString aPathW(thePath); |
314 | theReferences.Append(PCDM_Reference (theReferenceIdentifier,aPathW,theDocumentVersion)); |
7fd59977 |
315 | |
316 | } |
317 | } |
318 | |
319 | } |
320 | |
321 | //======================================================================= |
322 | //function : ReadExtensions |
323 | //purpose : |
324 | //======================================================================= |
325 | |
83ae3591 |
326 | void PCDM_ReadWriter_1::ReadExtensions(const TCollection_ExtendedString& aFileName, TColStd_SequenceOfExtendedString& theExtensions, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
327 | |
328 | ReadUserInfo(aFileName,START_EXT,END_EXT,theExtensions, theMsgDriver); |
329 | } |
330 | |
331 | |
332 | //======================================================================= |
333 | //function : ReadUserInfo |
334 | //purpose : |
335 | //======================================================================= |
336 | |
337 | void PCDM_ReadWriter_1::ReadUserInfo(const TCollection_ExtendedString& aFileName, |
338 | const TCollection_AsciiString& Start, |
339 | const TCollection_AsciiString& End, |
340 | TColStd_SequenceOfExtendedString& theUserInfo, |
83ae3591 |
341 | const Handle(Message_Messenger)&) { |
7fd59977 |
342 | |
343 | static Standard_Integer i ; |
344 | PCDM_BaseDriverPointer theFileDriver; |
d9ff84e8 |
345 | TCollection_AsciiString aFileNameU(aFileName); |
346 | if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown) |
347 | return; |
7fd59977 |
348 | |
349 | PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead); |
350 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
351 | Storage_HeaderData hd; |
352 | hd.Read (*theFileDriver); |
353 | const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo(); |
7fd59977 |
354 | |
355 | Standard_Integer debut=0,fin=0; |
356 | |
357 | for ( i =1; i<= refUserInfo.Length() ; i++) { |
358 | TCollection_ExtendedString theLine=refUserInfo(i); |
359 | if(refUserInfo(i)== Start) debut=i; |
360 | if(refUserInfo(i)== End) fin=i; |
361 | } |
362 | if(debut != 0) { |
363 | for (i=debut+1 ; i<fin; i++) { |
d9ff84e8 |
364 | TCollection_ExtendedString aInfoW(refUserInfo(i)); |
365 | theUserInfo.Append(aInfoW); |
7fd59977 |
366 | } |
367 | } |
368 | theFileDriver->Close(); |
369 | delete theFileDriver; |
370 | } |
371 | |
372 | //======================================================================= |
373 | //function : ReadDocumentVersion |
374 | //purpose : |
375 | //======================================================================= |
376 | |
83ae3591 |
377 | Standard_Integer PCDM_ReadWriter_1::ReadDocumentVersion(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const { |
7fd59977 |
378 | |
379 | static Standard_Integer theVersion ; |
380 | theVersion=-1; |
381 | |
382 | PCDM_BaseDriverPointer theFileDriver; |
d9ff84e8 |
383 | TCollection_AsciiString aFileNameU(aFileName); |
384 | if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown) |
385 | return theVersion; |
7fd59977 |
386 | |
387 | static Standard_Boolean theFileIsOpen ; |
388 | theFileIsOpen =Standard_False; |
389 | |
390 | try { |
391 | OCC_CATCH_SIGNALS |
392 | PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead); |
393 | theFileIsOpen=Standard_True; |
394 | Handle(Storage_Schema) s = new Storage_Schema; |
7ed7467d |
395 | Storage_HeaderData hd; |
396 | hd.Read (*theFileDriver); |
397 | const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo(); |
7fd59977 |
398 | |
399 | static Standard_Integer i ; |
400 | for ( i =1; i<= refUserInfo.Length() ; i++) { |
401 | if(refUserInfo(i).Search(MODIFICATION_COUNTER) != -1) { |
402 | try { OCC_CATCH_SIGNALS theVersion=refUserInfo(i).Token(" ",2).IntegerValue();} |
403 | catch (Standard_Failure) { |
404 | // cout << "warning: could not read the version in " << aFileName << endl; |
405 | TCollection_ExtendedString aMsg("Warning: "); |
406 | aMsg = aMsg.Cat("could not read the version in ").Cat(aFileName).Cat("\0"); |
407 | if(!theMsgDriver.IsNull()) |
83ae3591 |
408 | theMsgDriver->Send(aMsg.ToExtString()); |
7fd59977 |
409 | } |
410 | |
411 | } |
412 | } |
413 | } |
414 | |
415 | catch (Standard_Failure) {} |
416 | |
417 | if(theFileIsOpen) theFileDriver->Close(); |
418 | delete theFileDriver; |
419 | return theVersion; |
420 | } |