1 : /* _________________________________________________________________________
2 : *
3 : * UTILIB: A utility library for developing portable C++ codes.
4 : * Copyright (c) 2008 Sandia Corporation.
5 : * This software is distributed under the BSD License.
6 : * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7 : * the U.S. Government retains certain rights in this software.
8 : * For more information, see the README file in the top UTILIB directory.
9 : * _________________________________________________________________________
10 : */
11 :
12 : #include <utilib/fSerialStream.h>
13 :
14 : using std::endl;
15 :
16 : using std::list;
17 :
18 : using utilib::SerialObject;
19 : using utilib::Serializer;
20 : using utilib::Any;
21 :
22 : #define OUT std::cout
23 :
24 : template<typename T>
25 : std::ostream& print(std::ostream& os, const T& stl)
26 : {
27 : typename T::const_iterator it = stl.begin();
28 : os << "[ " << stl.size() << ": ";
29 : for ( ; it != stl.end(); ++it )
30 : os << *it << " ";
31 : os << "]";
32 : return os;
33 : }
34 :
35 : template<typename T1, typename T2>
36 : std::ostream& operator<<(std::ostream& os, const list<T1,T2>& stl)
37 : { return print(os, stl); }
38 :
39 :
40 : namespace {
41 :
42 : /// Defining a simple class to serialize
43 : class A
44 17 : {
45 : public:
46 11 : A()
47 11 : : a(0), b(0), c()
48 11 : {}
49 1 : A(int x, float y)
50 1 : : a(x), b(y), c(x,y)
51 1 : {}
52 : std::ostream& print(std::ostream& os) const
53 : {
54 : os << "{" << a << ", " << b << ", " << c << "}";
55 : return os;
56 : }
57 5 : bool operator==(const A& rhs) const
58 : {
59 5 : return ( a == rhs.a ) && ( b == rhs.b ) && ( c == rhs.c );
60 : }
61 : bool operator<(const A& rhs) const
62 : {
63 : return a < rhs.a; // bogus... I know...
64 : }
65 :
66 : private:
67 : static int serializer(SerialObject::elementList_t& serial,
68 : Any& data,
69 8 : bool serialize)
70 : {
71 8 : A& me = const_cast<A&>(data.expose<A>());
72 8 : serial_transform(serial, me.a, serialize);
73 8 : serial_transform(serial, me.b, serialize);
74 8 : serial_transform(serial, me.c, serialize);
75 8 : return 0;
76 : }
77 :
78 : private:
79 : static const int serializer_registered;
80 :
81 : int a;
82 : float b;
83 : list<double> c;
84 : };
85 :
86 : // Register the serializer for class A
87 34 : const int A::serializer_registered
88 : = Serializer().register_serializer<A>("fss:A", A::serializer);
89 :
90 : // support stream output for the testing macros
91 : std::ostream& operator<<(std::ostream& os, const A& data)
92 : { return data.print(os); }
93 :
94 :
95 : } // namespace local
96 :
97 : //-----------------------------------------------------------------------
98 :
99 1 : int test_fserialstream(int , char**)
100 : {
101 1 : int i1 = 5;
102 1 : double d1 = 3.1415;
103 1 : double d1a = 1.234;
104 1 : char c1 = 'A';
105 1 : A a1(2, 5.5f);
106 :
107 : // Test 0: generate a test file
108 : try
109 : {
110 1 : utilib::ofSerialStream ofss("fserialstream.out");
111 1 : ofss << i1 << d1 << a1;
112 1 : ofss.close();
113 :
114 1 : OUT << "(file created)" << endl;
115 : }
116 0 : catch (std::exception &e)
117 : {
118 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
119 : }
120 :
121 : // Test 1: reading 1 at a time
122 1 : OUT << "Single reads:" << endl;
123 : try
124 : {
125 1 : int i2 = 0;
126 1 : double d2 = 1.0;
127 1 : A a2;
128 :
129 1 : utilib::ifSerialStream ifss("fserialstream.out");
130 1 : ifss >> i2;
131 1 : OUT << " int: " << ( i1 == i2 ? "[ OK ]" : "[FAIL]" ) << endl;
132 1 : ifss >> d2;
133 1 : OUT << " double: " << ( d1 == d2 ? "[ OK ]" : "[FAIL]" ) << endl;
134 1 : ifss >> a2;
135 1 : OUT << " A: " << (( a1 == a2 )? "[ OK ]" : "[FAIL]" ) << endl;
136 1 : ifss.close();
137 : }
138 0 : catch (std::exception &e)
139 : {
140 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
141 : }
142 :
143 : // Test 2: chain reading
144 1 : OUT << "Chain reading:" << endl;
145 : try
146 : {
147 1 : int i2 = 0;
148 1 : double d2 = 1.0;
149 1 : A a2;
150 :
151 1 : utilib::ifSerialStream ifss("fserialstream.out");
152 1 : ifss >> i2 >> d2 >> a2;
153 1 : ifss.close();
154 :
155 1 : OUT << " int: " << ( i1 == i2 ? "[ OK ]" : "[FAIL]" ) << endl;
156 1 : OUT << " double: " << ( d1 == d2 ? "[ OK ]" : "[FAIL]" ) << endl;
157 1 : OUT << " A: " << (( a1 == a2 )? "[ OK ]" : "[FAIL]" ) << endl;
158 : }
159 0 : catch (std::exception &e)
160 : {
161 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
162 : }
163 :
164 : // Test 3: type conversions
165 1 : OUT << "Converting read:" << endl;
166 : try
167 : {
168 1 : list<double> l1;
169 2 : list<double> l2;
170 2 : list<double> l3;
171 :
172 1 : utilib::ifSerialStream ifss("fserialstream.out");
173 1 : ifss >> l1 >> l2;
174 :
175 : OUT << " l1: " << ( i1 == l1.front() ? "[ OK ]: " : "[FAIL]: " )
176 1 : << l1 << endl;
177 : OUT << " l2: " << ( d1 == l2.front() ? "[ OK ]: " : "[FAIL]: " )
178 1 : << l2 << endl;
179 :
180 : try {
181 1 : ifss >> l3;
182 0 : OUT << "[FAIL]: should NOT be able to read A as list<double>" << endl;
183 : }
184 2 : catch ( ... )
185 : {
186 : OUT << " [ OK ]: get A as list<double> (correctly) threw exception"
187 1 : << endl;
188 : }
189 1 : ifss.close();
190 : }
191 0 : catch (std::exception &e)
192 : {
193 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
194 : }
195 :
196 : // Test 4: appending to a file
197 1 : OUT << "Appending to an existing file" << endl;
198 : try
199 : {
200 1 : int i2 = 0;
201 1 : double d2 = 1.0;
202 1 : A a2;
203 1 : double d2a = 0.0;
204 :
205 1 : utilib::ofSerialStream ofss("fserialstream.out", std::ios_base::app);
206 1 : ofss << d1a;
207 1 : ofss.close();
208 1 : OUT << " (appended d1a)" << endl;
209 :
210 1 : utilib::ifSerialStream ifss("fserialstream.out");
211 1 : ifss >> i2 >> d2 >> a2 >> d2a;
212 1 : ifss.close();
213 :
214 1 : OUT << " int: " << ( i1 == i2 ? "[ OK ]" : "[FAIL]" ) << endl;
215 1 : OUT << " double: " << ( d1 == d2 ? "[ OK ]" : "[FAIL]" ) << endl;
216 1 : OUT << " A: " << (( a1 == a2 )? "[ OK ]" : "[FAIL]" ) << endl;
217 1 : OUT << " double: " << ( d1a == d2a ? "[ OK ]" : "[FAIL]" ) << endl;
218 : }
219 0 : catch (std::exception &e)
220 : {
221 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
222 : }
223 :
224 : // Test 5: appending information
225 1 : OUT << "fSerialStream appending to an existing file" << endl;
226 : try
227 : {
228 1 : int i2 = 0;
229 1 : double d2 = 1.0;
230 1 : A a2;
231 1 : double d2a = 1.0;
232 1 : char c2 = ' ';
233 :
234 1 : utilib::fSerialStream fss("fserialstream.out", std::ios_base::ate);
235 : // read 2 ...
236 1 : fss >> i2 >> d2;
237 1 : OUT << " int: " << ( i1 == i2 ? "[ OK ]" : "[FAIL]" ) << endl;
238 1 : OUT << " double: " << ( d1 == d2 ? "[ OK ]" : "[FAIL]" ) << endl;
239 : // write 1...
240 1 : fss << c1;
241 1 : OUT << " (wrote c1)" << endl;
242 1 : fss.flush();
243 : // read 2 ...
244 1 : fss >> a2 >> d2a >> c2;
245 1 : OUT << " A: " << (( a1 == a2 )? "[ OK ]" : "[FAIL]" ) << endl;
246 1 : OUT << " double: " << ( d1a == d2a ? "[ OK ]" : "[FAIL]" ) << endl;
247 1 : OUT << " char " << (( c1 == c2 )? "[ OK ]" : "[FAIL]" ) << endl;
248 1 : fss.close();
249 : }
250 0 : catch (std::exception &e)
251 : {
252 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
253 : }
254 :
255 : // Test 6:
256 1 : OUT << "fSerialStream to a new/truncated file" << endl;
257 : try
258 : {
259 1 : int i2 = 0;
260 1 : double d2 = 1.0;
261 1 : A a2;
262 1 : char c2 = ' ';
263 :
264 1 : utilib::fSerialStream fss("fserialstream.out", std::ios_base::trunc);
265 1 : fss << i1 << d1;
266 1 : fss >> i2 >> d2;
267 1 : OUT << " int: " << ( i1 == i2 ? "[ OK ]" : "[FAIL]" ) << endl;
268 1 : OUT << " double: " << ( d1 == d2 ? "[ OK ]" : "[FAIL]" ) << endl;
269 :
270 1 : fss << a1 << c1;
271 1 : fss >> a2 >> c2;
272 1 : OUT << " A: " << (( a1 == a2 )? "[ OK ]" : "[FAIL]" ) << endl;
273 1 : OUT << " char " << (( c1 == c2 )? "[ OK ]" : "[FAIL]" ) << endl;
274 1 : fss.close();
275 : }
276 0 : catch (std::exception &e)
277 : {
278 0 : OUT << "Caught unexpected exception: " << endl << e.what() << endl;
279 : }
280 :
281 1 : return 0;
282 68 : }
|