0030169: Application Framework - Document format version management improvement
[occt.git] / src / BinLDrivers / BinLDrivers_DocumentSection.cxx
1 // Created on: 2008-06-20
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <BinLDrivers_DocumentSection.hxx>
17 #include <FSD_FileHeader.hxx>
18 #include <BinMDataStd.hxx>
19
20 //=======================================================================
21 //function : BinLDrivers_DocumentSection
22 //purpose  : Empty constructor
23 //=======================================================================
24
25 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection ()
26   : myIsPostRead (Standard_False)
27 {
28   myValue[0] = 0;
29   myValue[1] = 0;
30 }
31
32 //=======================================================================
33 //function : BinLDrivers_DocumentSection
34 //purpose  : Constructor
35 //=======================================================================
36
37 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection
38                         (const TCollection_AsciiString& theName,
39                          const Standard_Boolean         isPostRead)
40   : myName       (theName),
41     myIsPostRead (isPostRead)
42 {
43   myValue[0] = 0;
44   myValue[1] = 0;
45 }
46
47 //=======================================================================
48 //function : Name
49 //purpose  : 
50 //=======================================================================
51
52 const TCollection_AsciiString&  BinLDrivers_DocumentSection::Name () const
53 {
54   return myName;
55 }
56
57 //=======================================================================
58 //function : Offset
59 //purpose  : 
60 //=======================================================================
61
62 uint64_t BinLDrivers_DocumentSection::Offset () const
63 {
64   return myValue[0];
65 }
66
67 //=======================================================================
68 //function : SetOffset
69 //purpose  : 
70 //=======================================================================
71
72 void BinLDrivers_DocumentSection::SetOffset (const uint64_t theOffset)
73 {
74   myValue[0] = theOffset;
75 }
76
77 //=======================================================================
78 //function : IsPostRead
79 //purpose  : 
80 //=======================================================================
81
82 Standard_Boolean BinLDrivers_DocumentSection::IsPostRead () const
83 {
84   return myIsPostRead;
85 }
86
87 //=======================================================================
88 //function : Length
89 //purpose  : 
90 //=======================================================================
91
92 uint64_t BinLDrivers_DocumentSection::Length () const
93 {
94   return myValue[1];
95 }
96
97 //=======================================================================
98 //function : SetLength
99 //purpose  : 
100 //=======================================================================
101
102 void BinLDrivers_DocumentSection::SetLength (const uint64_t theLength)
103 {
104   myValue[1] = theLength;
105 }
106
107 //=======================================================================
108 //function : WriteTOC
109 //purpose  : 
110 //=======================================================================
111
112 void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream)
113 {
114   char aBuf[512];
115
116   if (myName.IsEmpty() == Standard_False) {
117     Standard_Integer * aBufSz = reinterpret_cast<Standard_Integer *> (&aBuf[0]);
118     const Standard_Size aBufSzSize = sizeof(aBuf) / sizeof(Standard_Integer);
119     aBufSz[aBufSzSize-1] = 0;
120
121     strncpy (&aBuf[sizeof(Standard_Integer)],
122              myName.ToCString(),
123              sizeof(aBuf)-sizeof(Standard_Integer)-1);
124
125     // Calculate the length of the buffer: Standard_Size + string.
126     // If the length is not multiple of Standard_Size, it is properly increased
127     const Standard_Size aLen = strlen (&aBuf[sizeof(Standard_Integer)]);
128     Standard_Size aBufSize =
129       (aLen/sizeof(Standard_Integer))*sizeof(Standard_Integer);
130     if (aBufSize < aLen)
131       aBufSize += sizeof(Standard_Integer);
132
133     // Write the buffer: size + string
134 #if DO_INVERSE
135     aBufSz[0] = InverseInt ((Standard_Integer)aBufSize);
136 #else
137     aBufSz[0] = (Standard_Integer)aBufSize;
138 #endif
139     theStream.write (&aBuf[0], aBufSize + sizeof(Standard_Integer));
140
141     // Store the address of Offset word in the file
142     myValue[0] = (uint64_t) theStream.tellp();
143     myValue[1] = 0;
144
145     // Write the placeholders of Offset and Length of the section that should
146     // be written afterwards
147     aBufSz[0] = 0;
148     aBufSz[1] = 0;
149     aBufSz[2] = 0;
150     theStream.write (&aBuf[0], 3*sizeof(uint64_t));
151   }
152 }
153
154 //=======================================================================
155 //function : Write
156 //purpose  : 
157 //=======================================================================
158
159 void BinLDrivers_DocumentSection::Write (Standard_OStream&   theStream,
160                                          const uint64_t theOffset)
161 {
162   const uint64_t aSectionEnd = (uint64_t) theStream.tellp();
163   theStream.seekp((std::streamsize)myValue[0]);
164   myValue[0] = theOffset;
165   myValue[1] = aSectionEnd - theOffset;
166   uint64_t aVal[3] = {
167     myValue[0],
168     myValue[1],
169     uint64_t(myIsPostRead ? 1 : 0)
170   };
171 #if DO_INVERSE
172   aVal[0] = InverseUint64(aVal[0]);
173   aVal[1] = InverseUint64(aVal[1]);
174   aVal[2] = InverseUint64(aVal[2]);
175 #endif
176
177   theStream.write((char *)&aVal[0], 3*sizeof(uint64_t));
178   theStream.seekp((std::streamsize)aSectionEnd);
179 }
180
181 //=======================================================================
182 //function : ReadTOC
183 //purpose  : 
184 //=======================================================================
185
186 void BinLDrivers_DocumentSection::ReadTOC
187                                 (BinLDrivers_DocumentSection& theSection,
188                                  Standard_IStream&            theStream,
189                                  const Standard_Integer theDocFormatVersion)
190 {
191   char aBuf[512];
192   Standard_Integer aNameBufferSize;
193   theStream.read ((char *)&aNameBufferSize, sizeof(Standard_Integer));
194 #if DO_INVERSE
195   aNameBufferSize = InverseSize(aNameBufferSize);
196 #endif
197   if (aNameBufferSize > 0) {
198     theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize);
199     theSection.myName = (Standard_CString)&aBuf[0];
200
201     uint64_t aValue[3];
202     if (theDocFormatVersion <= 9)
203     {
204       // Old documents stored file position as 4-bytes values.
205       Standard_Integer aValInt[3];
206       theStream.read ((char *)&aValInt[0], 3*sizeof(Standard_Integer));
207 #if DO_INVERSE
208       aValue[0] = InverseInt (aValInt[0]);
209       aValue[1] = InverseInt (aValInt[1]);
210       aValue[2] = InverseInt (aValInt[2]);
211 #else
212       aValue[0] = aValInt[0];
213       aValue[1] = aValInt[1];
214       aValue[2] = aValInt[2];
215 #endif
216     }
217     else
218     {
219       theStream.read ((char *)&aValue[0], 3*sizeof(uint64_t));
220 #if DO_INVERSE
221       aValue[0] = InverseUint64 (aValue[0]);
222       aValue[1] = InverseUint64 (aValue[1]);
223       aValue[2] = InverseUint64 (aValue[2]);
224 #endif
225     }
226
227     theSection.myValue[0] = aValue[0];
228     theSection.myValue[1] = aValue[1];
229     theSection.myIsPostRead = (aValue[2] != 0);
230   }
231 }