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.
18 #include <CDM_Document.hxx>
19 #include <CDM_MetaData.hxx>
20 #include <CDM_ReferenceIterator.hxx>
21 #include <OSD_Path.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>
39 IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReadWriter_1,PCDM_ReadWriter)
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: "
48 //=======================================================================
49 //function : PCDM_ReadWriter_1
51 //=======================================================================
53 PCDM_ReadWriter_1::PCDM_ReadWriter_1() {}
54 static Standard_Integer RemoveExtraSeparator(TCollection_AsciiString& aString) {
56 Standard_Integer i, j, len ;
58 len = aString.Length() ;
60 // Case of network path, such as \\MACHINE\dir
61 for (i = j = 2 ; j <= len ; i++,j++) {
63 for (i = j = 1 ; j <= len ; i++,j++) {
65 Standard_Character c = aString.Value(j) ;
66 aString.SetValue(i,c) ;
68 while(j < len && aString.Value(j+1) == '/') j++ ;
71 if (aString.Value(len) == '/') len-- ;
75 static TCollection_AsciiString AbsolutePath(
76 const TCollection_AsciiString& aDirPath,
77 const TCollection_AsciiString& aRelFilePath)
79 TCollection_AsciiString EmptyString = "" ;
81 if (aRelFilePath.Search(":") == 2 ||
82 (aRelFilePath.Search("\\") == 1 && aRelFilePath.Value(2) == '\\'))
84 if(aRelFilePath.Search("/") == 1)
88 TCollection_AsciiString DirPath = aDirPath, RelFilePath = aRelFilePath ;
89 Standard_Integer i,len ;
92 if(DirPath.Search(":") != 2 &&
93 (DirPath.Search("\\") != 1 || DirPath.Value(2) != '\\'))
95 if (DirPath.Search("/") != 1 )
100 DirPath.ChangeAll('\\','/') ;
101 RelFilePath.ChangeAll('\\','/') ;
104 RemoveExtraSeparator(DirPath) ;
105 len = RemoveExtraSeparator(RelFilePath) ;
107 while (RelFilePath.Search("../") == 1) {
110 RelFilePath = RelFilePath.SubString(4,len) ;
112 if (DirPath.IsEmpty())
114 i = DirPath.SearchFromEnd("/") ;
119 TCollection_AsciiString retx;
126 static TCollection_AsciiString GetDirFromFile(const TCollection_ExtendedString& aFileName) {
127 TCollection_AsciiString theCFile(aFileName);
128 TCollection_AsciiString theDirectory;
129 Standard_Integer i=theCFile.SearchFromEnd("/");
131 // if(i==-1) i=theCFile.SearchFromEnd("\\");
132 if(theCFile.SearchFromEnd("\\") > i)
133 i=theCFile.SearchFromEnd("\\");
135 if(i!=-1) theDirectory=theCFile.SubString(1,i);
138 //=======================================================================
141 //=======================================================================
143 TCollection_AsciiString PCDM_ReadWriter_1::Version() const {
144 return "PCDM_ReadWriter_1";
146 //=======================================================================
147 //function : WriteReferenceCounter
149 //=======================================================================
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);
156 //=======================================================================
157 //function : WriteReferences
159 //=======================================================================
161 void PCDM_ReadWriter_1::WriteReferences(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument,const TCollection_ExtendedString& theReferencerFileName) const {
163 Standard_Integer theNumber = aDocument->ToReferencesNumber();
166 aData->AddToUserInfo(START_REF);
168 CDM_ReferenceIterator it(aDocument);
170 TCollection_ExtendedString ligne;
172 TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(theReferencerFileName);
174 for (;it.More();it.Next()) {
175 ligne = TCollection_ExtendedString(it.ReferenceIdentifier());
177 ligne += TCollection_ExtendedString(it.Document()->Modifications());
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;
186 ligne += TCollection_ExtendedString(thePath);
187 UTL::AddToUserInfo(aData,ligne);
189 aData->AddToUserInfo(END_REF);
193 //=======================================================================
194 //function : WriteExtensions
196 //=======================================================================
198 void PCDM_ReadWriter_1::WriteExtensions(const Handle(Storage_Data)& aData, const Handle(CDM_Document)& aDocument) const {
200 TColStd_SequenceOfExtendedString theExtensions;
201 aDocument->Extensions(theExtensions);
202 Standard_Integer theNumber = theExtensions.Length();
205 aData->AddToUserInfo(START_EXT);
206 for (Standard_Integer i=1; i<=theNumber; i++) {
207 UTL::AddToUserInfo(aData,theExtensions(i));
209 aData->AddToUserInfo(END_EXT);
212 //=======================================================================
213 //function : WriteVersion
215 //=======================================================================
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);
222 //=======================================================================
223 //function : ReadReferenceCounter
225 //=======================================================================
227 Standard_Integer PCDM_ReadWriter_1::ReadReferenceCounter(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const {
229 Standard_Integer theReferencesCounter(0) ;
231 Handle(Storage_BaseDriver) theFileDriver;
232 TCollection_AsciiString aFileNameU(aFileName);
233 if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
234 return theReferencesCounter;
236 Standard_Boolean theFileIsOpen(Standard_False);
239 PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead);
240 theFileIsOpen=Standard_True;
242 Handle(Storage_Schema) s = new Storage_Schema;
243 Storage_HeaderData hd;
244 hd.Read (theFileDriver);
245 const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
247 for ( i =1; i<= refUserInfo.Length() ; i++) {
248 if(refUserInfo(i).Search(REFERENCE_COUNTER) != -1) {
249 try { OCC_CATCH_SIGNALS theReferencesCounter=refUserInfo(i).Token(" ",2).IntegerValue();}
250 catch (Standard_Failure const&) {
251 // std::cout << "warning: could not read the reference counter in " << aFileName << std::endl;
252 TCollection_ExtendedString aMsg("Warning: ");
253 aMsg = aMsg.Cat("could not read the reference counter in ").Cat(aFileName).Cat("\0");
254 if(!theMsgDriver.IsNull())
255 theMsgDriver->Send(aMsg.ToExtString());
261 catch (Standard_Failure const&) {}
265 theFileDriver->Close();
268 return theReferencesCounter;
271 //=======================================================================
272 //function : ReadReferences
274 //=======================================================================
276 void PCDM_ReadWriter_1::ReadReferences(const TCollection_ExtendedString& aFileName, PCDM_SequenceOfReference& theReferences, const Handle(Message_Messenger)& theMsgDriver) const {
278 TColStd_SequenceOfExtendedString ReadReferences;
280 ReadUserInfo(aFileName,START_REF,END_REF,ReadReferences, theMsgDriver);
282 Standard_Integer theReferenceIdentifier;
283 TCollection_ExtendedString theFileName;
284 Standard_Integer theDocumentVersion;
286 TCollection_AsciiString theAbsoluteDirectory=GetDirFromFile(aFileName);
288 for (Standard_Integer i=1; i<=ReadReferences.Length(); i++) {
289 Standard_Integer pos=ReadReferences(i).Search(" ");
291 TCollection_ExtendedString theRest=ReadReferences(i).Split(pos);
292 theReferenceIdentifier=UTL::IntegerValue(ReadReferences(i));
294 Standard_Integer pos2=theRest.Search(" ");
296 theFileName=theRest.Split(pos2);
297 theDocumentVersion=UTL::IntegerValue(theRest);
299 TCollection_AsciiString thePath(theFileName);
300 TCollection_AsciiString theAbsolutePath;
301 if(!theAbsoluteDirectory.IsEmpty()) {
302 theAbsolutePath=AbsolutePath(theAbsoluteDirectory,thePath);
303 if(!theAbsolutePath.IsEmpty()) thePath=theAbsolutePath;
305 if(!theMsgDriver.IsNull()) {
306 // std::cout << "reference found; ReferenceIdentifier: " << theReferenceIdentifier << "; File:" << thePath << ", version:" << theDocumentVersion;
307 TCollection_ExtendedString aMsg("Warning: ");
308 aMsg = aMsg.Cat("reference found; ReferenceIdentifier: ").Cat(theReferenceIdentifier).Cat("; File:").Cat(thePath).Cat(", version:").Cat(theDocumentVersion).Cat("\0");
309 theMsgDriver->Send(aMsg.ToExtString());
311 TCollection_ExtendedString aPathW(thePath);
312 theReferences.Append(PCDM_Reference (theReferenceIdentifier,aPathW,theDocumentVersion));
319 //=======================================================================
320 //function : ReadExtensions
322 //=======================================================================
324 void PCDM_ReadWriter_1::ReadExtensions(const TCollection_ExtendedString& aFileName, TColStd_SequenceOfExtendedString& theExtensions, const Handle(Message_Messenger)& theMsgDriver) const {
326 ReadUserInfo(aFileName,START_EXT,END_EXT,theExtensions, theMsgDriver);
330 //=======================================================================
331 //function : ReadUserInfo
333 //=======================================================================
335 void PCDM_ReadWriter_1::ReadUserInfo(const TCollection_ExtendedString& aFileName,
336 const TCollection_AsciiString& Start,
337 const TCollection_AsciiString& End,
338 TColStd_SequenceOfExtendedString& theUserInfo,
339 const Handle(Message_Messenger)&)
342 Handle(Storage_BaseDriver) theFileDriver;
343 TCollection_AsciiString aFileNameU(aFileName);
344 if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
347 PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead);
348 Handle(Storage_Schema) s = new Storage_Schema;
349 Storage_HeaderData hd;
350 hd.Read (theFileDriver);
351 const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
353 Standard_Integer debut=0,fin=0;
355 for ( i =1; i<= refUserInfo.Length() ; i++) {
356 TCollection_ExtendedString theLine=refUserInfo(i);
357 if(refUserInfo(i)== Start) debut=i;
358 if(refUserInfo(i)== End) fin=i;
361 for (i=debut+1 ; i<fin; i++) {
362 TCollection_ExtendedString aInfoW(refUserInfo(i));
363 theUserInfo.Append(aInfoW);
366 theFileDriver->Close();
369 //=======================================================================
370 //function : ReadDocumentVersion
372 //=======================================================================
374 Standard_Integer PCDM_ReadWriter_1::ReadDocumentVersion(const TCollection_ExtendedString& aFileName, const Handle(Message_Messenger)& theMsgDriver) const {
376 Standard_Integer theVersion(-1);
377 Handle(Storage_BaseDriver) theFileDriver;
378 TCollection_AsciiString aFileNameU(aFileName);
379 if(PCDM::FileDriverType(aFileNameU, theFileDriver) == PCDM_TOFD_Unknown)
382 Standard_Boolean theFileIsOpen(Standard_False);
386 PCDM_ReadWriter::Open(theFileDriver,aFileName,Storage_VSRead);
387 theFileIsOpen=Standard_True;
388 Handle(Storage_Schema) s = new Storage_Schema;
389 Storage_HeaderData hd;
390 hd.Read (theFileDriver);
391 const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
394 for ( i =1; i<= refUserInfo.Length() ; i++) {
395 if(refUserInfo(i).Search(MODIFICATION_COUNTER) != -1) {
396 try { OCC_CATCH_SIGNALS theVersion=refUserInfo(i).Token(" ",2).IntegerValue();}
397 catch (Standard_Failure const&) {
398 // std::cout << "warning: could not read the version in " << aFileName << std::endl;
399 TCollection_ExtendedString aMsg("Warning: ");
400 aMsg = aMsg.Cat("could not read the version in ").Cat(aFileName).Cat("\0");
401 if(!theMsgDriver.IsNull())
402 theMsgDriver->Send(aMsg.ToExtString());
409 catch (Standard_Failure const&) {}
413 theFileDriver->Close();