diff options
author | spark <spark@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-03-08 22:29:36 +0000 |
---|---|---|
committer | spark <spark@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-03-08 22:29:36 +0000 |
commit | 9919060605e676f574dc330dc04b92efdee1f660 (patch) | |
tree | ff6f39c9d66991d9560e6921d045d94b20ad4821 | |
parent | 8fb4f68d77f8e6ff20fc6443b15285d787447f72 (diff) | |
download | ATCD-9919060605e676f574dc330dc04b92efdee1f660.tar.gz |
A new class to convert command line parameter type between char and wchar_t.
-rw-r--r-- | ace/Argv_Type_Converter.cpp | 165 | ||||
-rw-r--r-- | ace/Argv_Type_Converter.h | 144 | ||||
-rw-r--r-- | ace/Argv_Type_Converter.inl | 39 |
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_; +} |