1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkXMLOffsetsManager.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   OffsetsManager
17  * @brief   Helper class due to PIMPL excess
18  *
19  * This class is deisgned to work within vtkXMLWriter. It store a position
20  * in a file (unsigned long) and associate a offset in the file. This is
21  * useful when writing TimeStep XML file when you want to forward the
22  * same offset from the AppendData section on every entry in let say
23  * \<Points\> definition
24  * Example:
25  * \verbatim
26  * <Points>
27  *   <DataArray type="Float32" TimeStep="0" format="appended" offset="268" />
28  *   <DataArray type="Float32" TimeStep="1" format="appended" offset="268" />
29  *   ...
30  * </Points>
31  * \endverbatim
32  * Therefore data is only stored once in the XML file. At read time the
33  * offset value is stored to determine whenever we need to read data
34  * (ie when offset different from previously stored offset)
35  *
36  * @sa
37  * vtkXMLWriter
38  * @warning
39  * Do not include this file in a header file, it will break PIMPL convention
40 */
41 
42 #ifndef vtkXMLOffsetsManager_DoNotInclude
43 #error "do not include unless you know what you are doing"
44 #endif
45 
46 #ifndef vtkXMLOffsetsManager_h
47 #define vtkXMLOffsetsManager_h
48 
49 #include "vtkSystemIncludes.h"
50 #include <vector>
51 #include <cassert>
52 
53 //----------------------------------------------------------------------------
54 class OffsetsManager
55 {
56 public:
57   // Construct with default (vtkMTimeType)-1  MTime
OffsetsManager()58   OffsetsManager()
59   {
60       this->LastMTime = static_cast<vtkMTimeType>(-1); //almost invalid state
61   }
Allocate(int numTimeStep)62   void Allocate(int numTimeStep)
63   {
64     assert( numTimeStep > 0);
65     this->Positions.resize(numTimeStep);
66     this->RangeMinPositions.resize(numTimeStep);
67     this->RangeMaxPositions.resize(numTimeStep);
68     this->OffsetValues.resize(numTimeStep);
69   }
GetPosition(unsigned int t)70   vtkTypeInt64 &GetPosition(unsigned int t)
71   {
72     assert( t < this->Positions.size());
73     return this->Positions[t];
74   }
GetRangeMinPosition(unsigned int t)75   vtkTypeInt64 &GetRangeMinPosition(unsigned int t)
76   {
77     assert( t < this->RangeMinPositions.size());
78     return this->RangeMinPositions[t];
79   }
GetRangeMaxPosition(unsigned int t)80   vtkTypeInt64 &GetRangeMaxPosition(unsigned int t)
81   {
82     assert( t < this->RangeMaxPositions.size());
83     return this->RangeMaxPositions[t];
84   }
GetOffsetValue(unsigned int t)85   vtkTypeInt64 &GetOffsetValue(unsigned int t)
86   {
87     assert( t < this->OffsetValues.size());
88     return this->OffsetValues[t];
89   }
GetLastMTime()90   vtkMTimeType &GetLastMTime()
91   {
92     return this->LastMTime;
93   }
94 private:
95   vtkMTimeType LastMTime; // Previously written dataarray mtime
96   // at some point these vectors could become a vector of map <string,ul>
97   // where the string is the name of the offset, but that would be pretty fat
98   // and slow, but if another couple offsets are added then we should
99   // consider doing it
100   // Position in the stream to write the offset
101   std::vector<vtkTypeInt64> Positions;
102   std::vector<vtkTypeInt64> RangeMinPositions; // Where is this
103   std::vector<vtkTypeInt64> RangeMaxPositions; // Whee is this
104 
105   std::vector<vtkTypeInt64> OffsetValues;    // Value of offset
106 };
107 
108 //----------------------------------------------------------------------------
109 class OffsetsManagerGroup
110 {
111 public:
112   // This is kind of a hack since we need to consider both the case of Points
113   // with only one array over time and PointData with possibly multiple array
114   // over time therefore we need to use a OffsetsManagerGroup for
115   // representing offset from Points but OffsetsManagerArray for
116   // PointData. In both case the toplevel structure is a container of
117   // Pieces...
GetPiece(unsigned int index)118   OffsetsManager &GetPiece(unsigned int index)
119   {
120     assert( index < this->Internals.size());
121     OffsetsManager &e = this->Internals[index];
122     return e;
123   }
124   // GetElement should be used when manipulating a OffsetsManagerArray
GetElement(unsigned int index)125   OffsetsManager &GetElement(unsigned int index)
126   {
127     // commenting the following out, this is an heisenbug which only appears
128     // on gcc when exporting GLIBCPP_NEW=1. If you try to print the value or
129     // run through gdb it desepears //assert( index <
130     // this->Internals.size());
131     OffsetsManager &e = this->Internals[index];
132     return e;
133   }
GetNumberOfElements()134   unsigned int GetNumberOfElements()
135   {
136     return static_cast<unsigned int>(this->Internals.size());
137   }
Allocate(int numElements)138   void Allocate(int numElements)
139   {
140     assert(numElements >= 0); //allow 0 for empty FieldData
141     this->Internals.resize(numElements);
142   }
Allocate(int numElements,int numTimeSteps)143   void Allocate(int numElements, int numTimeSteps)
144   {
145     assert(numElements > 0);
146     assert(numTimeSteps > 0);
147     this->Internals.resize(numElements);
148     for(int i=0; i<numElements; i++)
149     {
150       this->Internals[i].Allocate(numTimeSteps);
151     }
152   }
153 private:
154   std::vector<OffsetsManager> Internals;
155 };
156 
157 //----------------------------------------------------------------------------
158 class OffsetsManagerArray
159 {
160 public:
GetPiece(unsigned int index)161   OffsetsManagerGroup &GetPiece(unsigned int index)
162   {
163     assert( index < this->Internals.size());
164     return this->Internals[index];
165   }
Allocate(int numPieces)166   void Allocate(int numPieces)
167   {
168     assert(numPieces > 0);
169     // Force re-initialization of values.
170     this->Internals.resize(0);
171     this->Internals.resize(numPieces);
172   }
Allocate(int numPieces,int numElements,int numTimeSteps)173   void Allocate(int numPieces, int numElements, int numTimeSteps)
174   {
175     assert(numPieces > 0);
176     assert(numElements > 0);
177     assert(numTimeSteps > 0);
178 
179     // Force re-initialization of values.
180     this->Internals.resize(0);
181     this->Internals.resize(numPieces);
182     for(int i=0; i<numPieces; i++)
183     {
184       this->Internals[i].Allocate(numElements, numTimeSteps);
185     }
186   }
187 private:
188   std::vector<OffsetsManagerGroup> Internals;
189 };
190 
191 #endif
192 // VTK-HeaderTest-Exclude: vtkXMLOffsetsManager.h
193