Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2002-10-29 |
2 | // Created by: Michael SAZONOV | |
973c2be1 | 3 | // Copyright (c) 2002-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
7fd59977 | 15 | |
42cf5bc1 | 16 | |
7fd59977 | 17 | #include <BinLDrivers.hxx> |
42cf5bc1 | 18 | #include <BinLDrivers_DocumentStorageDriver.hxx> |
7fd59977 | 19 | #include <BinLDrivers_Marker.hxx> |
42cf5bc1 | 20 | #include <BinMDF_ADriverTable.hxx> |
7fd59977 | 21 | #include <BinObjMgt_Persistent.hxx> |
d5c71e20 | 22 | #include <BinObjMgt_Position.hxx> |
7fd59977 | 23 | #include <CDM_Application.hxx> |
83ae3591 | 24 | #include <Message_Messenger.hxx> |
7fd59977 | 25 | #include <FSD_BinaryFile.hxx> |
26 | #include <FSD_FileHeader.hxx> | |
27e64adb | 27 | #include <OSD_FileSystem.hxx> |
7fd59977 | 28 | #include <PCDM_ReadWriter.hxx> |
42cf5bc1 | 29 | #include <Standard_Type.hxx> |
7fd59977 | 30 | #include <Storage_Schema.hxx> |
42cf5bc1 | 31 | #include <TCollection_AsciiString.hxx> |
32 | #include <TCollection_ExtendedString.hxx> | |
7fd59977 | 33 | #include <TDF_AttributeIterator.hxx> |
34 | #include <TDF_ChildIterator.hxx> | |
35 | #include <TDF_Data.hxx> | |
42cf5bc1 | 36 | #include <TDF_Label.hxx> |
7fd59977 | 37 | #include <TDF_Tool.hxx> |
38 | #include <TDocStd_Document.hxx> | |
7e785937 | 39 | #include <Message_ProgressScope.hxx> |
7fd59977 | 40 | |
92efcf78 | 41 | IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentStorageDriver,PCDM_StorageDriver) |
42 | ||
7fd59977 | 43 | #define SHAPESECTION_POS (Standard_CString)"SHAPE_SECTION_POS:" |
d5c71e20 | 44 | #define ENDSECTION_POS (Standard_CString)":" |
7fd59977 | 45 | |
46 | //======================================================================= | |
47 | //function : BinLDrivers_DocumentStorageDriver | |
48 | //purpose : Constructor | |
49 | //======================================================================= | |
50 | ||
d5c71e20 | 51 | BinLDrivers_DocumentStorageDriver::BinLDrivers_DocumentStorageDriver() |
7fd59977 | 52 | { |
53 | } | |
54 | ||
7fd59977 | 55 | //======================================================================= |
56 | //function : Write | |
57 | //purpose : | |
58 | //======================================================================= | |
59 | ||
60 | void BinLDrivers_DocumentStorageDriver::Write | |
61 | (const Handle(CDM_Document)& theDocument, | |
6d8f9f4a | 62 | const TCollection_ExtendedString& theFileName, |
7e785937 | 63 | const Message_ProgressRange& theRange) |
7fd59977 | 64 | { |
15e8b082 M |
65 | SetIsError(Standard_False); |
66 | SetStoreStatus(PCDM_SS_OK); | |
67 | ||
4ff92abe | 68 | myFileName = theFileName; |
69 | ||
27e64adb | 70 | const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem(); |
65acdce5 | 71 | std::shared_ptr<std::ostream> aFileStream = aFileSystem->OpenOStream (theFileName, std::ios::out | std::ios::binary); |
4ff92abe | 72 | |
27e64adb | 73 | if (aFileStream.get() != NULL && aFileStream->good()) |
4ff92abe | 74 | { |
27e64adb | 75 | Write (theDocument, *aFileStream, theRange); |
4ff92abe | 76 | } |
77 | else | |
78 | { | |
79 | SetIsError (Standard_True); | |
80 | SetStoreStatus(PCDM_SS_WriteFailure); | |
81 | } | |
82 | } | |
83 | ||
84 | //======================================================================= | |
85 | //function : Write | |
86 | //purpose : | |
87 | //======================================================================= | |
88 | ||
7e785937 | 89 | void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)& theDoc, |
90 | Standard_OStream& theOStream, | |
91 | const Message_ProgressRange& theRange) | |
4ff92abe | 92 | { |
93 | myMsgDriver = theDoc->Application()->MessageDriver(); | |
7fd59977 | 94 | myMapUnsupported.Clear(); |
d5c71e20 | 95 | mySizesToWrite.Clear(); |
7fd59977 | 96 | |
d5c71e20 | 97 | Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast (theDoc); |
7fd59977 | 98 | if (aDoc.IsNull()) { |
15e8b082 M |
99 | SetIsError(Standard_True); |
100 | SetStoreStatus(PCDM_SS_Doc_IsNull); | |
7fd59977 | 101 | } |
102 | else { | |
7fd59977 | 103 | // First pass: collect empty labels, assign IDs to the types |
104 | if (myDrivers.IsNull()) | |
105 | myDrivers = AttributeDrivers (myMsgDriver); | |
106 | Handle(TDF_Data) aData = aDoc->GetData(); | |
107 | FirstPass (aData->Root()); | |
030ba648 | 108 | if(aDoc->EmptyLabelsSavingMode()) |
109 | myEmptyLabels.Clear(); // | |
7fd59977 | 110 | |
111 | // 1. Write info section (including types table) | |
4ff92abe | 112 | WriteInfoSection (aDoc, theOStream); |
113 | ||
7fd59977 | 114 | myTypesMap.Clear(); |
15e8b082 M |
115 | if (IsError()) |
116 | { | |
117 | SetStoreStatus(PCDM_SS_Info_Section_Error); | |
118 | return; | |
119 | } | |
7fd59977 | 120 | |
7fd59977 | 121 | // 2. Write the Table of Contents of Sections |
9f45d35b | 122 | const TDocStd_FormatVersion aDocVer = aDoc->StorageFormatVersion(); |
4ff92abe | 123 | BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections); |
124 | for (; anIterS.More(); anIterS.Next()) | |
716cf4d9 | 125 | anIterS.ChangeValue().WriteTOC (theOStream, aDocVer); |
7fd59977 | 126 | |
d5c71e20 | 127 | EnableQuickPartWriting (myMsgDriver, IsQuickPart (aDocVer)); |
128 | BinLDrivers_DocumentSection* aShapesSection = 0; | |
129 | Standard_Boolean aQuickPart = IsQuickPart (aDocVer); | |
130 | if (!aQuickPart) | |
131 | { | |
132 | // Shapes Section is the last one, it indicates the end of the table. | |
133 | aShapesSection = new BinLDrivers_DocumentSection (SHAPESECTION_POS, Standard_False); | |
134 | aShapesSection->WriteTOC (theOStream, aDocVer); | |
135 | } | |
136 | else | |
137 | { | |
138 | // End Section is the last one, it indicates the end of the table. | |
139 | BinLDrivers_DocumentSection anEndSection (ENDSECTION_POS, Standard_False); | |
140 | anEndSection.WriteTOC (theOStream, aDocVer); | |
141 | } | |
7fd59977 | 142 | |
143 | // 3. Write document contents | |
4ff92abe | 144 | // (Storage data to the stream) |
145 | myRelocTable.Clear(); | |
146 | myPAtt.Init(); | |
d5c71e20 | 147 | if (aQuickPart) |
148 | myPAtt.SetOStream (theOStream); // for writing shapes data into the stream directly | |
7fd59977 | 149 | |
7e785937 | 150 | Message_ProgressScope aPS(theRange, "Writing document", 3); |
7fd59977 | 151 | |
6d8f9f4a | 152 | // Write Doc structure |
d5c71e20 | 153 | WriteSubTree (aData->Root(), theOStream, aQuickPart, aPS.Next()); // Doc is written |
6d8f9f4a | 154 | if (!aPS.More()) |
155 | { | |
156 | SetIsError(Standard_True); | |
157 | SetStoreStatus(PCDM_SS_UserBreak); | |
158 | return; | |
159 | } | |
7e785937 | 160 | |
7fd59977 | 161 | // 4. Write Shapes section |
d5c71e20 | 162 | if (!aQuickPart) |
163 | { | |
164 | WriteShapeSection (*aShapesSection, theOStream, aDocVer, aPS.Next()); | |
165 | delete aShapesSection; | |
166 | } | |
167 | else | |
168 | Clear(); | |
169 | ||
6d8f9f4a | 170 | if (!aPS.More()) |
171 | { | |
d5c71e20 | 172 | SetIsError (Standard_True); |
173 | SetStoreStatus (PCDM_SS_UserBreak); | |
174 | return; | |
6d8f9f4a | 175 | } |
7e785937 | 176 | |
4ff92abe | 177 | // Write application-defined sections |
178 | for (anIterS.Init (mySections); anIterS.More(); anIterS.Next()) { | |
179 | BinLDrivers_DocumentSection& aSection = anIterS.ChangeValue(); | |
180 | const Standard_Size aSectionOffset = (Standard_Size) theOStream.tellp(); | |
181 | WriteSection (aSection.Name(), aDoc, theOStream); | |
716cf4d9 | 182 | aSection.Write (theOStream, aSectionOffset, aDocVer); |
4ff92abe | 183 | } |
184 | ||
d5c71e20 | 185 | // 5. Write sizes along the file where it is needed for quick part mode |
186 | if (aQuickPart) | |
187 | WriteSizes (theOStream); | |
188 | ||
4ff92abe | 189 | // End of processing: close structures and check the status |
190 | myPAtt.Destroy(); // free buffer | |
191 | myEmptyLabels.Clear(); | |
192 | myMapUnsupported.Clear(); | |
193 | ||
194 | if (!myRelocTable.Extent()) { | |
195 | // No objects written | |
0797d9d3 | 196 | #ifdef OCCT_DEBUG |
83ae3591 | 197 | myMsgDriver->Send ("BinLDrivers_DocumentStorageDriver, no objects written", Message_Info); |
7fd59977 | 198 | #endif |
4ff92abe | 199 | SetIsError(Standard_True); |
200 | SetStoreStatus(PCDM_SS_No_Obj); | |
7fd59977 | 201 | } |
4ff92abe | 202 | myRelocTable.Clear(); |
6d8f9f4a | 203 | if (!aPS.More()) |
204 | { | |
205 | SetIsError(Standard_True); | |
206 | SetStoreStatus(PCDM_SS_UserBreak); | |
207 | return; | |
208 | } | |
209 | aPS.Next(); | |
4ff92abe | 210 | if (!theOStream) { |
7fd59977 | 211 | // A problem with the stream |
0797d9d3 | 212 | #ifdef OCCT_DEBUG |
83ae3591 | 213 | TCollection_ExtendedString anErrorStr ("BinLDrivers_DocumentStorageDriver, Problem with the file stream, rdstate = "); |
214 | myMsgDriver->Send (anErrorStr + (Standard_Integer )theOStream.rdstate(), Message_Info); | |
7fd59977 | 215 | #endif |
15e8b082 | 216 | SetIsError(Standard_True); |
566f8441 | 217 | SetStoreStatus(PCDM_SS_WriteFailure); |
7fd59977 | 218 | } |
219 | ||
220 | } | |
221 | } | |
222 | ||
223 | //======================================================================= | |
224 | //function : UnsupportedAttrMsg | |
9293178b | 225 | //purpose : |
7fd59977 | 226 | //======================================================================= |
227 | ||
228 | void BinLDrivers_DocumentStorageDriver::UnsupportedAttrMsg | |
229 | (const Handle(Standard_Type)& theType) | |
230 | { | |
0797d9d3 | 231 | #ifdef OCCT_DEBUG |
b34d86cb | 232 | TCollection_ExtendedString aMsg |
d5c71e20 | 233 | ("BinLDrivers_DocumentStorageDriver: warning: attribute driver for type "); |
7fd59977 | 234 | #endif |
235 | if (!myMapUnsupported.Contains(theType)) { | |
236 | myMapUnsupported.Add(theType); | |
0797d9d3 | 237 | #ifdef OCCT_DEBUG |
83ae3591 | 238 | myMsgDriver->Send (aMsg + theType->Name() + " not found", Message_Info); |
7fd59977 | 239 | #endif |
240 | } | |
241 | } | |
242 | ||
243 | //======================================================================= | |
244 | //function : WriteSubTree | |
245 | //purpose : | |
246 | //======================================================================= | |
247 | ||
248 | void BinLDrivers_DocumentStorageDriver::WriteSubTree | |
7e785937 | 249 | (const TDF_Label& theLabel, |
250 | Standard_OStream& theOS, | |
d5c71e20 | 251 | const Standard_Boolean& theQuickPart, |
7e785937 | 252 | const Message_ProgressRange& theRange) |
7fd59977 | 253 | { |
254 | // Skip empty labels | |
255 | if (!myEmptyLabels.IsEmpty() && myEmptyLabels.First() == theLabel) { | |
256 | myEmptyLabels.RemoveFirst(); | |
257 | return; | |
258 | } | |
7e785937 | 259 | Message_ProgressScope aPS(theRange, "Writing sub tree", 2, true); |
7fd59977 | 260 | // Write label header: tag |
261 | Standard_Integer aTag = theLabel.Tag(); | |
ff1f0c9a | 262 | #ifdef DO_INVERSE |
7fd59977 | 263 | aTag = InverseInt (aTag); |
264 | #endif | |
265 | theOS.write ((char*)&aTag, sizeof(Standard_Integer)); | |
266 | ||
d5c71e20 | 267 | Handle(BinObjMgt_Position) aPosition; |
268 | if (theQuickPart) | |
269 | { | |
270 | aPosition = mySizesToWrite.Append (new BinObjMgt_Position (theOS)); | |
271 | aPosition->WriteSize (theOS, Standard_True); | |
272 | } | |
273 | ||
7fd59977 | 274 | // Write attributes |
275 | TDF_AttributeIterator itAtt (theLabel); | |
6d8f9f4a | 276 | for ( ; itAtt.More() && theOS && aPS.More(); itAtt.Next()) { |
1bd04b5a | 277 | const Handle(TDF_Attribute) tAtt = itAtt.Value(); |
7fd59977 | 278 | const Handle(Standard_Type)& aType = tAtt->DynamicType(); |
279 | // Get type ID and driver | |
280 | Handle(BinMDF_ADriver) aDriver; | |
d5c71e20 | 281 | const Standard_Integer aTypeId = myDrivers->GetDriver (aType, aDriver); |
7fd59977 | 282 | if (aTypeId > 0) { |
283 | // Add source to relocation table | |
284 | const Standard_Integer anId = myRelocTable.Add (tAtt); | |
285 | ||
286 | // Create and fill data item | |
287 | myPAtt.SetTypeId (aTypeId); | |
288 | myPAtt.SetId (anId); | |
289 | aDriver->Paste (tAtt, myPAtt, myRelocTable); | |
d5c71e20 | 290 | if (!myPAtt.StreamStart().IsNull()) |
291 | { | |
292 | Handle(BinObjMgt_Position) anAttrPosition = myPAtt.StreamStart(); | |
293 | anAttrPosition->StoreSize (theOS); | |
294 | mySizesToWrite.Append (anAttrPosition); | |
295 | } | |
7fd59977 | 296 | |
297 | // Write data to the stream -->!!! | |
298 | theOS << myPAtt; | |
299 | } | |
0797d9d3 | 300 | #ifdef OCCT_DEBUG |
7fd59977 | 301 | else |
302 | UnsupportedAttrMsg (aType); | |
303 | #endif | |
304 | } | |
305 | if (!theOS) { | |
306 | // Problem with the stream | |
307 | return; | |
308 | } | |
6d8f9f4a | 309 | if (!aPS.More()) |
310 | { | |
311 | SetIsError(Standard_True); | |
312 | SetStoreStatus(PCDM_SS_UserBreak); | |
313 | return; | |
314 | } | |
7fd59977 | 315 | // Write the end attributes list marker |
316 | BinLDrivers_Marker anEndAttr = BinLDrivers_ENDATTRLIST; | |
ff1f0c9a | 317 | #ifdef DO_INVERSE |
7fd59977 | 318 | anEndAttr = (BinLDrivers_Marker) InverseInt (anEndAttr); |
319 | #endif | |
320 | theOS.write ((char*)&anEndAttr, sizeof(anEndAttr)); | |
321 | ||
322 | // Process sub-labels | |
323 | TDF_ChildIterator itChld (theLabel); | |
324 | for ( ; itChld.More(); itChld.Next()) | |
325 | { | |
326 | const TDF_Label& aChildLab = itChld.Value(); | |
6d8f9f4a | 327 | if (!aPS.More()) |
328 | { | |
329 | SetIsError(Standard_True); | |
330 | SetStoreStatus(PCDM_SS_UserBreak); | |
331 | return; | |
332 | } | |
d5c71e20 | 333 | WriteSubTree (aChildLab, theOS, theQuickPart, aPS.Next()); |
7fd59977 | 334 | } |
7fd59977 | 335 | // Write the end label marker |
336 | BinLDrivers_Marker anEndLabel = BinLDrivers_ENDLABEL; | |
ff1f0c9a | 337 | #ifdef DO_INVERSE |
d5c71e20 | 338 | anEndLabel = (BinLDrivers_Marker)InverseInt (anEndLabel); |
7fd59977 | 339 | #endif |
d5c71e20 | 340 | theOS.write ((char*)&anEndLabel, sizeof (anEndLabel)); |
341 | if (theQuickPart) | |
342 | aPosition->StoreSize (theOS); | |
7fd59977 | 343 | } |
344 | ||
7fd59977 | 345 | //======================================================================= |
346 | //function : AttributeDrivers | |
347 | //purpose : | |
348 | //======================================================================= | |
349 | ||
350 | Handle(BinMDF_ADriverTable) BinLDrivers_DocumentStorageDriver::AttributeDrivers | |
83ae3591 | 351 | (const Handle(Message_Messenger)& theMessageDriver) |
7fd59977 | 352 | { |
353 | return BinLDrivers::AttributeDrivers (theMessageDriver); | |
354 | } | |
355 | ||
356 | //======================================================================= | |
357 | //function : FirstPassSubTree | |
358 | //purpose : | |
359 | //======================================================================= | |
360 | ||
361 | Standard_Boolean BinLDrivers_DocumentStorageDriver::FirstPassSubTree | |
362 | (const TDF_Label& L, | |
363 | TDF_LabelList& ListOfEmptyL) | |
364 | { | |
365 | // are there writable attributes on L ? | |
366 | Standard_Boolean hasAttr = Standard_False; | |
367 | TDF_AttributeIterator itAtt (L); | |
368 | for ( ; itAtt.More(); itAtt.Next()) { | |
369 | const Handle(Standard_Type)& aType = itAtt.Value()->DynamicType(); | |
370 | Handle(BinMDF_ADriver) aDriver; | |
371 | // do not rely on a value returned by GetDriver here, because | |
372 | // the IDs have not yet been assigned to the types | |
373 | myDrivers->GetDriver (aType, aDriver); | |
374 | if (!aDriver.IsNull()) { | |
375 | hasAttr = Standard_True; | |
376 | myTypesMap.Add (aType); | |
377 | } | |
0797d9d3 | 378 | #ifdef OCCT_DEBUG |
7fd59977 | 379 | else |
380 | UnsupportedAttrMsg (aType); | |
381 | #endif | |
382 | } | |
383 | ||
384 | // are there writable attributes on sub-labels ? | |
385 | Standard_Boolean hasChildAttr = Standard_False; | |
386 | TDF_LabelList emptyChildrenList; | |
387 | TDF_ChildIterator itChld (L); | |
388 | for ( ; itChld.More(); itChld.Next()) | |
389 | { | |
390 | if (FirstPassSubTree (itChld.Value(), emptyChildrenList)) | |
391 | emptyChildrenList.Append( itChld.Value() ); | |
392 | else | |
393 | hasChildAttr = Standard_True; | |
394 | } | |
395 | ||
396 | Standard_Boolean isEmpty = !(hasAttr || hasChildAttr); | |
397 | ||
398 | if (!isEmpty) | |
399 | ListOfEmptyL.Append( emptyChildrenList ); | |
400 | ||
401 | return isEmpty; | |
402 | } | |
403 | ||
404 | //======================================================================= | |
405 | //function : FirstPass | |
406 | //purpose : | |
407 | //======================================================================= | |
408 | ||
409 | void BinLDrivers_DocumentStorageDriver::FirstPass | |
410 | (const TDF_Label& theRoot) | |
411 | { | |
412 | myTypesMap.Clear(); | |
413 | myEmptyLabels.Clear(); | |
414 | ||
415 | if (FirstPassSubTree( theRoot, myEmptyLabels)) | |
416 | myEmptyLabels.Append( theRoot ); | |
417 | ||
418 | myDrivers->AssignIds (myTypesMap); | |
419 | } | |
420 | ||
421 | //======================================================================= | |
422 | //function : WriteInfoSection | |
b81b237f | 423 | //purpose : Write info section using FSD_BinaryFile driver |
7fd59977 | 424 | //======================================================================= |
425 | ||
426 | #define START_TYPES "START_TYPES" | |
427 | #define END_TYPES "END_TYPES" | |
428 | ||
4ff92abe | 429 | void BinLDrivers_DocumentStorageDriver::WriteInfoSection |
430 | (const Handle(CDM_Document)& theDoc, | |
431 | Standard_OStream& theOStream) | |
7fd59977 | 432 | { |
4ff92abe | 433 | // Magic number |
434 | theOStream.write (FSD_BinaryFile::MagicNumber(), strlen(FSD_BinaryFile::MagicNumber())); | |
435 | ||
436 | FSD_FileHeader aHeader; | |
437 | ||
438 | { | |
439 | aHeader.testindian = -1; | |
440 | aHeader.binfo = -1; | |
441 | aHeader.einfo = -1; | |
442 | aHeader.bcomment = -1; | |
443 | aHeader.ecomment = -1; | |
444 | aHeader.btype = -1; | |
445 | aHeader.etype = -1; | |
446 | aHeader.broot = -1; | |
447 | aHeader.eroot = -1; | |
448 | aHeader.bref = -1; | |
449 | aHeader.eref = -1; | |
450 | aHeader.bdata = -1; | |
451 | aHeader.edata = -1; | |
452 | } | |
453 | ||
454 | // aHeader.testindian | |
455 | { | |
456 | union { | |
457 | char ti2[4]; | |
458 | Standard_Integer aResult; | |
459 | } aWrapUnion; | |
460 | ||
461 | aWrapUnion.ti2[0] = 1; | |
462 | aWrapUnion.ti2[1] = 2; | |
463 | aWrapUnion.ti2[2] = 3; | |
464 | aWrapUnion.ti2[3] = 4; | |
465 | ||
466 | aHeader.testindian = aWrapUnion.aResult; | |
7fd59977 | 467 | } |
468 | ||
4ff92abe | 469 | // info section |
470 | aHeader.binfo = (Standard_Integer)theOStream.tellp(); | |
471 | ||
472 | // header section | |
473 | aHeader.einfo = aHeader.binfo + FSD_BinaryFile::WriteHeader (theOStream, aHeader, Standard_True); | |
474 | ||
475 | // add format | |
476 | Handle(Storage_Data) theData = new Storage_Data; | |
477 | PCDM_ReadWriter::WriteFileFormat (theData, theDoc); | |
478 | PCDM_ReadWriter::Writer()->WriteReferenceCounter (theData, theDoc); | |
479 | PCDM_ReadWriter::Writer()->WriteReferences (theData, theDoc, myFileName); | |
480 | PCDM_ReadWriter::Writer()->WriteExtensions (theData, theDoc); | |
481 | PCDM_ReadWriter::Writer()->WriteVersion (theData, theDoc); | |
482 | ||
483 | // add the types table | |
484 | theData->AddToUserInfo(START_TYPES); | |
485 | for (Standard_Integer i = 1; i <= myTypesMap.Extent(); i++) | |
7fd59977 | 486 | { |
4ff92abe | 487 | Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(i); |
488 | if (!aDriver.IsNull()) | |
489 | { | |
490 | const TCollection_AsciiString& aTypeName = aDriver->TypeName(); | |
491 | theData->AddToUserInfo (aTypeName); | |
7fd59977 | 492 | } |
7fd59977 | 493 | } |
4ff92abe | 494 | theData->AddToUserInfo(END_TYPES); |
495 | ||
496 | Standard_Integer aObjNb = 1; | |
497 | Standard_Integer aShemaVer = 1; | |
498 | ||
fe21f796 BB |
499 | // Store the name and version of the application that has created the |
500 | // document. | |
501 | theData->SetApplicationVersion(theDoc->Application()->Version()); | |
502 | theData->SetApplicationName(theDoc->Application()->Name()); | |
503 | ||
716cf4d9 | 504 | Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(theDoc); |
505 | const Standard_Integer aDocVer = aDoc->StorageFormatVersion(); | |
4ff92abe | 506 | aHeader.einfo += FSD_BinaryFile::WriteInfo (theOStream, |
507 | aObjNb, | |
716cf4d9 | 508 | aDocVer, |
4ff92abe | 509 | Storage_Schema::ICreationDate(), |
6fe96f84 | 510 | "", // schema name |
4ff92abe | 511 | aShemaVer, |
512 | theData->ApplicationName(), | |
513 | theData->ApplicationVersion(), | |
514 | theData->DataType(), | |
515 | theData->UserInfo(), | |
516 | Standard_True); // only count the size of the section | |
517 | ||
518 | // calculate comment section | |
519 | TColStd_SequenceOfExtendedString aComments; | |
520 | theDoc->Comments(aComments); | |
521 | for (Standard_Integer i = 1; i <= aComments.Length(); i++) | |
522 | { | |
523 | theData->AddToComments (aComments(i)); | |
7fd59977 | 524 | } |
4ff92abe | 525 | |
526 | aHeader.bcomment = aHeader.einfo; | |
527 | aHeader.ecomment = aHeader.bcomment + FSD_BinaryFile::WriteComment(theOStream, theData->Comments(), Standard_True); | |
528 | ||
529 | aHeader.edata = aHeader.ecomment; | |
530 | ||
531 | // write header information | |
532 | FSD_BinaryFile::WriteHeader (theOStream, aHeader); | |
533 | ||
534 | // write info section | |
535 | FSD_BinaryFile::WriteInfo (theOStream, | |
536 | aObjNb, | |
716cf4d9 | 537 | aDocVer, |
4ff92abe | 538 | Storage_Schema::ICreationDate(), |
6fe96f84 | 539 | "", // schema name |
4ff92abe | 540 | aShemaVer, |
541 | theData->ApplicationName(), | |
542 | theData->ApplicationVersion(), | |
543 | theData->DataType(), | |
544 | theData->UserInfo()); | |
545 | ||
546 | // write the comments | |
547 | FSD_BinaryFile::WriteComment(theOStream, theData->Comments()); | |
548 | ||
7fd59977 | 549 | } |
550 | ||
7fd59977 | 551 | //======================================================================= |
552 | //function : AddSection | |
9293178b | 553 | //purpose : |
7fd59977 | 554 | //======================================================================= |
555 | ||
556 | void BinLDrivers_DocumentStorageDriver::AddSection | |
557 | (const TCollection_AsciiString& theName, | |
558 | const Standard_Boolean isPostRead) | |
559 | { | |
560 | mySections.Append (BinLDrivers_DocumentSection (theName, isPostRead)); | |
561 | } | |
562 | ||
563 | //======================================================================= | |
564 | //function : WriteSection | |
9293178b | 565 | //purpose : |
7fd59977 | 566 | //======================================================================= |
567 | ||
568 | void BinLDrivers_DocumentStorageDriver::WriteSection | |
569 | (const TCollection_AsciiString& /*theName*/, | |
857ffd5e | 570 | const Handle(CDM_Document)& /*theDocument*/, |
7fd59977 | 571 | Standard_OStream& /*theOS*/) |
572 | { | |
573 | // empty; should be redefined in subclasses | |
574 | } | |
575 | ||
576 | //======================================================================= | |
577 | //function : WriteShapeSection | |
578 | //purpose : defines WriteShapeSection | |
579 | //======================================================================= | |
580 | void BinLDrivers_DocumentStorageDriver::WriteShapeSection | |
581 | (BinLDrivers_DocumentSection& theSection, | |
6d8f9f4a | 582 | Standard_OStream& theOS, |
9f45d35b | 583 | const TDocStd_FormatVersion theDocVer, |
7e785937 | 584 | const Message_ProgressRange& /*theRange*/) |
7fd59977 | 585 | { |
586 | const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp(); | |
716cf4d9 | 587 | theSection.Write (theOS, aShapesSectionOffset, theDocVer); |
7fd59977 | 588 | } |
d5c71e20 | 589 | |
590 | //======================================================================= | |
591 | //function : IsQuickPart | |
592 | //purpose : Return true if document should be stored in quick mode for partial reading | |
593 | //======================================================================= | |
594 | Standard_Boolean BinLDrivers_DocumentStorageDriver::IsQuickPart (const Standard_Integer theVersion) const | |
595 | { | |
596 | return theVersion >= TDocStd_FormatVersion_VERSION_12; | |
597 | } | |
598 | ||
599 | //======================================================================= | |
600 | //function : Clear | |
601 | //purpose : | |
602 | //======================================================================= | |
603 | void BinLDrivers_DocumentStorageDriver::Clear() | |
604 | { | |
605 | // empty; should be redefined in subclasses | |
606 | } | |
607 | ||
608 | ||
609 | //======================================================================= | |
610 | //function : WriteSizes | |
611 | //purpose : | |
612 | //======================================================================= | |
613 | void BinLDrivers_DocumentStorageDriver::WriteSizes (Standard_OStream& theOS) | |
614 | { | |
615 | NCollection_List<Handle(BinObjMgt_Position)>::Iterator anIter (mySizesToWrite); | |
616 | for (; anIter.More() && theOS; anIter.Next()) | |
617 | anIter.Value()->WriteSize (theOS); | |
618 | mySizesToWrite.Clear(); | |
619 | } |