1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestArraySerialization.cxx
5
6 -------------------------------------------------------------------------
7 Copyright 2008 Sandia Corporation.
8 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 the U.S. Government retains certain rights in this software.
10 -------------------------------------------------------------------------
11
12 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
13 All rights reserved.
14 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
15
16 This software is distributed WITHOUT ANY WARRANTY; without even
17 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18 PURPOSE. See the above copyright notice for more information.
19
20 =========================================================================*/
21
22 #include <vtkArrayReader.h>
23 #include <vtkArrayWriter.h>
24 #include <vtkDenseArray.h>
25 #include <vtkNew.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkSparseArray.h>
28
29 #include <vtksys/ios/iostream>
30 #include <vtksys/ios/sstream>
31 #include <stdexcept>
32
33 #define test_expression(expression) \
34 { \
35 if(!(expression)) \
36 { \
37 std::ostringstream buffer; \
38 buffer << "Expression failed at line " << __LINE__ << ": " << #expression; \
39 throw std::runtime_error(buffer.str()); \
40 } \
41 }
42
TestArraySerialization(int vtkNotUsed (argc),char * vtkNotUsed (argv)[])43 int TestArraySerialization(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
44 {
45 try
46 {
47 // Test Read and Write in Ascii text mode
48 // Test sparse-array round-trip ...
49 vtkSmartPointer<vtkSparseArray<double> > a1 = vtkSmartPointer<vtkSparseArray<double> >::New();
50 a1->SetName("a1");
51 a1->Resize(2, 2);
52 a1->SetDimensionLabel(0, "rows");
53 a1->SetDimensionLabel(1, "columns");
54 a1->SetNullValue(0.5);
55 a1->AddValue(0, 0, 1.5);
56 a1->AddValue(1, 1, 2.5);
57
58 std::stringstream a_buffer;
59 vtkArrayWriter::Write(a1, a_buffer);
60
61 vtkSmartPointer<vtkArray> a2;
62 a2.TakeReference(vtkArrayReader::Read(a_buffer));
63
64 test_expression(a2);
65 test_expression(a2->GetName() == "a1");
66 test_expression(vtkSparseArray<double>::SafeDownCast(a2));
67 test_expression(a2->GetExtents() == a1->GetExtents());
68 test_expression(a2->GetNonNullSize() == a1->GetNonNullSize());
69 test_expression(a2->GetDimensionLabel(0) == "rows");
70 test_expression(a2->GetDimensionLabel(1) == "columns");
71 test_expression(vtkSparseArray<double>::SafeDownCast(a2)->GetNullValue() == 0.5);
72 test_expression(a2->GetVariantValue(0, 0).ToDouble() == 1.5);
73 test_expression(a2->GetVariantValue(0, 1).ToDouble() == 0.5);
74 test_expression(a2->GetVariantValue(1, 1).ToDouble() == 2.5);
75
76 // Test sparse-array coordinates out-of-bounds ...
77 std::istringstream b_buffer("vtk-sparse-array double\nascii\nb1\n0 2 0 2 1\nrows\ncolumns\n0\n2 2 3.5\n");
78 vtkSmartPointer<vtkArray> b1;
79 b1.TakeReference(vtkArrayReader::Read(b_buffer));
80
81 test_expression(!b1);
82
83 // Test sparse-array not enough values ...
84 std::istringstream d_buffer("vtk-sparse-array double\nascii\nd1\n0 2 0 2 1\nrows\ncolumns\n0\n");
85 vtkSmartPointer<vtkArray> d1;
86 d1.TakeReference(vtkArrayReader::Read(d_buffer));
87
88 test_expression(!d1);
89
90 // Test dense string arrays containing whitespace ...
91 std::istringstream e_buffer("vtk-dense-array string\nascii\ne1\n0 3 3\nvalues\nThe\nquick brown\nfox\n");
92 vtkSmartPointer<vtkArray> e1;
93 e1.TakeReference(vtkArrayReader::Read(e_buffer));
94
95 test_expression(e1);
96 test_expression(vtkDenseArray<vtkStdString>::SafeDownCast(e1));
97 test_expression(e1->GetNonNullSize() == 3);
98 test_expression(e1->GetVariantValue(0).ToString() == "The");
99 test_expression(e1->GetVariantValue(1).ToString() == "quick brown");
100 test_expression(e1->GetVariantValue(2).ToString() == "fox");
101
102 // Test sparse string arrays containing whitespace ...
103 std::istringstream f_buffer("vtk-sparse-array string\nascii\nf1\n0 3 3\nvalues\nempty value\n0 The\n1 quick brown\n2 fox\n");
104 vtkSmartPointer<vtkArray> f1;
105 f1.TakeReference(vtkArrayReader::Read(f_buffer));
106
107 test_expression(f1);
108 test_expression(vtkSparseArray<vtkStdString>::SafeDownCast(f1));
109 test_expression(f1->GetNonNullSize() == 3);
110 test_expression(vtkSparseArray<vtkStdString>::SafeDownCast(f1)->GetNullValue() == "empty value");
111 test_expression(f1->GetVariantValue(0).ToString() == "The");
112 test_expression(f1->GetVariantValue(1).ToString() == "quick brown");
113 test_expression(f1->GetVariantValue(2).ToString() == "fox");
114
115 // Test dense Unicode string arrays containing whitespace ...
116 vtkSmartPointer<vtkDenseArray<vtkUnicodeString> > g1 = vtkSmartPointer<vtkDenseArray<vtkUnicodeString> >::New();
117 g1->Resize(3);
118 g1->SetValue(0, vtkUnicodeString::from_utf8("The"));
119 g1->SetValue(1, vtkUnicodeString::from_utf8("quick brown"));
120 g1->SetValue(2, vtkUnicodeString::from_utf8("fox"));
121
122 std::stringstream g_buffer;
123 vtkArrayWriter::Write(g1, g_buffer);
124 vtkSmartPointer<vtkArray> g2;
125 g2.TakeReference(vtkArrayReader::Read(g_buffer));
126
127 test_expression(g2);
128 test_expression(vtkDenseArray<vtkUnicodeString>::SafeDownCast(g2));
129 test_expression(g2->GetNonNullSize() == 3);
130 test_expression(g2->GetVariantValue(0).ToUnicodeString() == vtkUnicodeString::from_utf8("The"));
131 test_expression(g2->GetVariantValue(1).ToUnicodeString() == vtkUnicodeString::from_utf8("quick brown"));
132 test_expression(g2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
133
134 // Test sparse Unicode string arrays containing whitespace ...
135 vtkSmartPointer<vtkSparseArray<vtkUnicodeString> > h1 = vtkSmartPointer<vtkSparseArray<vtkUnicodeString> >::New();
136 h1->Resize(3);
137 h1->SetNullValue(vtkUnicodeString::from_utf8("nothing here"));
138 h1->SetValue(0, vtkUnicodeString::from_utf8("The"));
139 h1->SetValue(1, vtkUnicodeString::from_utf8("quick brown"));
140 h1->SetValue(2, vtkUnicodeString::from_utf8("fox"));
141
142 std::stringstream h_buffer;
143 vtkArrayWriter::Write(h1, h_buffer);
144 vtkSmartPointer<vtkArray> h2;
145 h2.TakeReference(vtkArrayReader::Read(h_buffer));
146
147 test_expression(h2);
148 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(h2));
149 test_expression(h2->GetNonNullSize() == 3);
150 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(h2)->GetNullValue() == vtkUnicodeString::from_utf8("nothing here"));
151 test_expression(h2->GetVariantValue(0).ToUnicodeString() == vtkUnicodeString::from_utf8("The"));
152 test_expression(h2->GetVariantValue(1).ToUnicodeString() == vtkUnicodeString::from_utf8("quick brown"));
153 test_expression(h2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
154
155 // Test sparse arrays with DOS line endings ...
156 std::istringstream i_buffer("vtk-sparse-array double\r\nascii\r\ni1\r\n0 2 0 2 1\r\nrows\r\ncolumns\r\n0\r\n0 0 5\r\n");
157 vtkSmartPointer<vtkArray> i1;
158 i1.TakeReference(vtkArrayReader::Read(i_buffer));
159
160 test_expression(i1);
161 test_expression(vtkSparseArray<double>::SafeDownCast(i1));
162 test_expression(i1->GetNonNullSize() == 1);
163 test_expression(i1->GetVariantValue(0, 0).ToDouble() == 5);
164 test_expression(i1->GetVariantValue(1, 0).ToDouble() == 0);
165
166 // Test writing to string and reading back ...
167 vtkNew<vtkSparseArray<vtkUnicodeString> > j1;
168 j1->Resize(3);
169 j1->SetNullValue(vtkUnicodeString::from_utf8("nothing here"));
170 j1->SetValue(0, vtkUnicodeString::from_utf8("The"));
171 j1->SetValue(1, vtkUnicodeString::from_utf8("quick brown"));
172 j1->SetValue(2, vtkUnicodeString::from_utf8("fox"));
173
174 vtkNew<vtkArrayData> j1d;
175 j1d->AddArray(j1.GetPointer());
176
177 vtkNew<vtkArrayWriter> jw;
178 jw->WriteToOutputStringOn();
179 jw->SetInputData(j1d.GetPointer());
180 jw->Write();
181 vtkStdString js = jw->GetOutputString();
182
183 vtkNew<vtkArrayReader> jr;
184 jr->ReadFromInputStringOn();
185 jr->SetInputString(js);
186 jr->Update();
187 vtkArray* j2 = jr->GetOutput()->GetArray(0);
188
189 test_expression(j2);
190 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(j2));
191 test_expression(j2->GetNonNullSize() == 3);
192 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(j2)->GetNullValue() == vtkUnicodeString::from_utf8("nothing here"));
193 test_expression(j2->GetVariantValue(0).ToUnicodeString() == vtkUnicodeString::from_utf8("The"));
194 test_expression(j2->GetVariantValue(1).ToUnicodeString() == vtkUnicodeString::from_utf8("quick brown"));
195 test_expression(j2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
196
197 // Test Read and Write in Binary mode
198 // Test sparse-array round-trip ...
199 vtkSmartPointer<vtkSparseArray<double> > ba1 = vtkSmartPointer<vtkSparseArray<double> >::New();
200 ba1->SetName("ba1");
201 ba1->Resize(2, 2);
202 ba1->SetNullValue(0.5);
203 ba1->AddValue(0, 0, 1.5);
204 ba1->AddValue(1, 1, 2.5);
205
206 std::stringstream ba_buffer;
207 vtkArrayWriter::Write(ba1, ba_buffer, true);
208 vtkSmartPointer<vtkArray> ba2;
209 ba2.TakeReference(vtkArrayReader::Read(ba_buffer));
210
211 test_expression(ba2);
212 test_expression(ba2->GetName() == "ba1");
213 test_expression(vtkSparseArray<double>::SafeDownCast(ba2));
214 test_expression(ba2->GetExtents() == ba1->GetExtents());
215 test_expression(ba2->GetNonNullSize() == ba1->GetNonNullSize());
216 test_expression(vtkSparseArray<double>::SafeDownCast(ba2)->GetNullValue() == 0.5);
217 test_expression(ba2->GetVariantValue(0, 0).ToDouble() == 1.5);
218 test_expression(ba2->GetVariantValue(0, 1).ToDouble() == 0.5);
219 test_expression(ba2->GetVariantValue(1, 1).ToDouble() == 2.5);
220
221 // Test dense string arrays containing whitespace ...
222 vtkSmartPointer<vtkDenseArray<vtkStdString> > bb1 = vtkSmartPointer<vtkDenseArray<vtkStdString> >::New();
223 bb1->SetName("bb1");
224 bb1->Resize(3);
225 bb1->SetValue(0, "The");
226 bb1->SetValue(1, "quick brown");
227 bb1->SetValue(2, "fox");
228
229 std::stringstream bb_buffer;
230 vtkArrayWriter::Write(bb1, bb_buffer, true);
231 vtkSmartPointer<vtkArray> bb2;
232 bb2.TakeReference(vtkArrayReader::Read(bb_buffer));
233
234 test_expression(bb2);
235 test_expression(bb2->GetName() == "bb1");
236 test_expression(vtkDenseArray<vtkStdString>::SafeDownCast(bb2));
237 test_expression(bb2->GetNonNullSize() == 3);
238 test_expression(bb2->GetVariantValue(0).ToString() == "The");
239 test_expression(bb2->GetVariantValue(1).ToString() == "quick brown");
240 test_expression(bb2->GetVariantValue(2).ToString() == "fox");
241
242 // Test sparse string arrays containing whitespace ...
243 vtkSmartPointer<vtkSparseArray<vtkStdString> > bc1 = vtkSmartPointer<vtkSparseArray<vtkStdString> >::New();
244 bc1->Resize(3);
245 bc1->SetNullValue("empty space");
246 bc1->SetValue(0, "The");
247 bc1->SetValue(1, "quick brown");
248 bc1->SetValue(2, "fox");
249
250 std::stringstream bc_buffer;
251 vtkArrayWriter::Write(bc1, bc_buffer, true);
252 vtkSmartPointer<vtkArray> bc2;
253 bc2.TakeReference(vtkArrayReader::Read(bc_buffer));
254
255 test_expression(bc2);
256 test_expression(vtkSparseArray<vtkStdString>::SafeDownCast(bc2));
257 test_expression(bc2->GetNonNullSize() == 3);
258 test_expression(vtkSparseArray<vtkStdString>::SafeDownCast(bc2)->GetNullValue() == "empty space");
259 test_expression(bc2->GetVariantValue(0).ToString() == "The");
260 test_expression(bc2->GetVariantValue(1).ToString() == "quick brown");
261 test_expression(bc2->GetVariantValue(2).ToString() == "fox");
262
263 // Test dense Unicode string arrays containing whitespace ...
264 vtkSmartPointer<vtkDenseArray<vtkUnicodeString> > bd1 = vtkSmartPointer<vtkDenseArray<vtkUnicodeString> >::New();
265 bd1->Resize(3);
266 bd1->SetValue(0, vtkUnicodeString::from_utf8("The"));
267 bd1->SetValue(1, vtkUnicodeString::from_utf8("quick brown"));
268 bd1->SetValue(2, vtkUnicodeString::from_utf8("fox"));
269
270 std::stringstream bd_buffer;
271 vtkArrayWriter::Write(bd1, bd_buffer, true);
272 vtkSmartPointer<vtkArray> bd2;
273 bd2.TakeReference(vtkArrayReader::Read(bd_buffer));
274
275 test_expression(bd2);
276 test_expression(vtkDenseArray<vtkUnicodeString>::SafeDownCast(bd2));
277 test_expression(bd2->GetNonNullSize() == 3);
278 test_expression(bd2->GetVariantValue(0).ToUnicodeString() == vtkUnicodeString::from_utf8("The"));
279 test_expression(bd2->GetVariantValue(1).ToUnicodeString() == vtkUnicodeString::from_utf8("quick brown"));
280 test_expression(bd2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
281
282 // Test sparse Unicode string arrays containing whitespace ...
283 vtkSmartPointer<vtkSparseArray<vtkUnicodeString> > be1 = vtkSmartPointer<vtkSparseArray<vtkUnicodeString> >::New();
284 be1->Resize(3);
285 be1->SetNullValue(vtkUnicodeString::from_utf8("nothing here"));
286 be1->SetValue(0, vtkUnicodeString::from_utf8("The"));
287 be1->SetValue(1, vtkUnicodeString::from_utf8("quick brown"));
288 be1->SetValue(2, vtkUnicodeString::from_utf8("fox"));
289
290 std::stringstream be_buffer;
291 vtkArrayWriter::Write(be1, be_buffer, true);
292 vtkSmartPointer<vtkArray> be2;
293 be2.TakeReference(vtkArrayReader::Read(be_buffer));
294
295 test_expression(be2);
296 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(be2));
297 test_expression(be2->GetNonNullSize() == 3);
298 test_expression(vtkSparseArray<vtkUnicodeString>::SafeDownCast(be2)->GetNullValue() == vtkUnicodeString::from_utf8("nothing here"));
299 test_expression(be2->GetVariantValue(0).ToUnicodeString() == vtkUnicodeString::from_utf8("The"));
300 test_expression(be2->GetVariantValue(1).ToUnicodeString() == vtkUnicodeString::from_utf8("quick brown"));
301 test_expression(be2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
302
303 return 0;
304 }
305 catch(std::exception& e)
306 {
307 cerr << e.what() << endl;
308 return 1;
309 }
310 }
311
312