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