0023934: Compiler warnings in MS VC++ 10
[occt.git] / src / BinLDrivers / BinLDrivers_DocumentRetrievalDriver.cxx
CommitLineData
b311480e 1// Created on: 2002-10-31
2// Created by: Michael SAZONOV
3// Copyright (c) 2002-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#include <BinLDrivers_DocumentRetrievalDriver.ixx>
22#include <BinLDrivers.hxx>
23#include <BinLDrivers_Marker.hxx>
24#include <BinMDF_ADriver.hxx>
25#include <BinMDataStd.hxx>
26#include <BinObjMgt_Persistent.hxx>
27#include <FSD_BinaryFile.hxx>
28#include <FSD_FileHeader.hxx>
29#include <Standard_ErrorHandler.hxx>
30#include <Standard_Stream.hxx>
31#include <Storage_Schema.hxx>
32#include <TDF_Data.hxx>
33#include <TDocStd_Document.hxx>
34#include <TDocStd_Owner.hxx>
35
36#define SHAPESECTION_POS "SHAPE_SECTION_POS:"
37#define SIZEOFSHAPELABEL 18
38
39#define DATATYPE_MIGRATION
40//#define DATATYPE_MIGRATION_DEB
41//=======================================================================
42//function : BinLDrivers_DocumentRetrievalDriver
43//purpose : Constructor
44//=======================================================================
45
46BinLDrivers_DocumentRetrievalDriver::BinLDrivers_DocumentRetrievalDriver ()
47{
48 myReaderStatus = PCDM_RS_OK;
49}
50
51//=======================================================================
52//function : CreateDocument
53//purpose : pure virtual method definition
54//=======================================================================
55
56Handle(CDM_Document) BinLDrivers_DocumentRetrievalDriver::CreateDocument()
57{
58 return new TDocStd_Document(PCDM_RetrievalDriver::GetFormat());
59}
60
61//=======================================================================
62//function : SchemaName
63//purpose : pure virtual method definition
64//=======================================================================
65
66TCollection_ExtendedString BinLDrivers_DocumentRetrievalDriver::SchemaName() const
67{
68 TCollection_ExtendedString schemaname;
69 return schemaname;
70}
71
72//=======================================================================
73//function : Make
74//purpose : pure virtual method definition
75//=======================================================================
76
77void BinLDrivers_DocumentRetrievalDriver::Make (const Handle(PCDM_Document)&,
78 const Handle(CDM_Document)&)
79{
80}
81
82//=======================================================================
83//function : Read
84//purpose :
85//=======================================================================
86
87#define START_TYPES "START_TYPES"
88#define END_TYPES "END_TYPES"
89
90void BinLDrivers_DocumentRetrievalDriver::Read
91 (const TCollection_ExtendedString& theFileName,
92 const Handle(CDM_Document)& theNewDocument,
93 const Handle(CDM_Application)& theApplication)
94{
95 myReaderStatus = PCDM_RS_DriverFailure;
96 myMsgDriver = theApplication -> MessageDriver();
97
98 const TCollection_ExtendedString aMethStr
99 ("BinLDrivers_DocumentRetrievalDriver: ");
100
101 Handle(TDocStd_Document) aDoc =
102 Handle(TDocStd_Document)::DownCast(theNewDocument);
103 if (aDoc.IsNull()) {
104#ifdef DEB
105 WriteMessage (aMethStr + "error: null document");
106#endif
107 myReaderStatus = PCDM_RS_NoDocument;
108 return;
109 }
110
111 TCollection_AsciiString aFileName (theFileName,'?');
112
113 // 1. Read the information section
114 Handle(Storage_HeaderData) aHeaderData;
115 Storage_Position anInfoSectionEnd = ReadInfoSection( aFileName, aHeaderData );
116 if (!anInfoSectionEnd) {
117 WriteMessage (aMethStr + "error: file has invalid header");
118 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
119 return;
120 }
121
122 // 1.a Version of writer
123 if (!aHeaderData->StorageVersion().IsIntegerValue()) {
124 // file has no format version
125 WriteMessage (aMethStr + "error: file has no format version");
126 myReaderStatus = PCDM_RS_FormatFailure;
127 return;
128 }
129 Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue();
130 Standard_Integer aCurrVer = BinLDrivers::StorageVersion().IntegerValue();
131 // maintain one-way compatibility starting from version 2+
132 if (aFileVer < 2 || aFileVer > aCurrVer) {
133 // file was written with another version
134 WriteMessage (aMethStr + "error: wrong file version: " +
135 aHeaderData->StorageVersion() + " while current is " +
136 BinLDrivers::StorageVersion());
137 myReaderStatus = PCDM_RS_NoVersion;
138 return;
139 }
140
141 // 1.b Retrieve the Types table
142 TColStd_SequenceOfAsciiString aTypeNames; //Sequence of types in file
143 const TColStd_SequenceOfAsciiString& aUserInfo = aHeaderData->UserInfo();
144 Standard_Boolean begin = Standard_False;
145 Standard_Integer i;
146 for (i=1; i <= aUserInfo.Length(); i++) {
147 //const TCollection_AsciiString& aStr = aUserInfo(i);
148 TCollection_AsciiString aStr = aUserInfo(i);
149 if (aStr == START_TYPES)
150 begin = Standard_True;
151 else if (aStr == END_TYPES)
152 break;
153 else if (begin) {
154 if(aFileVer < 5) {
155#ifdef DATATYPE_MIGRATION
156 TCollection_AsciiString newName;
157 if(Storage_Schema::CheckTypeMigration(aStr, newName)) {
158#ifdef DATATYPE_MIGRATION_DEB
159 cout << "CheckTypeMigration:OldType = " <<aStr << " Len = "<<aStr.Length()<<endl;
160 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
161#endif
162 aStr = newName;
163 }
164#endif
165 }
166 aTypeNames.Append (aStr);
167 }
168 }
169 if (myDrivers.IsNull())
170 myDrivers = AttributeDrivers (myMsgDriver);
171 myDrivers->AssignIds (aTypeNames);
172
173 // recognize types not supported by drivers
174 myMapUnsupported.Clear();
175 for (i=1; i <= aTypeNames.Length(); i++)
176 if (myDrivers->GetDriver(i).IsNull())
177 myMapUnsupported.Add(i);
178 if (!myMapUnsupported.IsEmpty()) {
179 WriteMessage (aMethStr + "warning: "
180 "the following attributes have no driver:");
181 for (i=1; i <= aTypeNames.Length(); i++)
182 if (myMapUnsupported.Contains(i))
183 WriteMessage (aTypeNames(i));
184 }
185
186 // Open the file stream
187#ifdef WNT
188 ifstream anIS (aFileName.ToCString(), ios::in | ios::binary);
189#else
190 ifstream anIS (aFileName.ToCString());
191#endif
192
193 if (!anIS) {
194 // Can not open file
195 WriteMessage (aMethStr + "error: can't open file " + theFileName);
196 myReaderStatus = PCDM_RS_OpenError;
197 return;
198 }
199
200 // skip info section
201 anIS.seekg( (streampos) anInfoSectionEnd );
202
203 // propagate the opened document version to data drivers
204 PropagateDocumentVersion(aFileVer);
205
206 // 2. Read document contents
207
208 // 2a. Retrieve data from the stream:
209 myRelocTable.Clear();
210 mySections.Clear();
211 myPAtt.Init();
212 Handle(TDF_Data) aData = new TDF_Data();
60be1f9b 213 streampos aDocumentPos = -1;
7fd59977 214
215 // 2b. Read the TOC of Sections
216 if (aFileVer >= 3) {
217 BinLDrivers_DocumentSection aSection;
218 do {
219 BinLDrivers_DocumentSection::ReadTOC (aSection, anIS);
220 mySections.Append(aSection);
221 } while
222 (!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS));
223 aDocumentPos = anIS.tellg(); // position of root label
224
225 BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
226 for (; anIterS.More(); anIterS.Next()) {
227 BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
228 if (aCurSection.IsPostRead() == Standard_False) {
229 anIS.seekg ((streampos) aCurSection.Offset());
230 if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
231 ReadShapeSection (aCurSection, anIS);
232 else
233 ReadSection (aCurSection, theNewDocument, anIS);
234 }
235 }
236 } else { //aFileVer < 3
237 aDocumentPos = anIS.tellg(); // position of root label
238
239 // retrieve SHAPESECTION_POS string
240 char aShapeSecLabel[SIZEOFSHAPELABEL + 1];
241 aShapeSecLabel[SIZEOFSHAPELABEL] = 0x00;
242 anIS.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS
243 TCollection_AsciiString aShapeLabel(aShapeSecLabel);
244 // detect if a file was written in old fashion (version 2 without shapes)
245 // and if so then skip reading ShapeSection
246 if (aShapeLabel.Length() > 0) {
247 // version 2+(with shapes) and higher goes here
248 if(aShapeLabel.Length() <= 0 || aShapeLabel != SHAPESECTION_POS) {
249 WriteMessage (aMethStr + "error: Format failure");
250 myReaderStatus = PCDM_RS_FormatFailure;
251 return;
252 }
253
254 // retrieve ShapeSection Position
255 Standard_Integer aShapeSectionPos; // go to ShapeSection
256 anIS.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer));
257
258#if DO_INVERSE
259 aShapeSectionPos = InverseInt (aShapeSectionPos);
260#endif
261#ifdef DATATYPE_MIGRATION_DEB
262 cout <<"aShapeSectionPos = " <<aShapeSectionPos <<endl;
263#endif
264 if(aShapeSectionPos) {
265 aDocumentPos = anIS.tellg();
266 anIS.seekg((streampos) aShapeSectionPos);
267
105aae76 268 CheckShapeSection(aShapeSectionPos, anIS);
7fd59977 269 // Read Shapes
270 BinLDrivers_DocumentSection aCurSection;
271 ReadShapeSection (aCurSection, anIS, Standard_False);
272 }
273 }
274 } // end of reading Sections or shape section
275
276 // Return to read of the Document structure
60be1f9b 277 anIS.seekg(aDocumentPos);
7fd59977 278
279 // read the header (tag) of the root label
280 Standard_Integer aTag;
281 anIS.read ((char*)&aTag, sizeof(Standard_Integer));
282
283 // read sub-tree of the root label
284 Standard_Integer nbRead = ReadSubTree (anIS, aData->Root());
285 myPAtt.Destroy(); // free buffer
286 myRelocTable.Clear();
287 myMapUnsupported.Clear();
288
289 if (nbRead > 0) {
290 // attach data to the document
291 aDoc->SetData (aData);
292 TDocStd_Owner::SetDocument (aData, aDoc);
293 aDoc->SetComments(aHeaderData->Comments());
294 myReaderStatus = PCDM_RS_OK;
295 }
296
297 // Read Sections (post-reading type)
298 if (aFileVer >= 3) {
299 BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
300 for (; anIterS.More(); anIterS.Next()) {
301 BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
302 if (aCurSection.IsPostRead()) {
303 anIS.seekg ((streampos) aCurSection.Offset());
304 ReadSection (aCurSection, theNewDocument, anIS);
305 }
306 }
307 }
308}
309
310//=======================================================================
311//function : ReadSubTree
312//purpose :
313//=======================================================================
314
315Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
316 (Standard_IStream& theIS,
317 const TDF_Label& theLabel)
318{
319 Standard_Integer nbRead = 0;
320 static TCollection_ExtendedString aMethStr
321 ("BinLDrivers_DocumentRetrievalDriver: ");
322
323 // Read attributes:
324 theIS >> myPAtt;
325 while (theIS && myPAtt.TypeId() > 0 && // not an end marker ?
326 myPAtt.Id() > 0) { // not a garbage ?
327 // get a driver according to TypeId
328 Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId());
329 if (!aDriver.IsNull()) {
330 // create transient attribute
331 nbRead++;
332 Standard_Integer anID = myPAtt.Id();
333 Handle(TDF_Attribute) tAtt;
334 Standard_Boolean isBound = myRelocTable.IsBound(anID);
335 if (isBound)
336 tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID));
337 else
338 tAtt = aDriver->NewEmpty();
339 if (tAtt->Label().IsNull())
340 theLabel.AddAttribute (tAtt);
341 else
342 WriteMessage (aMethStr +
343 "warning: attempt to attach attribute " +
344 aDriver->TypeName() + " to a second label");
345
346 Standard_Boolean ok = aDriver->Paste (myPAtt, tAtt, myRelocTable);
347 if (!ok) {
348 // error converting persistent to transient
349 WriteMessage (aMethStr + "warning: failure reading attribute " +
350 aDriver->TypeName());
351 }
352 else if (!isBound)
353 myRelocTable.Bind (anID, tAtt);
354 }
355 else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
356 WriteMessage (aMethStr + "warning: type ID not registered in header: "
357 + myPAtt.TypeId());
358
359 // read next attribute
360 theIS >> myPAtt;
361 }
362 if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) {
363 // unexpected EOF or garbage data
364 WriteMessage (aMethStr + "error: unexpected EOF or garbage data");
365 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
366 return -1;
367 }
368
369 // Read children:
370 // read the tag of a child label
371 Standard_Integer aTag = BinLDrivers_ENDLABEL;
372 theIS.read ((char*) &aTag, sizeof(Standard_Integer));
373#if DO_INVERSE
374 aTag = InverseInt (aTag);
375#endif
376 while (theIS && aTag >= 0) { // not an end marker ?
377 // create sub-label
378 TDF_Label aLab = theLabel.FindChild (aTag, Standard_True);
379
380 // read sub-tree
381 Standard_Integer nbSubRead = ReadSubTree(theIS, aLab);
382 // check for error
383 if (nbSubRead == -1)
384 return -1;
385 nbRead += nbSubRead;
386
387 // read the tag of the next child
388 theIS.read ((char*) &aTag, sizeof(Standard_Integer));
389#if DO_INVERSE
390 aTag = InverseInt (aTag);
391#endif
392 }
393 if (aTag != BinLDrivers_ENDLABEL) {
394 // invalid end label marker
395 WriteMessage (aMethStr + "error: invalid end label marker");
396 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
397 return -1;
398 }
399
400 return nbRead;
401}
402
403//=======================================================================
404//function : AttributeDrivers
405//purpose :
406//=======================================================================
407
408Handle(BinMDF_ADriverTable) BinLDrivers_DocumentRetrievalDriver::AttributeDrivers
409 (const Handle(CDM_MessageDriver)& theMessageDriver)
410{
411 return BinLDrivers::AttributeDrivers (theMessageDriver);
412}
413
414//=======================================================================
415//function : ReadInfoSection
416//purpose : Read the info section of theFile, return a file
417// position corresponding to the info section end
418//=======================================================================
419
420Storage_Position BinLDrivers_DocumentRetrievalDriver::ReadInfoSection
421 (const TCollection_AsciiString& theFileName,
422 Handle(Storage_HeaderData)& theData)
423{
424 TCollection_ExtendedString aMsg
425 ( "BinLDrivers_DocumentRetrievalDriver: error: ");
426
427 FSD_BinaryFile aFileDriver;
428 Storage_Position aPos = 0;
429 if (aFileDriver.Open( theFileName, Storage_VSRead ) == Storage_VSOk)
430 {
431 Storage_Schema aSchema;
432 theData = aSchema.ReadHeaderSection( aFileDriver );
433
434 if (theData->ErrorStatus() == Storage_VSOk)
435 aPos = aFileDriver.Tell();
436 else
437 WriteMessage( aMsg + theData->ErrorStatusExtension() );
438 }
439 else
440 WriteMessage( aMsg + "can not open file " + theFileName);
441
442 aFileDriver.Close();
443
444 return aPos;
445}
446
447//=======================================================================
448//function : WriteMessage
449//purpose : write theMessage to the MessageDriver of
450// theApplication
451//=======================================================================
452
453void BinLDrivers_DocumentRetrievalDriver::WriteMessage
454 (const TCollection_ExtendedString& theMsg)
455{
456 if (!myMsgDriver.IsNull())
457 myMsgDriver->Write (theMsg.ToExtString());
458}
459
460//=======================================================================
461//function : ReadSection
462//purpose :
463//=======================================================================
464
465void BinLDrivers_DocumentRetrievalDriver::ReadSection
466 (BinLDrivers_DocumentSection& /*theSection*/,
467 const Handle(CDM_Document)& /*theDocument*/,
468 Standard_IStream& /*theIS*/)
469{
470 // empty; should be redefined in subclasses
471}
472
473//=======================================================================
474//function : ReadShapeSection
475//purpose :
476//=======================================================================
477
478void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection
479 (BinLDrivers_DocumentSection& theSection,
480 Standard_IStream& /*theIS*/,
481 const Standard_Boolean isMess)
482
483{
484 if(isMess && theSection.Length()) {
485 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
486 WriteMessage (aMethStr + "warning: Geometry is not supported by Lite schema. ");
487 }
488}
489
490//=======================================================================
491//function : CheckShapeSection
492//purpose :
493//=======================================================================
494void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection(
495 const Storage_Position& ShapeSectionPos,
496 Standard_IStream& IS)
497{
498 if(!IS.eof()) {
499#if defined(WNT) || defined(HAVE_IOSTREAM)
105aae76 500 const std::streamoff endPos = IS.rdbuf()->pubseekoff(0L, std::ios_base::end, std::ios_base::in);
7fd59977 501#else
502 const Storage_Position endPos = IS.rdbuf()->seekoff(0L, unsafe_ios::end, unsafe_ios::in);
503#endif
504#ifdef DATATYPE_MIGRATION_DEB
505 cout << "endPos = " << endPos <<endl;
506#endif
507 if(ShapeSectionPos != endPos) {
508 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
509 WriteMessage (aMethStr + "warning: Geometry is not supported by Lite schema. ");
510 }
511 }
512}
513
514//=======================================================================
515//function : PropagateDocumentVersion
516//purpose :
517//=======================================================================
518void BinLDrivers_DocumentRetrievalDriver::PropagateDocumentVersion(const Standard_Integer theDocVersion )
519{
520 BinMDataStd::SetDocumentVersion(theDocVersion);
521}