summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspark <spark@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-03-08 22:29:36 +0000
committerspark <spark@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-03-08 22:29:36 +0000
commit9919060605e676f574dc330dc04b92efdee1f660 (patch)
treeff6f39c9d66991d9560e6921d045d94b20ad4821
parent8fb4f68d77f8e6ff20fc6443b15285d787447f72 (diff)
downloadATCD-9919060605e676f574dc330dc04b92efdee1f660.tar.gz
A new class to convert command line parameter type between char and wchar_t.
-rw-r--r--ace/Argv_Type_Converter.cpp165
-rw-r--r--ace/Argv_Type_Converter.h144
-rw-r--r--ace/Argv_Type_Converter.inl39
3 files changed, 348 insertions, 0 deletions
diff --git a/ace/Argv_Type_Converter.cpp b/ace/Argv_Type_Converter.cpp
new file mode 100644
index 00000000000..6ff2286f567
--- /dev/null
+++ b/ace/Argv_Type_Converter.cpp
@@ -0,0 +1,165 @@
+// $Id$
+
+#include "ace/Argv_Type_Converter.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Argv_Type_Converter.inl"
+#endif // __ACE_INLINE__
+
+
+#if defined (ACE_USES_WCHAR)
+ACE_Argv_Type_Converter::ACE_Argv_Type_Converter(int& argc, wchar_t** argv)
+: saved_argc_(argc)
+, char_argv_(0)
+, wchar_argv_(argv)
+, before_pass_argc_(argc)
+, original_type_(true)
+, wchar_passed_(false)
+, char_passed_(false)
+{
+ initialize();
+
+ for (int i = 0; i < argc; ++i) {
+ char_argv_[i] = ACE_OS::strdup(ACE_TEXT_ALWAYS_CHAR(argv[i]));
+ }
+}
+#endif // ACE_USES_WCHAR
+
+
+ACE_Argv_Type_Converter::ACE_Argv_Type_Converter(int& argc, char** argv)
+: saved_argc_(argc)
+, char_argv_(argv)
+#if defined (ACE_USES_WCHAR)
+, wchar_argv_(0)
+, before_pass_argc_(argc)
+, original_type_(false)
+, wchar_passed_(false)
+, char_passed_(false)
+{
+ initialize();
+
+ for (int i = 0; i < argc; ++i) {
+ wchar_argv_[i] = ACE_OS::strdup(ACE_TEXT_ANTI_TO_TCHAR(argv[i]));
+ }
+}
+#else
+{
+}
+#endif // ACE_USES_WCHAR
+
+
+ACE_Argv_Type_Converter::~ACE_Argv_Type_Converter(void)
+{
+#if defined (ACE_USES_WCHAR)
+ // selectively delete the 'copy' of argv
+ if (original_type_) {
+ // if original type is wchar_t
+ if (char_passed_) {
+ align_wchar_with_char();
+ }
+ for (int i = 0; i < saved_argc_; ++i) {
+ delete [] char_argv_[i];
+ }
+ delete [] char_argv_;
+ }
+ else {
+ // if original type is char
+ if (wchar_passed_) {
+ align_char_with_wchar();
+ }
+ for (int i = 0; i < saved_argc_; ++i) {
+ delete [] wchar_argv_[i];
+ }
+ delete [] wchar_argv_;
+ }
+#endif // ACE_USES_WCHAR
+}
+
+
+#if defined (ACE_USES_WCHAR)
+void ACE_Argv_Type_Converter::initialize()
+{
+ if (original_type_) { // make a copy of argv in 'char' type
+ // Create one more argv entry than original argc for the NULL.
+ ACE_NEW(char_argv_, char*[saved_argc_ + 1]);
+ char_argv_[saved_argc_] = 0; // last entry of argv is always a NULL
+ }
+ else { // make a copy of argv in 'wchar_t' type
+ ACE_NEW(wchar_argv_, wchar_t*[saved_argc_ + 1]);
+ wchar_argv_[saved_argc_] = 0;
+ }
+}
+
+
+void ACE_Argv_Type_Converter::align_char_with_wchar()
+{
+ int wchar_argv_index = 0;
+ wchar_t* match_argv = wchar_argv_[0]; // pick the initial entry
+
+ while (wchar_argv_index < saved_argc_) {
+ // if n'th entries of both argv lists are different
+ if (ACE_OS::strcmp(char_argv_[wchar_argv_index], ACE_TEXT_ALWAYS_CHAR(match_argv)) != 0) {
+ // loop through the wchar argv list entries that are after wchar_argv_index
+ for (int i = wchar_argv_index + 1; i < before_pass_argc_; ++i) {
+ if (ACE_OS::strcmp(char_argv_[i], ACE_TEXT_ALWAYS_CHAR(match_argv)) == 0) {
+ // swap the pointers in the char argv list
+ char* temp = char_argv_[wchar_argv_index];
+ char_argv_[wchar_argv_index] = char_argv_[i];
+ char_argv_[i] = temp;
+ break;
+ }
+ }
+ }
+
+ // move to the next wchar argv list entry
+ match_argv = wchar_argv_[++wchar_argv_index];
+ }
+
+ cleanup();
+}
+
+
+void ACE_Argv_Type_Converter::align_wchar_with_char()
+{
+ int char_argv_index = 0;
+ char* match_argv = char_argv_[0]; // pick the initial entry
+
+ while (char_argv_index < saved_argc_) {
+ // if n'th entries of both argv lists are different
+ if (ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(wchar_argv_[char_argv_index]), match_argv) != 0) {
+ // loop through the wchar argv list entries that are after wchar_argv_index
+ for (int i = char_argv_index + 1; i < before_pass_argc_; ++i) {
+ if (ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(wchar_argv_[i]), match_argv) == 0) {
+ // swap the pointers in the char argv list
+ wchar_t* temp = wchar_argv_[char_argv_index];
+ wchar_argv_[char_argv_index] = wchar_argv_[i];
+ wchar_argv_[i] = temp;
+ break;
+ }
+ }
+ }
+
+ // move to the next wchar argv list entry
+ match_argv = char_argv_[++char_argv_index];
+ }
+
+ cleanup();
+}
+
+
+void ACE_Argv_Type_Converter::cleanup()
+{
+ for (int i = saved_argc_; i < before_pass_argc_; ++i) {
+ delete [] char_argv_[i];
+ delete [] wchar_argv_[i];
+
+ char_argv_[i] = 0;
+ wchar_argv_[i] = 0;
+ }
+
+ before_pass_argc_ = saved_argc_;
+
+ wchar_passed_ = false;
+ char_passed_ = false;
+}
+#endif // ACE_USES_WCHAR
diff --git a/ace/Argv_Type_Converter.h b/ace/Argv_Type_Converter.h
new file mode 100644
index 00000000000..8559cb8acc6
--- /dev/null
+++ b/ace/Argv_Type_Converter.h
@@ -0,0 +1,144 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Argv_Type_Converter.h
+ *
+ * $Id$
+ *
+ * @author Si Mong Park <spark@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ACE_Argv_Type_Converter_h
+#define ACE_Argv_Type_Converter_h
+
+#include "ace/pre.h"
+#include "ace/OS.h"
+
+
+/**
+ * @class ACE_Argv_Type_Converter
+ *
+ * @brief To convert 'char' input/command line parameter to 'wchar_t'.
+ *
+ * This class is to convert 'char' type command line paramter to
+ * wide-character (wchar_t) format and stores the copy of it.
+ * This is useful for all classes that use 'char**' argv but cannot
+ * be converted into 'ACE_TCHAR**' version.
+ * Note that the converted data will be lost upon destruction, so
+ * classes should use this class as their data member.
+ */
+class ACE_Export ACE_Argv_Type_Converter
+{
+public:
+ /**
+ * Ctor accepts integer argc and 'char' type argv.
+ */
+ ACE_Argv_Type_Converter(int& argc, char** argv);
+
+#if defined (ACE_USES_WCHAR)
+ /**
+ * Ctor accepts integer argc and 'wchar_t' type argv.
+ */
+ ACE_Argv_Type_Converter(int& argc, wchar_t** argv);
+#endif // ACE_USES_WCHAR
+
+ /**
+ * Dtor will delete all stored data.
+ */
+ ~ACE_Argv_Type_Converter(void);
+
+ /**
+ * Returns the pointer of converted command line.
+ */
+ ACE_TCHAR** get_TCHAR_argv(void);
+
+ /**
+ * Returns the pointer of ASCII (char) command line.
+ */
+ char** get_ASCII_argv(void);
+
+ /**
+ * Returns the number of sub paramters (argc).
+ */
+ int& get_argc(void);
+
+private:
+ /**
+ * Copy Ctor should not be used.
+ */
+ ACE_Argv_Type_Converter(ACE_Argv_Type_Converter&);
+
+ /**
+ * '=' operator should not be used.
+ */
+ ACE_Argv_Type_Converter operator = (ACE_Argv_Type_Converter&);
+
+#if defined (ACE_USES_WCHAR)
+ /**
+ * Perform common initialization for two Ctor's.
+ */
+ void initialize();
+
+ /**
+ * Align all entries in the char type argv list with wchar_t type argv list.
+ */
+ void align_char_with_wchar();
+
+ /**
+ * Align all entries in the wchar_t type argv list with char type argv list.
+ */
+ void align_wchar_with_char();
+
+ /**
+ * Clean up removed (comsumed) argv entries and reset the pass flags.
+ */
+ void cleanup();
+#endif // ACE_USES_WCHAR
+
+ /**
+ * Original number of input paramter, same as 'argc'.
+ */
+ int& saved_argc_;
+
+ /**
+ * Data member pointer that contains converted argv in ACE_ANTI_TCHAR.
+ */
+ char** char_argv_;
+
+#if defined (ACE_USES_WCHAR)
+ /**
+ * Data member pointer that contains converted argv in ACE_TCHAR.
+ */
+ wchar_t** wchar_argv_;
+
+ /**
+ * argc value before any argv has been passed.
+ */
+ int before_pass_argc_;
+
+ /**
+ * FALSE represents original argv passed in is char, and TRUE represents wchar_t.
+ * Boolean type could be used for this, but used integer for old compiler issue.
+ */
+ const bool original_type_;
+
+ /**
+ * TRUE indicates wchar_t type argv has been passed.
+ */
+ bool wchar_passed_;
+
+ /**
+ * TRUE indicates char type argv has been passed.
+ */
+ bool char_passed_;
+#endif // ACE_USES_WCHAR
+};
+
+#if defined (__ACE_INLINE__)
+#include "ace/Argv_Type_Converter.inl"
+#endif // __ACE_INLINE__
+
+#include "ace/post.h"
+
+#endif // ACE_Argv_Type_Converter_h
diff --git a/ace/Argv_Type_Converter.inl b/ace/Argv_Type_Converter.inl
new file mode 100644
index 00000000000..f29cd705e99
--- /dev/null
+++ b/ace/Argv_Type_Converter.inl
@@ -0,0 +1,39 @@
+// $Id$
+
+
+ACE_INLINE ACE_TCHAR**
+ACE_Argv_Type_Converter::get_TCHAR_argv(void)
+{
+#if defined (ACE_USES_WCHAR)
+ if (char_passed_) {
+ align_wchar_with_char();
+ }
+
+ wchar_passed_ = true;
+ return wchar_argv_;
+#else
+ return char_argv_;
+#endif // ACE_USES_WCHAR
+}
+
+
+ACE_INLINE char**
+ACE_Argv_Type_Converter::get_ASCII_argv(void)
+{
+#if defined (ACE_USES_WCHAR)
+ if (wchar_passed_) {
+ align_char_with_wchar();
+ }
+
+ char_passed_ = true;
+#endif // ACE_USES_WCHAR
+
+ return char_argv_;
+}
+
+
+ACE_INLINE int&
+ACE_Argv_Type_Converter::get_argc(void)
+{
+ return saved_argc_;
+}