0031353: TDocStd_Application does not have api to set progress indicator
[occt.git] / src / PCDM / PCDM_ReadWriter_1.cxx
1 // Created on: 1997-12-09
2 // Created by: Jean-Louis Frenkel
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <CDM_Document.hxx>
19 #include <CDM_MetaData.hxx>
20 #include <CDM_ReferenceIterator.hxx>
21 #include <OSD_Path.hxx>
22 #include <PCDM.hxx>
23 #include <PCDM_BaseDriverPointer.hxx>
24 #include <PCDM_ReadWriter_1.hxx>
25 #include <PCDM_Reference.hxx>
26 #include <PCDM_TypeOfFileDriver.hxx>
27 #include <Message_Messenger.hxx>
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>
38
39 IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReadWriter_1,PCDM_ReadWriter)
40
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() ;
59 #ifdef _WIN32
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 = "" ;
80 #ifdef _WIN32
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   
91 #ifdef _WIN32
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
99 #ifdef _WIN32
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) {
127   TCollection_AsciiString theCFile(aFileName);
128   TCollection_AsciiString theDirectory;
129   Standard_Integer i=theCFile.SearchFromEnd("/");
130 #ifdef _WIN32    
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
180       TCollection_AsciiString thePath(it.Document()->MetaData()->FileName());
181       TCollection_AsciiString theRelativePath;
182       if(!theAbsoluteDirectory.IsEmpty()) {
183         theRelativePath=OSD_Path::RelativePath(theAbsoluteDirectory,thePath);
184         if(!theRelativePath.IsEmpty()) thePath=theRelativePath;
185       }
186       ligne +=  TCollection_ExtendedString(thePath);
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
227 Standard_Integer PCDM_ReadWriter_1::ReadReferenceCounter(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const {
228
229   static Standard_Integer theReferencesCounter ;
230   theReferencesCounter=0;
231   static Standard_Integer i ;
232
233   Handle(Storage_BaseDriver) theFileDriver;
234   TCollection_AsciiString aFileNameU(aFileName);
235   if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
236     return theReferencesCounter;
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;
247     Storage_HeaderData hd;
248     hd.Read (theFileDriver);
249     const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
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 const&) {
255 //        std::cout << "warning: could not read the reference counter in " << aFileName << std::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()) 
259             theMsgDriver->Send(aMsg.ToExtString());
260         }
261       }
262     }
263     
264   }
265   catch (Standard_Failure const&) {}
266
267   if(theFileIsOpen)
268   {
269     theFileDriver->Close();
270   }
271
272   return theReferencesCounter;
273 }
274   
275 //=======================================================================
276 //function : ReadReferences
277 //purpose  : 
278 //=======================================================================
279
280 void PCDM_ReadWriter_1::ReadReferences(const TCollection_ExtendedString& aFileName, PCDM_SequenceOfReference& theReferences, const Handle(Message_Messenger)& theMsgDriver) const  {
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       
303       TCollection_AsciiString thePath(theFileName);
304       TCollection_AsciiString theAbsolutePath;
305       if(!theAbsoluteDirectory.IsEmpty()) {
306         theAbsolutePath=AbsolutePath(theAbsoluteDirectory,thePath);
307         if(!theAbsolutePath.IsEmpty()) thePath=theAbsolutePath;
308       }
309       if(!theMsgDriver.IsNull()) {
310 //      std::cout << "reference found; ReferenceIdentifier: " << theReferenceIdentifier << "; File:" << thePath << ", version:" << theDocumentVersion;
311         TCollection_ExtendedString aMsg("Warning: ");
312         aMsg = aMsg.Cat("reference found; ReferenceIdentifier:  ").Cat(theReferenceIdentifier).Cat("; File:").Cat(thePath).Cat(", version:").Cat(theDocumentVersion).Cat("\0");
313         theMsgDriver->Send(aMsg.ToExtString());
314       }
315       TCollection_ExtendedString aPathW(thePath);
316       theReferences.Append(PCDM_Reference (theReferenceIdentifier,aPathW,theDocumentVersion));
317     
318     }
319   }
320
321 }
322
323 //=======================================================================
324 //function : ReadExtensions
325 //purpose  : 
326 //=======================================================================
327
328 void PCDM_ReadWriter_1::ReadExtensions(const TCollection_ExtendedString& aFileName, TColStd_SequenceOfExtendedString& theExtensions, const Handle(Message_Messenger)& theMsgDriver) const {
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,
343                                      const Handle(Message_Messenger)&)
344 {
345   static Standard_Integer i ;
346   Handle(Storage_BaseDriver) theFileDriver;
347   TCollection_AsciiString aFileNameU(aFileName);
348   if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
349     return;
350
351   PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead);
352   Handle(Storage_Schema) s = new Storage_Schema;
353   Storage_HeaderData hd;
354   hd.Read (theFileDriver);
355   const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
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++) {
366       TCollection_ExtendedString aInfoW(refUserInfo(i));
367       theUserInfo.Append(aInfoW);
368     }
369   }
370   theFileDriver->Close();
371 }
372
373 //=======================================================================
374 //function : ReadDocumentVersion
375 //purpose  : 
376 //=======================================================================
377
378 Standard_Integer PCDM_ReadWriter_1::ReadDocumentVersion(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const {
379
380   static Standard_Integer theVersion ;
381   theVersion=-1;
382
383   Handle(Storage_BaseDriver) theFileDriver;
384   TCollection_AsciiString aFileNameU(aFileName);
385   if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
386     return theVersion;
387
388   static Standard_Boolean theFileIsOpen ;
389   theFileIsOpen =Standard_False;
390
391   try {
392     OCC_CATCH_SIGNALS
393     PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead);
394     theFileIsOpen=Standard_True;
395     Handle(Storage_Schema) s = new Storage_Schema;
396     Storage_HeaderData hd;
397     hd.Read (theFileDriver);
398     const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
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();}
404     catch (Standard_Failure const&) {
405 //        std::cout << "warning: could not read the version in " << aFileName << std::endl;
406           TCollection_ExtendedString aMsg("Warning: ");
407           aMsg = aMsg.Cat("could not read the version in ").Cat(aFileName).Cat("\0");
408           if(!theMsgDriver.IsNull()) 
409             theMsgDriver->Send(aMsg.ToExtString());
410         }
411
412       }
413     }
414   }
415
416   catch (Standard_Failure const&) {}
417
418   if(theFileIsOpen)
419   {
420     theFileDriver->Close();
421   }
422
423   return theVersion;
424 }