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