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