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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <PCDM_ReadWriter_1.ixx>
19 #include <Storage_Data.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TCollection_ExtendedString.hxx>
22 #include <CDM_Document.hxx>
23 #include <CDM_ReferenceIterator.hxx>
24 #include <CDM_MetaData.hxx>
25 #include <TColStd_SequenceOfExtendedString.hxx>
26 #include <Storage_Schema.hxx>
27 #include <Storage_HeaderData.hxx>
28 #include <TColStd_SequenceOfAsciiString.hxx>
29 #include <PCDM_Reference.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <OSD_Path.hxx>
32 #include <PCDM_BaseDriverPointer.hxx>
34 #include <PCDM_TypeOfFileDriver.hxx>
36 #define START_REF "START_REF"
37 #define END_REF "END_REF"
38 #define START_EXT "START_EXT"
39 #define END_EXT "END_EXT"
40 #define MODIFICATION_COUNTER "MODIFICATION_COUNTER: "
41 #define REFERENCE_COUNTER "REFERENCE_COUNTER: "
43 //=======================================================================
44 //function : PCDM_ReadWriter_1
46 //=======================================================================
48 PCDM_ReadWriter_1::PCDM_ReadWriter_1() {}
49 static Standard_Integer RemoveExtraSeparator(TCollection_AsciiString& aString) {
51 Standard_Integer i, j, len ;
53 len = aString.Length() ;
55 // Case of network path, such as \\MACHINE\dir
56 for (i = j = 2 ; j <= len ; i++,j++) {
58 for (i = j = 1 ; j <= len ; i++,j++) {
60 Standard_Character c = aString.Value(j) ;
61 aString.SetValue(i,c) ;
63 while(j < len && aString.Value(j+1) == '/') j++ ;
66 if (aString.Value(len) == '/') len-- ;
70 static TCollection_AsciiString AbsolutePath(
71 const TCollection_AsciiString& aDirPath,
72 const TCollection_AsciiString& aRelFilePath)
74 TCollection_AsciiString EmptyString = "" ;
76 if (aRelFilePath.Search(":") == 2 ||
77 (aRelFilePath.Search("\\") == 1 && aRelFilePath.Value(2) == '\\'))
79 if(aRelFilePath.Search("/") == 1)
83 TCollection_AsciiString DirPath = aDirPath, RelFilePath = aRelFilePath ;
84 Standard_Integer i,len ;
87 if(DirPath.Search(":") != 2 &&
88 (DirPath.Search("\\") != 1 || DirPath.Value(2) != '\\'))
90 if (DirPath.Search("/") != 1 )
95 DirPath.ChangeAll('\\','/') ;
96 RelFilePath.ChangeAll('\\','/') ;
99 RemoveExtraSeparator(DirPath) ;
100 len = RemoveExtraSeparator(RelFilePath) ;
102 while (RelFilePath.Search("../") == 1) {
105 RelFilePath = RelFilePath.SubString(4,len) ;
107 if (DirPath.IsEmpty())
109 i = DirPath.SearchFromEnd("/") ;
114 TCollection_AsciiString retx;
121 static TCollection_AsciiString GetDirFromFile(const TCollection_ExtendedString& aFileName) {
122 TCollection_AsciiString theCFile=UTL::CString(aFileName);
123 TCollection_AsciiString theDirectory;
124 Standard_Integer i=theCFile.SearchFromEnd("/");
126 // if(i==-1) i=theCFile.SearchFromEnd("\\");
127 if(theCFile.SearchFromEnd("\\") > i)
128 i=theCFile.SearchFromEnd("\\");
130 if(i!=-1) theDirectory=theCFile.SubString(1,i);
133 //=======================================================================
136 //=======================================================================
138 TCollection_AsciiString PCDM_ReadWriter_1::Version() const {
139 return "PCDM_ReadWriter_1";
141 //=======================================================================
142 //function : WriteReferenceCounter
144 //=======================================================================
146 void PCDM_ReadWriter_1::WriteReferenceCounter(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const {
147 TCollection_AsciiString ligne(REFERENCE_COUNTER);
148 ligne+=aDocument->ReferenceCounter();
149 aData->AddToUserInfo(ligne);
151 //=======================================================================
152 //function : WriteReferences
154 //=======================================================================
156 void PCDM_ReadWriter_1::WriteReferences(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument,const TCollection_ExtendedString& theReferencerFileName) const {
158 Standard_Integer theNumber = aDocument->ToReferencesNumber();
161 aData->AddToUserInfo(START_REF);
163 CDM_ReferenceIterator it(aDocument);
165 TCollection_ExtendedString ligne;
167 TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(theReferencerFileName);
169 for (;it.More();it.Next()) {
170 ligne = TCollection_ExtendedString(it.ReferenceIdentifier());
172 ligne += TCollection_ExtendedString(it.Document()->Modifications());
175 TCollection_AsciiString thePath=UTL::CString(it.Document()->MetaData()->FileName());
176 TCollection_AsciiString theRelativePath;
177 if(!theAbsoluteDirectory.IsEmpty()) {
178 theRelativePath=OSD_Path::RelativePath(theAbsoluteDirectory,thePath);
179 if(!theRelativePath.IsEmpty()) thePath=theRelativePath;
181 ligne += UTL::ExtendedString(thePath);
182 UTL::AddToUserInfo(aData,ligne);
184 aData->AddToUserInfo(END_REF);
188 //=======================================================================
189 //function : WriteExtensions
191 //=======================================================================
193 void PCDM_ReadWriter_1::WriteExtensions(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const {
195 TColStd_SequenceOfExtendedString theExtensions;
196 aDocument->Extensions(theExtensions);
197 Standard_Integer theNumber = theExtensions.Length();
200 aData->AddToUserInfo(START_EXT);
201 for (Standard_Integer i=1; i<=theNumber; i++) {
202 UTL::AddToUserInfo(aData,theExtensions(i));
204 aData->AddToUserInfo(END_EXT);
207 //=======================================================================
208 //function : WriteVersion
210 //=======================================================================
212 void PCDM_ReadWriter_1::WriteVersion(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const {
213 TCollection_AsciiString ligne(MODIFICATION_COUNTER);
214 ligne+=aDocument->Modifications();
215 aData->AddToUserInfo(ligne);
217 //=======================================================================
218 //function : ReadReferenceCounter
220 //=======================================================================
222 Standard_Integer PCDM_ReadWriter_1::ReadReferenceCounter(const TCollection_ExtendedString& aFileName, const Handle(CDM_MessageDriver)& theMsgDriver) const {
224 static Standard_Integer theReferencesCounter ;
225 theReferencesCounter=0;
226 static Standard_Integer i ;
228 PCDM_BaseDriverPointer theFileDriver;
229 if(PCDM::FileDriverType(TCollection_AsciiString(UTL::CString(aFileName)), theFileDriver) == PCDM_TOFD_Unknown) return theReferencesCounter;
231 static Standard_Boolean theFileIsOpen ;
232 theFileIsOpen=Standard_False;
236 PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead);
237 theFileIsOpen=Standard_True;
239 Handle(Storage_Schema) s = new Storage_Schema;
240 Handle(Storage_HeaderData) hd = s->ReadHeaderSection(*theFileDriver);
241 const TColStd_SequenceOfAsciiString &refUserInfo = hd->UserInfo();
243 for ( i =1; i<= refUserInfo.Length() ; i++) {
244 if(refUserInfo(i).Search(REFERENCE_COUNTER) != -1) {
245 try { OCC_CATCH_SIGNALS theReferencesCounter=refUserInfo(i).Token(" ",2).IntegerValue();}
246 catch (Standard_Failure) {
247 // cout << "warning: could not read the reference counter in " << aFileName << endl;
248 TCollection_ExtendedString aMsg("Warning: ");
249 aMsg = aMsg.Cat("could not read the reference counter in ").Cat(aFileName).Cat("\0");
250 if(!theMsgDriver.IsNull())
251 theMsgDriver->Write(aMsg.ToExtString());
257 catch (Standard_Failure) {}
259 if(theFileIsOpen) theFileDriver->Close();
261 delete theFileDriver;
262 return theReferencesCounter;
265 //=======================================================================
266 //function : ReadReferences
268 //=======================================================================
270 void PCDM_ReadWriter_1::ReadReferences(const TCollection_ExtendedString& aFileName, PCDM_SequenceOfReference& theReferences, const Handle(CDM_MessageDriver)& theMsgDriver) const {
272 TColStd_SequenceOfExtendedString ReadReferences;
274 ReadUserInfo(aFileName,START_REF,END_REF,ReadReferences, theMsgDriver);
276 Standard_Integer theReferenceIdentifier;
277 TCollection_ExtendedString theFileName;
278 Standard_Integer theDocumentVersion;
280 TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(aFileName);
282 for (Standard_Integer i=1; i<=ReadReferences.Length(); i++) {
283 Standard_Integer pos=ReadReferences(i).Search(" ");
285 TCollection_ExtendedString theRest=ReadReferences(i).Split(pos);
286 theReferenceIdentifier=UTL::IntegerValue(ReadReferences(i));
288 Standard_Integer pos2=theRest.Search(" ");
290 theFileName=theRest.Split(pos2);
291 theDocumentVersion=UTL::IntegerValue(theRest);
293 TCollection_AsciiString thePath=UTL::CString(theFileName);
294 TCollection_AsciiString theAbsolutePath;
295 if(!theAbsoluteDirectory.IsEmpty()) {
296 theAbsolutePath=AbsolutePath(theAbsoluteDirectory,thePath);
297 if(!theAbsolutePath.IsEmpty()) thePath=theAbsolutePath;
299 if(!theMsgDriver.IsNull()) {
300 // cout << "reference found; ReferenceIdentifier: " << theReferenceIdentifier << "; File:" << thePath << ", version:" << theDocumentVersion;
301 TCollection_ExtendedString aMsg("Warning: ");
302 aMsg = aMsg.Cat("reference found; ReferenceIdentifier: ").Cat(theReferenceIdentifier).Cat("; File:").Cat(thePath).Cat(", version:").Cat(theDocumentVersion).Cat("\0");
303 theMsgDriver->Write(aMsg.ToExtString());
305 theReferences.Append(PCDM_Reference (theReferenceIdentifier,UTL::ExtendedString(thePath),theDocumentVersion));
312 //=======================================================================
313 //function : ReadExtensions
315 //=======================================================================
317 void PCDM_ReadWriter_1::ReadExtensions(const TCollection_ExtendedString& aFileName, TColStd_SequenceOfExtendedString& theExtensions, const Handle(CDM_MessageDriver)& theMsgDriver) const {
319 ReadUserInfo(aFileName,START_EXT,END_EXT,theExtensions, theMsgDriver);
323 //=======================================================================
324 //function : ReadUserInfo
326 //=======================================================================
328 void PCDM_ReadWriter_1::ReadUserInfo(const TCollection_ExtendedString& aFileName,
329 const TCollection_AsciiString& Start,
330 const TCollection_AsciiString& End,
331 TColStd_SequenceOfExtendedString& theUserInfo,
332 const Handle(CDM_MessageDriver)&) {
334 static Standard_Integer i ;
335 PCDM_BaseDriverPointer theFileDriver;
336 if(PCDM::FileDriverType(TCollection_AsciiString(UTL::CString(aFileName)), theFileDriver) == PCDM_TOFD_Unknown) return;
338 PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead);
339 Handle(Storage_Schema) s = new Storage_Schema;
340 Handle(Storage_HeaderData) hd = s->ReadHeaderSection(*theFileDriver);
341 const TColStd_SequenceOfAsciiString &refUserInfo = hd->UserInfo();
343 Standard_Integer debut=0,fin=0;
345 for ( i =1; i<= refUserInfo.Length() ; i++) {
346 TCollection_ExtendedString theLine=refUserInfo(i);
347 if(refUserInfo(i)== Start) debut=i;
348 if(refUserInfo(i)== End) fin=i;
351 for (i=debut+1 ; i<fin; i++) {
352 theUserInfo.Append(UTL::ExtendedString(refUserInfo(i)));
355 theFileDriver->Close();
356 delete theFileDriver;
359 //=======================================================================
360 //function : ReadDocumentVersion
362 //=======================================================================
364 Standard_Integer PCDM_ReadWriter_1::ReadDocumentVersion(const TCollection_ExtendedString& aFileName, const Handle(CDM_MessageDriver)& theMsgDriver) const {
366 static Standard_Integer theVersion ;
369 PCDM_BaseDriverPointer theFileDriver;
370 if(PCDM::FileDriverType(TCollection_AsciiString(UTL::CString(aFileName)), theFileDriver) == PCDM_TOFD_Unknown) return theVersion;
372 static Standard_Boolean theFileIsOpen ;
373 theFileIsOpen =Standard_False;
377 PCDM_ReadWriter::Open(*theFileDriver,aFileName,Storage_VSRead);
378 theFileIsOpen=Standard_True;
379 Handle(Storage_Schema) s = new Storage_Schema;
380 Handle(Storage_HeaderData) hd = s->ReadHeaderSection(*theFileDriver);
381 const TColStd_SequenceOfAsciiString &refUserInfo = hd->UserInfo();
383 static Standard_Integer i ;
384 for ( i =1; i<= refUserInfo.Length() ; i++) {
385 if(refUserInfo(i).Search(MODIFICATION_COUNTER) != -1) {
386 try { OCC_CATCH_SIGNALS theVersion=refUserInfo(i).Token(" ",2).IntegerValue();}
387 catch (Standard_Failure) {
388 // cout << "warning: could not read the version in " << aFileName << endl;
389 TCollection_ExtendedString aMsg("Warning: ");
390 aMsg = aMsg.Cat("could not read the version in ").Cat(aFileName).Cat("\0");
391 if(!theMsgDriver.IsNull())
392 theMsgDriver->Write(aMsg.ToExtString());
399 catch (Standard_Failure) {}
401 if(theFileIsOpen) theFileDriver->Close();
402 delete theFileDriver;