summaryrefslogtreecommitdiff
path: root/ACE/examples/Mem_Map
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/Mem_Map')
-rw-r--r--ACE/examples/Mem_Map/IO-tests/.cvsignore2
-rw-r--r--ACE/examples/Mem_Map/IO-tests/IO_Test.cpp240
-rw-r--r--ACE/examples/Mem_Map/IO-tests/IO_Test.h100
-rw-r--r--ACE/examples/Mem_Map/IO-tests/Makefile.am40
-rw-r--r--ACE/examples/Mem_Map/IO-tests/Mem_Map_IO_Tests.mpc6
-rw-r--r--ACE/examples/Mem_Map/IO-tests/test_io.cpp211
-rw-r--r--ACE/examples/Mem_Map/Makefile.am14
-rw-r--r--ACE/examples/Mem_Map/file-reverse/.cvsignore1
-rw-r--r--ACE/examples/Mem_Map/file-reverse/Makefile.am38
-rw-r--r--ACE/examples/Mem_Map/file-reverse/Mem_Map_File_Reverse.mpc7
-rw-r--r--ACE/examples/Mem_Map/file-reverse/file-reverse.cpp59
11 files changed, 718 insertions, 0 deletions
diff --git a/ACE/examples/Mem_Map/IO-tests/.cvsignore b/ACE/examples/Mem_Map/IO-tests/.cvsignore
new file mode 100644
index 00000000000..80ea1892dab
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/.cvsignore
@@ -0,0 +1,2 @@
+test_io
+test_io
diff --git a/ACE/examples/Mem_Map/IO-tests/IO_Test.cpp b/ACE/examples/Mem_Map/IO-tests/IO_Test.cpp
new file mode 100644
index 00000000000..86f2596098e
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/IO_Test.cpp
@@ -0,0 +1,240 @@
+// $Id$
+
+#if !defined(_WIN32)
+
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Mem_Map.h"
+#include "ace/Log_Msg.h"
+#include "IO_Test.h"
+
+ACE_RCSID(IO_tests, IO_Test, "$Id$")
+
+
+
+IO_Test::IO_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : name_ (name), tm_ (tm)
+{
+}
+
+IO_Test::~IO_Test (void)
+{
+}
+
+const char *
+IO_Test::name (void)
+{
+ return this->name_;
+}
+
+Slow_Read_Write_Test::Slow_Read_Write_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Slow_Read_Write_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ ACE_HANDLE ifd = fileno (input_fp);
+ ACE_HANDLE ofd = fileno (output_fp);
+
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ {
+ char c;
+
+ while (ACE_OS::read (ifd, &c, sizeof c) > 0)
+ ::write (ofd, &c, sizeof c);
+
+ ACE_OS::lseek (ifd, 0, SEEK_SET);
+ ACE_OS::lseek (ofd, 0, SEEK_SET);
+ }
+
+ this->tm_.stop ();
+ return 0;
+}
+
+Stdio_Test::Stdio_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Stdio_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ {
+ int c;
+
+ while ((c = getc (input_fp)) != EOF)
+ putc (c, output_fp);
+
+ ACE_OS::rewind (input_fp);
+ ACE_OS::rewind (output_fp);
+ }
+ this->tm_.stop ();
+ return 0;
+}
+
+Block_Read_Write_Test::Block_Read_Write_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Block_Read_Write_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ int ifd = fileno (input_fp);
+ int ofd = fileno (output_fp);
+
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ {
+ char buf[BUFSIZ];
+ ssize_t n;
+
+ while ((n = ACE_OS::read (ifd,
+ buf,
+ sizeof buf)) > 0)
+ ::write (ofd, buf, n);
+
+ ACE_OS::lseek (ifd, 0, SEEK_SET);
+ ACE_OS::lseek (ofd, 0, SEEK_SET);
+ }
+
+ this->tm_.stop ();
+ return 0;
+}
+
+Block_Fread_Fwrite_Test::Block_Fread_Fwrite_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Block_Fread_Fwrite_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ {
+ char buf[BUFSIZ];
+ ssize_t n;
+
+ while ((n = ACE_OS::fread (buf,
+ 1,
+ sizeof buf,
+ input_fp)) != 0)
+ ::fwrite (buf, n, 1, output_fp);
+
+ ACE_OS::rewind (input_fp);
+ ACE_OS::rewind (output_fp);
+ }
+
+ this->tm_.stop ();
+ return 0;
+}
+
+Mmap1_Test::Mmap1_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Mmap1_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ ACE_Mem_Map map_input (fileno (input_fp));
+ void *src = map_input.addr ();
+
+ if (src == MAP_FAILED)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%C"), this->name ()), -1);
+ else
+ {
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ {
+ if (ACE_OS::write (fileno (output_fp),
+ src,
+ map_input.size ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%C"),
+ this->name ()),
+ -1);
+ ACE_OS::lseek (fileno (output_fp),
+ 0,
+ SEEK_SET);
+ }
+
+ this->tm_.stop ();
+ }
+
+ if (map_input.unmap () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%C"),
+ this->name ()),
+ -1);
+ else
+ return 0;
+}
+
+Mmap2_Test::Mmap2_Test (const char *name,
+ ACE_Profile_Timer &tm)
+ : IO_Test (name, tm)
+{
+}
+
+int
+Mmap2_Test::run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp)
+{
+ ACE_Mem_Map map_input (fileno (input_fp));
+ int size = map_input.size ();
+ ACE_Mem_Map map_output (fileno (output_fp),
+ size,
+ PROT_WRITE,
+ MAP_SHARED);
+ void *src = map_input.addr ();
+ void *dst = map_output.addr ();
+
+ if (src == MAP_FAILED || dst == MAP_FAILED)
+ return -1;
+ else
+ {
+ this->tm_.start ();
+
+ while (--iterations >= 0)
+ ACE_OS::memcpy (dst, src, size);
+
+ this->tm_.stop ();
+ }
+
+ if (map_input.unmap () == -1
+ || map_output.unmap () == -1)
+ return -1;
+ else
+ return 0;
+}
+#endif
diff --git a/ACE/examples/Mem_Map/IO-tests/IO_Test.h b/ACE/examples/Mem_Map/IO-tests/IO_Test.h
new file mode 100644
index 00000000000..3c130b32363
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/IO_Test.h
@@ -0,0 +1,100 @@
+/* -*- C++ -*- */
+// $Id$
+
+/* Class hierarchy for the File I/O tests. */
+
+#include "ace/Profile_Timer.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/* Base class for all the File I/O tests. */
+
+class IO_Test
+{
+public:
+
+ // Initialize the test name
+ IO_Test (const char *name,
+ ACE_Profile_Timer &tm);
+
+ // Destructor.
+ virtual ~IO_Test (void);
+
+ // Return the name of the test
+ const char *name (void);
+
+ // Execute the IO test (note this is a pure virtual function...)
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp) = 0;
+
+protected:
+ // Name of the test
+ const char *name_;
+
+ // Reference to a timer
+ ACE_Profile_Timer &tm_;
+};
+
+class Slow_Read_Write_Test : public IO_Test
+{
+public:
+ Slow_Read_Write_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
+class Stdio_Test : public IO_Test
+{
+public:
+ Stdio_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
+class Block_Read_Write_Test : public IO_Test
+{
+public:
+ Block_Read_Write_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
+class Block_Fread_Fwrite_Test : public IO_Test
+{
+public:
+ Block_Fread_Fwrite_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
+class Mmap1_Test : public IO_Test
+{
+public:
+ Mmap1_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
+class Mmap2_Test : public IO_Test
+{
+public:
+ Mmap2_Test (const char *name,
+ ACE_Profile_Timer &tm);
+ virtual int run_test (int iterations,
+ FILE *input_fp,
+ FILE *output_fp);
+};
+
diff --git a/ACE/examples/Mem_Map/IO-tests/Makefile.am b/ACE/examples/Mem_Map/IO-tests/Makefile.am
new file mode 100644
index 00000000000..9a6e3638c29
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/Makefile.am
@@ -0,0 +1,40 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+
+## Makefile.Mem_Map_IO_Tests.am
+
+if !BUILD_ACE_FOR_TAO
+noinst_PROGRAMS = test_io
+
+test_io_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+test_io_SOURCES = \
+ IO_Test.cpp \
+ test_io.cpp \
+ IO_Test.h
+
+test_io_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/examples/Mem_Map/IO-tests/Mem_Map_IO_Tests.mpc b/ACE/examples/Mem_Map/IO-tests/Mem_Map_IO_Tests.mpc
new file mode 100644
index 00000000000..6e2bcc9f3aa
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/Mem_Map_IO_Tests.mpc
@@ -0,0 +1,6 @@
+// -*- MPC -*-
+// $Id$
+
+project : aceexe {
+ avoids += ace_for_tao
+}
diff --git a/ACE/examples/Mem_Map/IO-tests/test_io.cpp b/ACE/examples/Mem_Map/IO-tests/test_io.cpp
new file mode 100644
index 00000000000..b60401cc813
--- /dev/null
+++ b/ACE/examples/Mem_Map/IO-tests/test_io.cpp
@@ -0,0 +1,211 @@
+// $Id$
+
+// Test program for different methods of copying files.
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/ACE.h"
+#include "ace/Profile_Timer.h"
+#include "ace/Get_Opt.h"
+#include "ace/Signal.h"
+#include "ace/Log_Msg.h"
+#include "IO_Test.h"
+
+ACE_RCSID(IO_tests, test_io, "$Id$")
+
+#if !defined(_WIN32)
+
+// Name of program.
+static const ACE_TCHAR *program_name;
+
+// Name of default input file.
+static const ACE_TCHAR *input_filename = ACE_TEXT ("/usr/dict/words");
+
+// Name of default output file.
+static const ACE_TCHAR *output_filename = ACE_TEXT ("/tmp/foo");
+
+// Check if removing output file upon completion...
+static int remove_output = 1;
+
+// Count of the number of iterations to run the tests.
+static int iteration_count = 100;
+
+// Profiler used to keep track of file I/O time.
+static ACE_Profile_Timer profile_timer;
+
+// Explain usage and exit.
+
+static void
+print_usage_and_die (void)
+{
+ ACE_OS::fprintf (stderr, "usage: %s"
+ " [-i input_file] [-o output_file] [-n iteration_count] [-r]\n",
+ ACE_TEXT_ALWAYS_CHAR (program_name));
+ ACE_OS::exit (1);
+}
+
+// Clean up the output file on exit from a signal.
+
+extern "C" void
+cleanup (int = 0)
+{
+ if (remove_output)
+ ACE_OS::unlink (output_filename);
+ ACE_OS::exit (0);
+}
+
+// Parse the command-line arguments and set options.
+
+static void
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("i:n:o:r"));
+
+ for (int c; ((c = get_opt ()) != -1); )
+ switch (c)
+ {
+ case 'i':
+ input_filename = get_opt.opt_arg ();
+ break;
+ case 'n':
+ iteration_count = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ case 'o':
+ output_filename = get_opt.opt_arg ();
+ break;
+ case 'r':
+ remove_output = 0;
+ break;
+ default:
+ print_usage_and_die ();
+ break;
+ }
+}
+
+// Vector of pointers to derived classes that inherit from IO_Test
+// base class.
+
+static IO_Test *test_vector[100];
+
+static int
+run_tests (int iterations, FILE *input_fp, FILE *output_fp)
+{
+ int i = 0;
+
+ ACE_NEW_RETURN (test_vector[i],
+ Stdio_Test ("Stdio_Test",
+ profile_timer),
+ -1);
+ i++;
+ ACE_NEW_RETURN (test_vector[i],
+ Block_Fread_Fwrite_Test ("Block_Fread_Fwrite_Test",
+ profile_timer),
+ -1);
+ i++;
+ ACE_NEW_RETURN (test_vector[i],
+ Block_Read_Write_Test ("Block_Read_Write_Test",
+ profile_timer),
+ -1);
+ i++;
+ ACE_NEW_RETURN (test_vector[i],
+ Mmap1_Test ("Mmap1_Test",
+ profile_timer),
+ -1);
+ i++;
+ ACE_NEW_RETURN (test_vector[i],
+ Mmap2_Test ("Mmap2_Test",
+ profile_timer),
+ -1);
+ i++;
+ ACE_NEW_RETURN (test_vector[i],
+ Slow_Read_Write_Test ("Slow_Read_Write_Test",
+ profile_timer),
+ -1);
+ i++;
+
+ test_vector[i] = (IO_Test *) 0;
+
+ for (i = 0; test_vector[i] != 0; i++)
+ {
+ ACE_HANDLE hfile = fileno (output_fp);
+ if (ACE_OS::ftruncate (hfile, 0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%s\n"),
+ ACE_TEXT ("ftruncate")),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("--------------------\n")
+ ACE_TEXT ("starting %C for %d iterations(s):\n"),
+ test_vector[i]->name (),
+ iterations));
+
+ test_vector[i]->run_test (iterations,
+ input_fp,
+ output_fp);
+
+ ACE_Profile_Timer::ACE_Elapsed_Time et;
+ profile_timer.elapsed_time (et);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("wallclock time = %f, user time = %f, system time = %f\n"),
+ et.real_time,
+ et.user_time,
+ et.system_time));
+
+ delete test_vector[i];
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("--------------------\n")));
+ return 0;
+}
+
+int
+main (int argc, ACE_TCHAR *argv[])
+{
+ program_name = ACE::basename (argv[0],
+ ACE_DIRECTORY_SEPARATOR_CHAR);
+ parse_args (argc, argv);
+
+ ACE_Sig_Action sa ((ACE_SignalHandler) cleanup, SIGINT);
+ ACE_UNUSED_ARG (sa);
+
+ FILE *input_fp =
+ ACE_OS::fopen (input_filename, ACE_TEXT ("r"));
+ FILE *output_fp =
+ ACE_OS::fopen (output_filename, ACE_TEXT ("w+"));
+
+ if (input_fp == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ input_filename),
+ -1);
+
+ if (output_fp == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ output_filename),
+ -1);
+
+ ACE_OS::unlink (output_filename);
+
+ if (run_tests (iteration_count,
+ input_fp,
+ output_fp) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("run_tests")),
+ -1);
+
+ if (ACE_OS::fclose (input_fp) == -1
+ || ACE_OS::fclose (output_fp) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("fclose")),
+ -1);
+ cleanup ();
+ return 0;
+}
+#else
+int ACE_TMAIN (int, ACE_TCHAR*[]) {
+ // not supported on win32
+ return 0;
+}
+#endif
diff --git a/ACE/examples/Mem_Map/Makefile.am b/ACE/examples/Mem_Map/Makefile.am
new file mode 100644
index 00000000000..9d8830d2147
--- /dev/null
+++ b/ACE/examples/Mem_Map/Makefile.am
@@ -0,0 +1,14 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+SUBDIRS = \
+ IO-tests \
+ file-reverse
+
diff --git a/ACE/examples/Mem_Map/file-reverse/.cvsignore b/ACE/examples/Mem_Map/file-reverse/.cvsignore
new file mode 100644
index 00000000000..cf791234c5e
--- /dev/null
+++ b/ACE/examples/Mem_Map/file-reverse/.cvsignore
@@ -0,0 +1 @@
+file-reverse
diff --git a/ACE/examples/Mem_Map/file-reverse/Makefile.am b/ACE/examples/Mem_Map/file-reverse/Makefile.am
new file mode 100644
index 00000000000..02a081a6c88
--- /dev/null
+++ b/ACE/examples/Mem_Map/file-reverse/Makefile.am
@@ -0,0 +1,38 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+
+## Makefile.Mem_Map_File_Reverse.am
+
+if !BUILD_ACE_FOR_TAO
+noinst_PROGRAMS = file-reverse
+
+file_reverse_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+file_reverse_SOURCES = \
+ file-reverse.cpp
+
+file_reverse_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/examples/Mem_Map/file-reverse/Mem_Map_File_Reverse.mpc b/ACE/examples/Mem_Map/file-reverse/Mem_Map_File_Reverse.mpc
new file mode 100644
index 00000000000..368866edb73
--- /dev/null
+++ b/ACE/examples/Mem_Map/file-reverse/Mem_Map_File_Reverse.mpc
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project : aceexe {
+ avoids += ace_for_tao
+ exename = file-reverse
+}
diff --git a/ACE/examples/Mem_Map/file-reverse/file-reverse.cpp b/ACE/examples/Mem_Map/file-reverse/file-reverse.cpp
new file mode 100644
index 00000000000..2e64c272c12
--- /dev/null
+++ b/ACE/examples/Mem_Map/file-reverse/file-reverse.cpp
@@ -0,0 +1,59 @@
+// $Id$
+
+// Print a file in reverse by using the ACE memory mapped file
+// wrapper. It is SO easy to do compared with alternatives!
+
+#include "ace/OS_main.h"
+#include "ace/Mem_Map.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID(file_reverse, file_reverse, "$Id$")
+
+static void
+putline (const char *s)
+{
+ while (putchar (*s++) != '\n')
+ continue;
+}
+
+static void
+print_array_in_reverse (char *array,
+ int size)
+{
+ if (size <= 0)
+ return;
+
+ size--;
+
+ if (array[size] == '\0')
+ array[size] = '\n';
+
+ while (--size >= 0)
+ if (array[size] == '\n')
+ putline (array + size + 1);
+
+ putline (array);
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR **argv)
+{
+ ACE_LOG_MSG->open (argv[0]);
+
+ if (argc != 2)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %n file\n"),
+ -1);
+
+ ACE_Mem_Map mmap;
+
+ if (mmap.map (argv[1], -1, O_RDWR) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%n: %p\n",
+ "mmap"),
+ -1);
+
+ print_array_in_reverse ((char *) mmap.addr (),
+ mmap.size ());
+ return 0;
+}