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