Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / ACE / tests / CDR_File_Test.cpp
blob6d44f5546a691a42c2b16b84b6d5d6c3d6273fe1
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 //=============================================================================
14 #include "test_config.h"
15 #include "ace/OS_Memory.h"
16 #include "ace/OS_NS_stdlib.h"
17 #include "ace/OS_NS_string.h"
18 #include "ace/CDR_Stream.h"
19 #include "ace/FILE_Connector.h"
20 #include "ace/Auto_Ptr.h"
21 #include "ace/Get_Opt.h"
22 #include "ace/ACE.h"
23 #include "ace/Truncate.h"
25 // FUZZ: disable check_for_streams_include
26 #include "ace/streams.h"
30 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
32 /**
33 * @class CDR_Test
35 * @brief Simple class that's used to read and write CDR streams.
37 class CDR_Test
40 /// Output the state of a <CDR_Test> object to the <ostream>.
41 friend ostream& operator << (ostream &os, const CDR_Test &t);
43 /// Convert the state of this object into an <ACE_OutputCDR>.
44 friend void operator << (ACE_OutputCDR &os, const CDR_Test &t);
46 /// Convert the <ACE_InputCDR> into the state of this object.
47 friend void operator >> (ACE_InputCDR &is, CDR_Test &);
49 public:
50 /// Default constructor.
51 CDR_Test (void);
53 /// Constructor.
54 CDR_Test (ACE_CDR::Char o,
55 ACE_CDR::Short s,
56 ACE_CDR::Long w,
57 ACE_CDR::ULongLong lw,
58 ACE_CDR::Float f,
59 ACE_CDR::Double d);
61 /// Compare <rhs> for equality with <this>.
62 bool operator == (const CDR_Test &rhs) const;
64 private:
65 ACE_CDR::Char char_;
66 ACE_CDR::Short word2_;
67 ACE_CDR::Long word4_;
68 ACE_CDR::ULongLong word8_;
69 ACE_CDR::Float fpoint_;
70 ACE_CDR::Double dprec_;
73 ostream &
74 operator << (ostream &os,
75 const CDR_Test &t)
77 #if defined (ACE_OPENVMS)
78 // to circumvent some obscure bug with OpenVMS iostreams digit conversions
79 // combined with shared libraries????
80 ACE_DEBUG ((LM_DEBUG,
81 ACE_TEXT ("\n"
82 "Char: %c\n"
83 "Short: %u\n"
84 "Long: %d\n"),
85 t.char_,
86 t.word2_,
87 t.word4_));
89 ACE_CDR::ULongLong hi = (t.word8_ >> 32);
90 ACE_CDR::ULongLong lo = (t.word8_ & 0xffffffff);
92 ACE_DEBUG ((LM_DEBUG,
93 ACE_TEXT ("\n"
94 "ULongLong 1st half: %x\n"
95 "ULongLong 2nd half: %x\n"
96 "Float: %f\n"
97 "Double: %f\n"),
98 ACE_Utils::truncate_cast<ACE_UINT32> (hi),
99 ACE_Utils::truncate_cast<ACE_UINT32> (lo),
100 t.fpoint_,
101 t.dprec_));
102 #else
103 os << "Char: " << t.char_ << endl
104 << "Short: " << t.word2_ << endl
105 << "Long: " << t.word4_ << endl;
107 ACE_CDR::ULongLong hi = (t.word8_ >> 32);
108 ACE_CDR::ULongLong lo = (t.word8_ & 0xffffffff);
110 os << "ULongLong 1st half: "
111 << hex
112 << ACE_Utils::truncate_cast<ACE_UINT32> (hi)
113 << dec << endl
114 << "ULongLong 2nd half: "
115 << hex
116 << ACE_Utils::truncate_cast<ACE_UINT32> (lo)
117 << dec << endl
118 << "Float: " << t.fpoint_ << endl
119 << "Double: " << t.dprec_ << endl;
120 #endif
121 return os;
124 CDR_Test::CDR_Test (void)
125 : char_ (0),
126 word2_ (0),
127 word4_ (0),
128 word8_ (0),
129 fpoint_ (0.0),
130 dprec_ (0.0)
134 CDR_Test::CDR_Test (ACE_CDR::Char o,
135 ACE_CDR::Short s,
136 ACE_CDR::Long w,
137 ACE_CDR::ULongLong lw,
138 ACE_CDR::Float f,
139 ACE_CDR::Double d)
140 : char_ (o),
141 word2_ (s),
142 word4_ (w),
143 word8_ (lw),
144 fpoint_ (f),
145 dprec_ (d)
149 void
150 operator << (ACE_OutputCDR &os, const CDR_Test &t)
152 os << t.char_;
153 os << t.word2_;
154 os << t.word4_;
155 os << t.word8_;
156 os << t.fpoint_;
157 os << t.dprec_;
160 void
161 operator >> (ACE_InputCDR &is, CDR_Test &t)
163 is >> t.char_;
164 is >> t.word2_;
165 is >> t.word4_;
166 is >> t.word8_;
167 is >> t.fpoint_;
168 is >> t.dprec_;
171 bool
172 CDR_Test::operator == (const CDR_Test &rhs) const
174 // @@ Workaround bug in egcs-1.1.1 using a single && expression
175 // results in UMR errors in purify.
176 if (this->char_ != rhs.char_)
177 return false;
178 if (this->word2_ != rhs.word2_)
179 return false;
180 if (this->word4_ != rhs.word4_)
181 return false;
182 if (this->word8_ != rhs.word8_)
183 return false;
184 if (!ACE::is_equal (this->fpoint_, rhs.fpoint_))
185 return false;
186 if (!ACE::is_equal (this->dprec_, rhs.dprec_))
187 return false;
188 return true;
191 static int
192 run_test (int write_file,
193 ACE_FILE_IO &file,
194 const ACE_TCHAR *filename,
195 CDR_Test &cdr_test)
197 if (write_file)
199 char byte_order = ACE_CDR_BYTE_ORDER;
200 size_t n = file.send (&byte_order, 1);
201 if (n != 1)
202 ACE_ERROR_RETURN ((LM_ERROR,
203 ACE_TEXT ("send failed on %p\n"),
204 filename),
205 -1);
207 ACE_OutputCDR output_cdr (0,
208 ACE_CDR_BYTE_ORDER,
212 ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
213 ACE_CDR_GIOP_MAJOR_VERSION,
214 ACE_CDR_GIOP_MINOR_VERSION);
215 // Marshal the <CDR_Test> object data to the output CDR stream.
216 output_cdr << cdr_test;
218 // Output the data to cout.
219 *ace_file_stream::instance ()->output_file () << cdr_test;
221 // Save the data.
222 const ACE_Message_Block *output_mb =
223 output_cdr.begin ();
225 ACE_DEBUG ((LM_DEBUG,
226 ACE_TEXT ("Writing file %s in %s endian format...\n"),
227 filename,
228 ACE_CDR_BYTE_ORDER ? ACE_TEXT("little") : ACE_TEXT("big")));
230 n = file.send (output_mb->rd_ptr (),
231 output_mb->length ());
232 if (n != (size_t) output_mb->length ())
233 ACE_ERROR_RETURN ((LM_ERROR,
234 ACE_TEXT ("send failed on %p\n"),
235 filename),
236 -1);
238 else // We're reading from the file.
240 ACE_FILE_Info info;
241 if (file.get_info (info) == -1)
242 ACE_ERROR_RETURN ((LM_ERROR,
243 ACE_TEXT ("get_info failed on %p\n"),
244 filename),
245 -1);
247 ACE_OFF_T msgsize = info.size_ - 1;
249 // Allocate the input buffer
250 char *buffer = 0;
251 ACE_NEW_RETURN (buffer,
252 char[msgsize],
253 -1);
254 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
255 ACE_OS::memset(buffer, 0, sizeof (buffer));
256 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
258 // Make sure <buffer> is released automagically.
259 ACE_Auto_Basic_Array_Ptr<char> b (buffer);
261 // Move the file pointer back to the beginning of the file.
262 if (file.seek (0,
263 SEEK_SET) == -1)
264 ACE_ERROR_RETURN ((LM_ERROR,
265 ACE_TEXT ("%p\n"),
266 filename),
267 -1);
269 char byte_order;
270 ssize_t size = file.recv (&byte_order, 1);
271 if (size != 1)
272 ACE_ERROR_RETURN ((LM_ERROR,
273 ACE_TEXT ("Read %d bytes, rather than expected ")
274 ACE_TEXT ("1 bytes\n"),
275 size),
276 -1);
278 // Read the cdr data from the file into the buffer.
279 size = file.recv (buffer, msgsize);
280 if (size != msgsize)
281 ACE_ERROR_RETURN ((LM_ERROR,
282 ACE_TEXT ("Read %d bytes, rather than expected ")
283 ACE_TEXT ("%d bytes\n"),
284 size,
285 msgsize),
286 -1);
288 // Create message block for the whole file. Ensure that it is
289 // aligned to properly handle the double.
290 ACE_Message_Block mb (ACE_CDR::MAX_ALIGNMENT + msgsize);
291 ACE_CDR::mb_align (&mb);
293 mb.copy (buffer, msgsize);
295 // Create CDR input stream from the message block.
297 ACE_InputCDR input_cdr (&mb);
298 input_cdr.reset_byte_order ((int) byte_order);
300 ACE_DEBUG ((LM_DEBUG,
301 ACE_TEXT ("Reading file %s in %s endian format...\n"),
302 filename,
303 ACE_CDR_BYTE_ORDER ? ACE_TEXT("little") : ACE_TEXT("big")));
305 CDR_Test temp;
307 // Demarshal the data from the input CDR stream into the
308 // <CDR_Test> object.
309 input_cdr >> temp;
311 *ace_file_stream::instance ()->output_file () << temp;
313 if (!(temp == cdr_test))
314 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Data mismatch across file\n")));
317 return 0;
320 static void
321 usage (const ACE_TCHAR *cmd)
323 ACE_ERROR ((LM_ERROR,
324 ACE_TEXT ("Usage: %s ")
325 ACE_TEXT ("[-f filename [-w|-r]]"),
326 cmd));
327 ACE_OS::exit (1);
330 // Main function
333 run_main (int argc, ACE_TCHAR *argv[])
335 ACE_START_TEST (ACE_TEXT ("CDR_File_Test"));
337 ACE_DEBUG ((LM_DEBUG,
338 ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"),
339 ACE::major_version (),
340 ACE::minor_version (),
341 ACE::beta_version ()));
343 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("f:rw"));
344 int opt;
345 int reading = 1;
346 int writing = 1;
347 ACE_TCHAR* fn = 0;
348 while ((opt = get_opt ()) != EOF)
350 switch (opt)
352 case 'f':
353 fn = get_opt.opt_arg ();
354 break;
355 case 'r':
356 writing = 0;
357 break;
358 case 'w':
359 reading = 0;
360 break;
361 case '?':
362 default:
363 usage (ACE_TEXT("CDR_File_Test"));
367 if ((!reading || !writing) && fn == 0)
368 usage (ACE_TEXT("CDR_File_Test"));
370 if (!reading && !writing)
371 usage (ACE_TEXT("CDR_File_Test"));
373 // Create a temporary filename.
374 ACE_FILE_Addr filename (ACE_sap_any_cast (ACE_FILE_Addr &));
375 if (fn != 0)
376 filename.set (fn);
379 ACE_FILE_Connector connector;
380 ACE_FILE_IO file;
382 // Open up the file.
383 if (connector.connect (file,
384 filename,
386 ACE_Addr::sap_any,
388 ((writing) ? (O_RDWR | O_CREAT) : O_RDONLY),
389 ACE_DEFAULT_FILE_PERMS) == -1)
390 ACE_ERROR_RETURN ((LM_ERROR,
391 ACE_TEXT ("connect failed for %p\n"),
392 filename.get_path_name ()),
395 CDR_Test cdr_test ('a',
396 0x00ff,
397 0xaabbccdd,
398 0x01234567,
399 1.54321f,
400 1.12345);
402 if (writing)
404 // write the file.
405 run_test (1,
406 file,
407 filename.get_path_name (),
408 cdr_test);
411 if (reading)
413 // read the file.
414 run_test (0,
415 file,
416 filename.get_path_name (),
417 cdr_test);
420 if (fn == 0)
422 file.close ();
423 if (file.unlink () == -1)
424 ACE_ERROR_RETURN ((LM_ERROR,
425 ACE_TEXT ("unlink failed for %p\n"),
426 filename.get_path_name ()),
430 ACE_END_TEST;
431 return 0;
434 #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
437 run_main (int, ACE_TCHAR *[])
439 ACE_START_TEST (ACE_TEXT ("CDR_File_Test"));
441 ACE_ERROR ((LM_INFO,
442 ACE_TEXT ("iostreams not supported on this platform\n")));
444 ACE_END_TEST;
445 return 0;
448 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */