1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkXMLPDataObjectReader.cxx
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 #include "vtkXMLPDataObjectReader.h"
16 
17 #include "vtkCallbackCommand.h"
18 #include "vtkXMLDataElement.h"
19 
20 #include <cassert>
21 #include <sstream>
22 
23 //------------------------------------------------------------------------------
vtkXMLPDataObjectReader()24 vtkXMLPDataObjectReader::vtkXMLPDataObjectReader()
25 {
26   this->NumberOfPieces = 0;
27 
28   this->PieceElements = nullptr;
29   this->CanReadPieceFlag = nullptr;
30 
31   this->PathName = nullptr;
32 
33   // Setup a callback for the internal serial readers to report
34   // progress.
35   this->PieceProgressObserver = vtkCallbackCommand::New();
36   this->PieceProgressObserver->SetCallback(&vtkXMLPDataObjectReader::PieceProgressCallbackFunction);
37   this->PieceProgressObserver->SetClientData(this);
38 }
39 
40 //------------------------------------------------------------------------------
~vtkXMLPDataObjectReader()41 vtkXMLPDataObjectReader::~vtkXMLPDataObjectReader()
42 {
43   if (this->NumberOfPieces)
44   {
45     this->DestroyPieces();
46   }
47   delete[] this->PathName;
48   this->PieceProgressObserver->Delete();
49 }
50 
51 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)52 void vtkXMLPDataObjectReader::PrintSelf(ostream& os, vtkIndent indent)
53 {
54   this->Superclass::PrintSelf(os, indent);
55   os << indent << "NumberOfPieces: " << this->NumberOfPieces << "\n";
56 }
57 
58 //------------------------------------------------------------------------------
SetupOutputData()59 void vtkXMLPDataObjectReader::SetupOutputData()
60 {
61   this->Superclass::SetupOutputData();
62 }
63 
64 //------------------------------------------------------------------------------
CreatePieceFileName(const char * fileName)65 char* vtkXMLPDataObjectReader::CreatePieceFileName(const char* fileName)
66 {
67   assert(fileName);
68 
69   std::ostringstream fileNameStream;
70 
71   // only prepend the path if the given file name is not
72   // absolute (i.e. doesn't start with '/')
73   if (this->PathName && fileName[0] != '/')
74   {
75     fileNameStream << this->PathName;
76   }
77   fileNameStream << fileName;
78 
79   size_t len = fileNameStream.str().length();
80   char* buffer = new char[len + 1];
81   strncpy(buffer, fileNameStream.str().c_str(), len);
82   buffer[len] = '\0';
83 
84   return buffer;
85 }
86 //------------------------------------------------------------------------------
SplitFileName()87 void vtkXMLPDataObjectReader::SplitFileName()
88 {
89   if (!this->FileName)
90   {
91     vtkErrorMacro(<< "Need to specify a filename");
92     return;
93   }
94 
95   // Pull the PathName component out of the FileName.
96   size_t length = strlen(this->FileName);
97   char* fileName = new char[length + 1];
98   strcpy(fileName, this->FileName);
99   char* begin = fileName;
100   char* end = fileName + length;
101   char* s;
102 
103 #if defined(_WIN32)
104   // Convert to UNIX-style slashes.
105   for (s = begin; s != end; ++s)
106   {
107     if (*s == '\\')
108     {
109       *s = '/';
110     }
111   }
112 #endif
113 
114   // Extract the path name up to the last '/'.
115   delete[] this->PathName;
116   this->PathName = nullptr;
117   char* rbegin = end - 1;
118   char* rend = begin - 1;
119   for (s = rbegin; s != rend; --s)
120   {
121     if (*s == '/')
122     {
123       break;
124     }
125   }
126   if (s >= begin)
127   {
128     length = (s - begin) + 1;
129     this->PathName = new char[length + 1];
130     strncpy(this->PathName, this->FileName, length);
131     this->PathName[length] = '\0';
132   }
133 
134   // Cleanup temporary name.
135   delete[] fileName;
136 }
137 
138 //------------------------------------------------------------------------------
PieceProgressCallbackFunction(vtkObject *,unsigned long,void * clientdata,void *)139 void vtkXMLPDataObjectReader::PieceProgressCallbackFunction(
140   vtkObject*, unsigned long, void* clientdata, void*)
141 {
142   reinterpret_cast<vtkXMLPDataObjectReader*>(clientdata)->PieceProgressCallback();
143 }
144 
145 //------------------------------------------------------------------------------
ReadXMLInformation()146 int vtkXMLPDataObjectReader::ReadXMLInformation()
147 {
148   // First setup the filename components.
149   this->SplitFileName();
150 
151   // Now proceed with reading the information.
152   return this->Superclass::ReadXMLInformation();
153 }
154 
155 //------------------------------------------------------------------------------
SetupPieces(int numPieces)156 void vtkXMLPDataObjectReader::SetupPieces(int numPieces)
157 {
158   if (this->NumberOfPieces)
159   {
160     this->DestroyPieces();
161   }
162 
163   this->NumberOfPieces = numPieces;
164   this->PieceElements = new vtkXMLDataElement*[this->NumberOfPieces];
165   this->CanReadPieceFlag = new int[this->NumberOfPieces];
166 
167   for (int i = 0; i < this->NumberOfPieces; ++i)
168   {
169     this->PieceElements[i] = nullptr;
170     this->CanReadPieceFlag[i] = 0;
171   }
172 }
173 
174 //------------------------------------------------------------------------------
DestroyPieces()175 void vtkXMLPDataObjectReader::DestroyPieces()
176 {
177   delete[] this->PieceElements;
178   delete[] this->CanReadPieceFlag;
179   this->PieceElements = nullptr;
180   this->NumberOfPieces = 0;
181 }
182 
183 //------------------------------------------------------------------------------
ReadPiece(vtkXMLDataElement * ePiece,int index)184 int vtkXMLPDataObjectReader::ReadPiece(vtkXMLDataElement* ePiece, int index)
185 {
186   this->Piece = index;
187   return this->ReadPiece(ePiece);
188 }
189