1fab06a2a9df9ebb58561e3edc2d12ad977f129c
[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
19 //=======================================================================
20 //function : BinLDrivers_DocumentSection
21 //purpose  : Empty constructor
22 //=======================================================================
23
24 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection ()
25   : myIsPostRead (Standard_False)
26 {
27   myValue[0] = 0;
28   myValue[1] = 0;
29 }
30
31 //=======================================================================
32 //function : BinLDrivers_DocumentSection
33 //purpose  : Constructor
34 //=======================================================================
35
36 BinLDrivers_DocumentSection::BinLDrivers_DocumentSection
37                         (const TCollection_AsciiString& theName,
38                          const Standard_Boolean         isPostRead)
39   : myName       (theName),
40     myIsPostRead (isPostRead)
41 {
42   myValue[0] = 0;
43   myValue[1] = 0;
44 }
45
46 //=======================================================================
47 //function : Name
48 //purpose  : 
49 //=======================================================================
50
51 const TCollection_AsciiString&  BinLDrivers_DocumentSection::Name () const
52 {
53   return myName;
54 }
55
56 //=======================================================================
57 //function : Offset
58 //purpose  : 
59 //=======================================================================
60
61 Standard_Size BinLDrivers_DocumentSection::Offset () const
62 {
63   return myValue[0];
64 }
65
66 //=======================================================================
67 //function : SetOffset
68 //purpose  : 
69 //=======================================================================
70
71 void BinLDrivers_DocumentSection::SetOffset (const Standard_Size theOffset)
72 {
73   myValue[0] = theOffset;
74 }
75
76 //=======================================================================
77 //function : IsPostRead
78 //purpose  : 
79 //=======================================================================
80
81 Standard_Boolean BinLDrivers_DocumentSection::IsPostRead () const
82 {
83   return myIsPostRead;
84 }
85
86 //=======================================================================
87 //function : Length
88 //purpose  : 
89 //=======================================================================
90
91 Standard_Size BinLDrivers_DocumentSection::Length () const
92 {
93   return myValue[1];
94 }
95
96 //=======================================================================
97 //function : SetLength
98 //purpose  : 
99 //=======================================================================
100
101 void BinLDrivers_DocumentSection::SetLength (const Standard_Size theLength)
102 {
103   myValue[1] = theLength;
104 }
105
106 //=======================================================================
107 //function : WriteTOC
108 //purpose  : 
109 //=======================================================================
110
111 void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream)
112 {
113   char aBuf[512];
114
115   if (myName.IsEmpty() == Standard_False) {
116     Standard_Integer * aBufSz = reinterpret_cast<Standard_Integer *> (&aBuf[0]);
117     const Standard_Size aBufSzSize = sizeof(aBuf) / sizeof(Standard_Integer);
118     aBufSz[aBufSzSize-1] = 0;
119
120     strncpy (&aBuf[sizeof(Standard_Integer)],
121              myName.ToCString(),
122              sizeof(aBuf)-sizeof(Standard_Integer)-1);
123
124     // Calculate the length of the buffer: Standard_Size + string.
125     // If the length is not multiple of Standard_Size, it is properly increased
126     const Standard_Size aLen = strlen (&aBuf[sizeof(Standard_Integer)]);
127     Standard_Size aBufSize =
128       (aLen/sizeof(Standard_Integer))*sizeof(Standard_Integer);
129     if (aBufSize < aLen)
130       aBufSize += sizeof(Standard_Integer);
131
132     // Write the buffer: size + string
133 #if DO_INVERSE
134     aBufSz[0] = InverseSize ((Standard_Integer)aBufSize);
135 #else
136     aBufSz[0] = (Standard_Integer)aBufSize;
137 #endif
138     theStream.write (&aBuf[0], aBufSize + sizeof(Standard_Integer));
139
140     // Store the address of Offset word in the file
141     myValue[0] = (Standard_Size) theStream.tellp();
142     myValue[1] = 0;
143
144     // Write the placeholders of Offset and Length of the section that should
145     // be written afterwards
146     aBufSz[0] = 0;
147     aBufSz[1] = 0;
148     aBufSz[2] = 0;
149     theStream.write (&aBuf[0], 3*sizeof(Standard_Integer));
150   }
151 }
152
153 //=======================================================================
154 //function : Write
155 //purpose  : 
156 //=======================================================================
157
158 void BinLDrivers_DocumentSection::Write (Standard_OStream&   theStream,
159                                          const Standard_Size theOffset)
160 {
161   const Standard_Size aSectionEnd = (Standard_Size) theStream.tellp();
162   theStream.seekp(myValue[0]);
163   myValue[0] = theOffset;
164   myValue[1] = aSectionEnd - theOffset;
165   Standard_Integer aVal[3] = {
166     Standard_Integer(myValue[0]),
167     Standard_Integer(myValue[1]),
168     Standard_Integer(myIsPostRead ? 1 : 0)
169   };
170 #if DO_INVERSE
171   aVal[0] = InverseSize(aVal[0]);
172   aVal[1] = InverseSize(aVal[1]);
173   aVal[2] = InverseSize(aVal[2]);
174 #endif
175
176   theStream.write((char *)&aVal[0], 3*sizeof(Standard_Integer));
177   theStream.seekp(aSectionEnd);
178 }
179
180 //=======================================================================
181 //function : ReadTOC
182 //purpose  : 
183 //=======================================================================
184
185 void BinLDrivers_DocumentSection::ReadTOC
186                                 (BinLDrivers_DocumentSection& theSection,
187                                  Standard_IStream&            theStream)
188 {
189   char aBuf[512];
190   Standard_Integer aNameBufferSize;
191   theStream.read ((char *)&aNameBufferSize, sizeof(Standard_Integer));
192 #if DO_INVERSE
193   aNameBufferSize = InverseSize(aNameBufferSize);
194 #endif
195   if (aNameBufferSize > 0) {
196     theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize);
197     theSection.myName = (Standard_CString)&aBuf[0];
198     Standard_Integer aValue[3];
199     theStream.read ((char *)&aValue[0], 3*sizeof(Standard_Integer));
200 #if DO_INVERSE
201     aValue[0] = InverseSize (aValue[0]);
202     aValue[1] = InverseSize (aValue[1]);
203     aValue[2] = InverseSize (aValue[2]);
204 #endif
205     theSection.myValue[0] = (Standard_Size)aValue[0];
206     theSection.myValue[1] = (Standard_Size)aValue[1];
207     theSection.myIsPostRead = aValue[2] != 0;
208   }
209 }