1 // Created on: 2008-06-20
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <BinLDrivers_DocumentSection.hxx>
17 #include <TDocStd_FormatVersion.hxx>
18 #include <FSD_FileHeader.hxx>
19 #include <BinMDataStd.hxx>
21 //=======================================================================
22 //function : BinLDrivers_DocumentSection
23 //purpose : Empty constructor
24 //=======================================================================
26 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection ()
27 : myIsPostRead (Standard_False)
33 //=======================================================================
34 //function : BinLDrivers_DocumentSection
35 //purpose : Constructor
36 //=======================================================================
38 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection
39 (const TCollection_AsciiString& theName,
40 const Standard_Boolean isPostRead)
42 myIsPostRead (isPostRead)
48 //=======================================================================
51 //=======================================================================
53 const TCollection_AsciiString& BinLDrivers_DocumentSection::Name () const
58 //=======================================================================
61 //=======================================================================
63 uint64_t BinLDrivers_DocumentSection::Offset () const
68 //=======================================================================
69 //function : SetOffset
71 //=======================================================================
73 void BinLDrivers_DocumentSection::SetOffset (const uint64_t theOffset)
75 myValue[0] = theOffset;
78 //=======================================================================
79 //function : IsPostRead
81 //=======================================================================
83 Standard_Boolean BinLDrivers_DocumentSection::IsPostRead () const
88 //=======================================================================
91 //=======================================================================
93 uint64_t BinLDrivers_DocumentSection::Length () const
98 //=======================================================================
99 //function : SetLength
101 //=======================================================================
103 void BinLDrivers_DocumentSection::SetLength (const uint64_t theLength)
105 myValue[1] = theLength;
108 //=======================================================================
109 //function : WriteTOC
111 //=======================================================================
113 void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream,
114 const TDocStd_FormatVersion theDocFormatVersion)
118 if (myName.IsEmpty() == Standard_False) {
119 Standard_Integer * aBufSz = reinterpret_cast<Standard_Integer *> (&aBuf[0]);
120 const Standard_Size aBufSzSize = sizeof(aBuf) / sizeof(Standard_Integer);
121 aBufSz[aBufSzSize-1] = 0;
123 strncpy (&aBuf[sizeof(Standard_Integer)],
125 sizeof(aBuf)-sizeof(Standard_Integer)-1);
127 // Calculate the length of the buffer: Standard_Size + string.
128 // If the length is not multiple of Standard_Size, it is properly increased
129 const Standard_Size aLen = strlen (&aBuf[sizeof(Standard_Integer)]);
130 Standard_Size aBufSize =
131 (aLen/sizeof(Standard_Integer))*sizeof(Standard_Integer);
133 aBufSize += sizeof(Standard_Integer);
135 // Write the buffer: size + string
137 aBufSz[0] = InverseInt ((Standard_Integer)aBufSize);
139 aBufSz[0] = (Standard_Integer)aBufSize;
141 theStream.write (&aBuf[0], aBufSize + sizeof(Standard_Integer));
143 // Store the address of Offset word in the file
144 myValue[0] = (uint64_t) theStream.tellp();
147 // Write the placeholders of Offset and Length of the section that should
148 // be written afterwards
152 if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
154 theStream.write(&aBuf[0], 3*sizeof(Standard_Integer));
158 theStream.write(&aBuf[0], 3*sizeof(uint64_t));
163 //=======================================================================
166 //=======================================================================
168 void BinLDrivers_DocumentSection::Write (Standard_OStream& theStream,
169 const uint64_t theOffset,
170 const TDocStd_FormatVersion theDocFormatVersion)
172 const uint64_t aSectionEnd = (uint64_t) theStream.tellp();
173 theStream.seekp((std::streamsize)myValue[0]);
174 myValue[0] = theOffset;
175 myValue[1] = aSectionEnd - theOffset;
176 if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
178 // Check the limits for a 4-bytes integer.
179 if (myValue[0] > INT_MAX || myValue[1] > INT_MAX)
180 throw Standard_OutOfRange("BinLDrivers_DocumentSection::Write : file size is too big, needs int64.");
182 // Old documents stored file position as 4-bytes values.
183 int32_t aValInt[3] = {
186 int32_t(myIsPostRead ? 1 : 0)
189 aValInt[0] = InverseInt(aValInt[0]);
190 aValInt[1] = InverseInt(aValInt[1]);
191 aValInt[2] = InverseInt(aValInt[2]);
193 theStream.write((char *)&aValInt[0], 3*sizeof(int32_t));
200 uint64_t(myIsPostRead ? 1 : 0)
203 aVal[0] = InverseUint64(aVal[0]);
204 aVal[1] = InverseUint64(aVal[1]);
205 aVal[2] = InverseUint64(aVal[2]);
207 theStream.write((char *)&aVal[0], 3*sizeof(uint64_t));
210 theStream.seekp((std::streamsize)aSectionEnd);
213 //=======================================================================
216 //=======================================================================
218 void BinLDrivers_DocumentSection::ReadTOC
219 (BinLDrivers_DocumentSection& theSection,
220 Standard_IStream& theStream,
221 const TDocStd_FormatVersion theDocFormatVersion)
224 Standard_Integer aNameBufferSize;
225 theStream.read ((char *)&aNameBufferSize, sizeof(Standard_Integer));
227 aNameBufferSize = InverseSize(aNameBufferSize);
229 if (aNameBufferSize > 0) {
230 theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize);
231 theSection.myName = (Standard_CString)&aBuf[0];
234 if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
236 // Old documents stored file position as 4-bytes values.
238 theStream.read ((char *)&aValInt[0], 3*sizeof(int32_t));
240 aValue[0] = InverseInt (aValInt[0]);
241 aValue[1] = InverseInt (aValInt[1]);
242 aValue[2] = InverseInt (aValInt[2]);
244 aValue[0] = aValInt[0];
245 aValue[1] = aValInt[1];
246 aValue[2] = aValInt[2];
251 theStream.read ((char *)&aValue[0], 3*sizeof(uint64_t));
253 aValue[0] = InverseUint64 (aValue[0]);
254 aValue[1] = InverseUint64 (aValue[1]);
255 aValue[2] = InverseUint64 (aValue[2]);
259 theSection.myValue[0] = aValue[0];
260 theSection.myValue[1] = aValue[1];
261 theSection.myIsPostRead = (aValue[2] != 0);