C++17 removes std::auto_ptr so we don't provide the ACE auto_ptr templates anymore...
[ACE_TAO.git] / ACE / tests / CDR_File_Test.cpp
blob7aa9b755801602f6a6ff90865fab79d374f0ba22
2 //=============================================================================
3 /**
4 * @file CDR_File_Test.cpp
6 * Checks the functionality of the ACE CDR streams used for file
7 * I/O.
9 * @author Giga Giguashvili <gregoryg@ParadigmGeo.com> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
11 //=============================================================================
13 #include "test_config.h"
14 #include "ace/OS_Memory.h"
15 #include "ace/OS_NS_stdlib.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/CDR_Stream.h"
18 #include "ace/FILE_Connector.h"
19 #include "ace/Auto_Ptr.h"
20 #include "ace/Get_Opt.h"
21 #include "ace/ACE.h"
22 #include "ace/Truncate.h"
24 // FUZZ: disable check_for_streams_include
25 #include "ace/streams.h"
27 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
29 /**
30 * @class CDR_Test
32 * @brief Simple class that's used to read and write CDR streams.
34 class CDR_Test
36 /// Output the state of a <CDR_Test> object to the <ostream>.
37 friend ostream& operator << (ostream &os, const CDR_Test &t);
39 /// Convert the state of this object into an <ACE_OutputCDR>.
40 friend void operator << (ACE_OutputCDR &os, const CDR_Test &t);
42 /// Convert the <ACE_InputCDR> into the state of this object.
43 friend void operator >> (ACE_InputCDR &is, CDR_Test &);
45 public:
46 /// Default constructor.
47 CDR_Test ();
49 /// Constructor.
50 CDR_Test (ACE_CDR::Char o,
51 ACE_CDR::Short s,
52 ACE_CDR::Long w,
53 ACE_CDR::ULongLong lw,
54 ACE_CDR::Float f,
55 ACE_CDR::Double d);
57 /// Compare <rhs> for equality with <this>.
58 bool operator == (const CDR_Test &rhs) const;
60 private:
61 ACE_CDR::Char char_;
62 ACE_CDR::Short word2_;
63 ACE_CDR::Long word4_;
64 ACE_CDR::ULongLong word8_;
65 ACE_CDR::Float fpoint_;
66 ACE_CDR::Double dprec_;
69 ostream &
70 operator << (ostream &os,
71 const CDR_Test &t)
73 os << "Char: " << t.char_ << endl
74 << "Short: " << t.word2_ << endl
75 << "Long: " << t.word4_ << endl;
77 ACE_CDR::ULongLong hi = (t.word8_ >> 32);
78 ACE_CDR::ULongLong lo = (t.word8_ & 0xffffffff);
80 os << "ULongLong 1st half: "
81 << hex
82 << ACE_Utils::truncate_cast<ACE_UINT32> (hi)
83 << dec << endl
84 << "ULongLong 2nd half: "
85 << hex
86 << ACE_Utils::truncate_cast<ACE_UINT32> (lo)
87 << dec << endl
88 << "Float: " << t.fpoint_ << endl
89 << "Double: " << t.dprec_ << endl;
90 return os;
93 CDR_Test::CDR_Test ()
94 : char_ (0),
95 word2_ (0),
96 word4_ (0),
97 word8_ (0),
98 fpoint_ (0.0),
99 dprec_ (0.0)
103 CDR_Test::CDR_Test (ACE_CDR::Char o,
104 ACE_CDR::Short s,
105 ACE_CDR::Long w,
106 ACE_CDR::ULongLong lw,
107 ACE_CDR::Float f,
108 ACE_CDR::Double d)
109 : char_ (o),
110 word2_ (s),
111 word4_ (w),
112 word8_ (lw),
113 fpoint_ (f),
114 dprec_ (d)
118 void
119 operator << (ACE_OutputCDR &os, const CDR_Test &t)
121 os << t.char_;
122 os << t.word2_;
123 os << t.word4_;
124 os << t.word8_;
125 os << t.fpoint_;
126 os << t.dprec_;
129 void
130 operator >> (ACE_InputCDR &is, CDR_Test &t)
132 is >> t.char_;
133 is >> t.word2_;
134 is >> t.word4_;
135 is >> t.word8_;
136 is >> t.fpoint_;
137 is >> t.dprec_;
140 bool
141 CDR_Test::operator == (const CDR_Test &rhs) const
143 // @@ Workaround bug in egcs-1.1.1 using a single && expression
144 // results in UMR errors in purify.
145 if (this->char_ != rhs.char_)
146 return false;
147 if (this->word2_ != rhs.word2_)
148 return false;
149 if (this->word4_ != rhs.word4_)
150 return false;
151 if (this->word8_ != rhs.word8_)
152 return false;
153 if (!ACE::is_equal (this->fpoint_, rhs.fpoint_))
154 return false;
155 if (!ACE::is_equal (this->dprec_, rhs.dprec_))
156 return false;
157 return true;
160 static int
161 run_test (int write_file,
162 ACE_FILE_IO &file,
163 const ACE_TCHAR *filename,
164 CDR_Test &cdr_test)
166 if (write_file)
168 char byte_order = ACE_CDR_BYTE_ORDER;
169 size_t n = file.send (&byte_order, 1);
170 if (n != 1)
171 ACE_ERROR_RETURN ((LM_ERROR,
172 ACE_TEXT ("send failed on %p\n"),
173 filename),
174 -1);
176 ACE_OutputCDR output_cdr (0,
177 ACE_CDR_BYTE_ORDER,
181 ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
182 ACE_CDR_GIOP_MAJOR_VERSION,
183 ACE_CDR_GIOP_MINOR_VERSION);
184 // Marshal the <CDR_Test> object data to the output CDR stream.
185 output_cdr << cdr_test;
187 // Output the data to cout.
188 *ace_file_stream::instance ()->output_file () << cdr_test;
190 // Save the data.
191 const ACE_Message_Block *output_mb =
192 output_cdr.begin ();
194 ACE_DEBUG ((LM_DEBUG,
195 ACE_TEXT ("Writing file %s in %s endian format...\n"),
196 filename,
197 ACE_CDR_BYTE_ORDER ? ACE_TEXT("little") : ACE_TEXT("big")));
199 n = file.send (output_mb->rd_ptr (),
200 output_mb->length ());
201 if (n != (size_t) output_mb->length ())
202 ACE_ERROR_RETURN ((LM_ERROR,
203 ACE_TEXT ("send failed on %p\n"),
204 filename),
205 -1);
207 else // We're reading from the file.
209 ACE_FILE_Info info;
210 if (file.get_info (info) == -1)
211 ACE_ERROR_RETURN ((LM_ERROR,
212 ACE_TEXT ("get_info failed on %p\n"),
213 filename),
214 -1);
216 ACE_OFF_T msgsize = info.size_ - 1;
218 // Allocate the input buffer
219 char *buffer = 0;
220 ACE_NEW_RETURN (buffer,
221 char[msgsize],
222 -1);
223 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
224 ACE_OS::memset(buffer, 0, sizeof (buffer));
225 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
227 // Make sure <buffer> is released automagically.
228 std::unique_ptr<char[]> b (buffer);
230 // Move the file pointer back to the beginning of the file.
231 if (file.seek (0,
232 SEEK_SET) == -1)
233 ACE_ERROR_RETURN ((LM_ERROR,
234 ACE_TEXT ("%p\n"),
235 filename),
236 -1);
238 char byte_order;
239 ssize_t size = file.recv (&byte_order, 1);
240 if (size != 1)
241 ACE_ERROR_RETURN ((LM_ERROR,
242 ACE_TEXT ("Read %d bytes, rather than expected ")
243 ACE_TEXT ("1 bytes\n"),
244 size),
245 -1);
247 // Read the cdr data from the file into the buffer.
248 size = file.recv (buffer, msgsize);
249 if (size != msgsize)
250 ACE_ERROR_RETURN ((LM_ERROR,
251 ACE_TEXT ("Read %d bytes, rather than expected ")
252 ACE_TEXT ("%d bytes\n"),
253 size,
254 msgsize),
255 -1);
257 // Create message block for the whole file. Ensure that it is
258 // aligned to properly handle the double.
259 ACE_Message_Block mb (ACE_CDR::MAX_ALIGNMENT + msgsize);
260 ACE_CDR::mb_align (&mb);
262 mb.copy (buffer, msgsize);
264 // Create CDR input stream from the message block.
266 ACE_InputCDR input_cdr (&mb);
267 input_cdr.reset_byte_order ((int) byte_order);
269 ACE_DEBUG ((LM_DEBUG,
270 ACE_TEXT ("Reading file %s in %s endian format...\n"),
271 filename,
272 ACE_CDR_BYTE_ORDER ? ACE_TEXT("little") : ACE_TEXT("big")));
274 CDR_Test temp;
276 // Demarshal the data from the input CDR stream into the
277 // <CDR_Test> object.
278 input_cdr >> temp;
280 *ace_file_stream::instance ()->output_file () << temp;
282 if (!(temp == cdr_test))
283 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Data mismatch across file\n")));
286 return 0;
289 static void
290 usage (const ACE_TCHAR *cmd)
292 ACE_ERROR ((LM_ERROR,
293 ACE_TEXT ("Usage: %s ")
294 ACE_TEXT ("[-f filename [-w|-r]]"),
295 cmd));
296 ACE_OS::exit (1);
299 // Main function
302 run_main (int argc, ACE_TCHAR *argv[])
304 ACE_START_TEST (ACE_TEXT ("CDR_File_Test"));
306 ACE_DEBUG ((LM_DEBUG,
307 ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"),
308 ACE::major_version (),
309 ACE::minor_version (),
310 ACE::micro_version ()));
312 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("f:rw"));
313 int opt;
314 int reading = 1;
315 int writing = 1;
316 ACE_TCHAR* fn = 0;
317 while ((opt = get_opt ()) != EOF)
319 switch (opt)
321 case 'f':
322 fn = get_opt.opt_arg ();
323 break;
324 case 'r':
325 writing = 0;
326 break;
327 case 'w':
328 reading = 0;
329 break;
330 case '?':
331 default:
332 usage (ACE_TEXT("CDR_File_Test"));
336 if ((!reading || !writing) && fn == 0)
337 usage (ACE_TEXT("CDR_File_Test"));
339 if (!reading && !writing)
340 usage (ACE_TEXT("CDR_File_Test"));
342 // Create a temporary filename.
343 ACE_FILE_Addr filename (ACE_sap_any_cast (ACE_FILE_Addr &));
344 if (fn != 0)
345 filename.set (fn);
348 ACE_FILE_Connector connector;
349 ACE_FILE_IO file;
351 // Open up the file.
352 if (connector.connect (file,
353 filename,
355 ACE_Addr::sap_any,
357 ((writing) ? (O_RDWR | O_CREAT) : O_RDONLY),
358 ACE_DEFAULT_FILE_PERMS) == -1)
359 ACE_ERROR_RETURN ((LM_ERROR,
360 ACE_TEXT ("connect failed for %p\n"),
361 filename.get_path_name ()),
364 CDR_Test cdr_test ('a',
365 0x00ff,
366 0xaabbccdd,
367 0x01234567,
368 1.54321f,
369 1.12345);
371 if (writing)
373 // write the file.
374 run_test (1,
375 file,
376 filename.get_path_name (),
377 cdr_test);
380 if (reading)
382 // read the file.
383 run_test (0,
384 file,
385 filename.get_path_name (),
386 cdr_test);
389 if (fn == 0)
391 file.close ();
392 if (file.unlink () == -1)
393 ACE_ERROR_RETURN ((LM_ERROR,
394 ACE_TEXT ("unlink failed for %p\n"),
395 filename.get_path_name ()),
399 ACE_END_TEST;
400 return 0;
403 #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
406 run_main (int, ACE_TCHAR *[])
408 ACE_START_TEST (ACE_TEXT ("CDR_File_Test"));
410 ACE_ERROR ((LM_INFO,
411 ACE_TEXT ("iostreams not supported on this platform\n")));
413 ACE_END_TEST;
414 return 0;
417 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */