searchengine/util/cpixtools/inc/public/cpixstrtools.h
changeset 0 671dee74050a
child 5 32c1e5a1c52c
equal deleted inserted replaced
-1:000000000000 0:671dee74050a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 #ifndef CPIXTOOLS_CPIXSTRTOOLS_H_
       
    18 #define CPIXTOOLS_CPIXSTRTOOLS_H_
       
    19 
       
    20 #include <list>
       
    21 #include <string>
       
    22 
       
    23 namespace Cpt
       
    24 {
       
    25 
       
    26 
       
    27     /**
       
    28      * Breaks down a string on certain delimiters.
       
    29      *
       
    30      * @param orig the original string
       
    31      *
       
    32      * @param delimiters the zero terminated string containing the
       
    33      * delimiter characters
       
    34      *
       
    35      * @param target the list to put the substrings into
       
    36      */
       
    37     void splitstring(const char             * orig,
       
    38                      const char             * delimiters,
       
    39                      std::list<std::string> & target);
       
    40 
       
    41 
       
    42     /**
       
    43      * @param first the first string - this should be the substring of
       
    44      * the second or equal to it
       
    45      *
       
    46      * @param second the second string
       
    47      *
       
    48      * @return true if the first string is the substring of the second
       
    49      * or equal to it, false otherwise
       
    50      */
       
    51     template<typename CTYPE>
       
    52     bool issubstroforequal(const CTYPE * first,
       
    53                            const CTYPE * second)
       
    54     {
       
    55         for ( ; 
       
    56               *first != static_cast<CTYPE>(0) 
       
    57                   && *second != static_cast<CTYPE>(0) 
       
    58                   && *first == *second;
       
    59               ++first, ++second)
       
    60             ;
       
    61         
       
    62         return *first == static_cast<CTYPE>(0);
       
    63     }
       
    64 
       
    65 
       
    66     /**
       
    67      * Poor man's substitute to OpenC's leaking printf("%f") formatting 
       
    68      * function, because printf float formatting leak memory. 
       
    69      * 
       
    70      * NOTE: Last number WILL NOT be rounded properly. It will 
       
    71      * be rounded up, when it should be rounded to closest.
       
    72      */
       
    73     int wsnprintdouble(wchar_t* buf, size_t n, double number, int decimals);
       
    74 
       
    75 
       
    76 
       
    77     /**
       
    78      * Exception class to tell about conversion failures.
       
    79      */
       
    80     class ConversionExc : public std::exception
       
    81     {
       
    82     private:
       
    83         //
       
    84         // private members
       
    85         //
       
    86 
       
    87         std::string    what_;
       
    88 
       
    89     public:
       
    90         //
       
    91         // public operators
       
    92         //
       
    93 
       
    94         /**
       
    95          * Overriden from std::exception
       
    96          */
       
    97         virtual const char * what() const throw();
       
    98 
       
    99 
       
   100         //
       
   101         // Lifecycle management
       
   102         //
       
   103             
       
   104         /**
       
   105          * Constructs this exception with printf style format string
       
   106          * and potential detail arguments.
       
   107          */
       
   108         ConversionExc(const char * format,
       
   109                       ...);
       
   110     };
       
   111 
       
   112 
       
   113 
       
   114     /**
       
   115      * A very simple lifetime mgmt class for arrays. (std::auto_ptr
       
   116      * should not be used on C-strings or arrays of a type, as it uses
       
   117      * delete and not delete[] to clean up.
       
   118      */
       
   119     template<typename T>
       
   120     class auto_array
       
   121     {
       
   122     private:
       
   123         //
       
   124         // private members
       
   125         //
       
   126         T * p_;
       
   127 
       
   128 
       
   129         // no value semantics
       
   130         auto_array(const auto_array &);
       
   131         auto_array & operator=(const auto_array &);
       
   132 
       
   133     public:
       
   134         //
       
   135         // public operators
       
   136         //
       
   137 
       
   138         
       
   139         /**
       
   140          * Gives up ownership of stored array to the caller.
       
   141          *
       
   142          * @returns the pointer to the array - the caller will have to
       
   143          * manage it from now on.
       
   144          */
       
   145         T * release();
       
   146 
       
   147 
       
   148         /**
       
   149          * Resets the array owned by this, any old arrays are
       
   150          * discarded.
       
   151          */
       
   152         void reset(T * p);
       
   153         
       
   154 
       
   155         /**
       
   156          * @returns the stored array - ownership is not transferred
       
   157          */
       
   158         T * get();
       
   159 
       
   160 
       
   161         /**
       
   162          * Default constructor
       
   163          */
       
   164         auto_array();
       
   165 
       
   166 
       
   167         /**
       
   168          * Constructor taking ownership of given array pointer by p.
       
   169          */
       
   170         auto_array(T * p);
       
   171 
       
   172 
       
   173 
       
   174         /**
       
   175          * Named constant for the default (auto) case for string
       
   176          * length parameter in the conversion constructor.
       
   177          *
       
   178          * The value should be max of size_t, and unfortunately
       
   179          * std::numeric_limits<size_t>::max() is no use here as it is
       
   180          * a function providing a value at runtime and not a constant
       
   181          * expression you can use at compile time. So much about the
       
   182          * usefulness of numeric_limits. So, using the fact that
       
   183          * size_t is always an unsigned type, we are going to use -1
       
   184          * cast to size_t as MAX. Bit obscure but should provide the
       
   185          * numerical value for the maximal unsigned number size_t can
       
   186          * represent.
       
   187          */
       
   188         enum { AUTO_STRLEN = static_cast<size_t>(-1) };
       
   189 
       
   190         
       
   191         /**
       
   192          * Constructor for the case when both T and CHAR are character
       
   193          * types but they are not the same (wchar_t, char).
       
   194          *
       
   195          * In this case, auto_array will behave as a simple string
       
   196          * class that was initialized by copying and converting an
       
   197          * original string of different character type.
       
   198          *
       
   199          * @param src a c-style string (char or wchar_t).
       
   200          *
       
   201          * @param length if not AUTO_STRLEN (default value), then
       
   202          * min(length, STRLEN(src)) amount of characters will be
       
   203          * copied to this auto_array instance. STRLEN(src) means
       
   204          * either strlen(src) or wcslen(src) depending on whether CHAR
       
   205          * is plain or wide character.
       
   206          *
       
   207          * NOTE: T has to be also char or wchar_t.
       
   208          *
       
   209          * NOTE: DO NOT attempt to use this constructor in the case
       
   210          * where the types T and CHAR are the same. In that case, the
       
   211          * overloaded constructor will be applied (cf above) by the
       
   212          * C++ compiler and that has completely different ownership
       
   213          * semantics: it does not copy (and convert), it takes
       
   214          * ownership of given string!
       
   215          *
       
   216          * @throws ConversionExc if conversion fails for some reason
       
   217          * (invalid byte sequences etc)
       
   218          */
       
   219         template<typename CHAR>
       
   220         explicit auto_array(const CHAR * src,
       
   221                             size_t       length = AUTO_STRLEN);
       
   222         
       
   223 
       
   224 
       
   225         /**
       
   226          * Destructor
       
   227          */
       
   228         ~auto_array();
       
   229     };
       
   230 
       
   231 
       
   232     /**
       
   233      * @return the used dynamic memory in bytes.
       
   234      */
       
   235     uint32_t getUsedDynamicMemory();
       
   236 
       
   237 
       
   238 
       
   239     /*******************************************************
       
   240      *
       
   241      *  Conversion utilities (wide string -> value types)
       
   242      *
       
   243      */
       
   244 
       
   245     /**
       
   246      * Attempts to convert the given wide string to a value. For
       
   247      * integer types, this will be equivalent to wconvertInteger call.
       
   248      *
       
   249      * @param to the pointer to the value to put the results, must not
       
   250      * be NULL
       
   251      *
       
   252      * @param fromStr wide string, must not be NULL, and it must
       
   253      * contain only the string representation for the value, nothing
       
   254      * more. Failure to eat all of the string and put it to the value
       
   255      * shall result in error.
       
   256      *
       
   257      * @return NULL if successful, and some string about what sort of
       
   258      * value/formatting was attempted on failure.
       
   259      */
       
   260     template<typename V>
       
   261     const char * wconvert(V             * to,
       
   262                           const wchar_t * fromStr);
       
   263 
       
   264 
       
   265     /**
       
   266      * Attempts to convert a given wide string to an integer type
       
   267      * (char, short, integer, long, long long). The string is
       
   268      * interpreted in decimal notation.
       
   269      *
       
   270      * @param to the pointer to the value to put the results, must not
       
   271      * be NULL
       
   272      *
       
   273      * @param fromStr wide string, must not be NULL, and it must
       
   274      * contain only the string representation for the value, nothing
       
   275      * more. Failure to eat all of the string and put it to the value
       
   276      * shall result in error.
       
   277      *
       
   278      * @return NULL if successful, and some string about what sort of
       
   279      * value/formatting was attempted on failure.
       
   280      */
       
   281     template<typename INT>
       
   282     const char * wconvertDecimal(INT           * to,
       
   283                                  const wchar_t * fromStr);
       
   284 
       
   285 
       
   286     /**
       
   287      * Attempts to convert a given wide string to an integer type
       
   288      * (char, short, integer, long, long long). The string is
       
   289      * interpreted generally: 0x prefix will cause hexadecimal
       
   290      * interpretation, 0 prefix octal and otherwise decimal base will
       
   291      * be used.
       
   292      *
       
   293      * @param to the pointer to the value to put the results, must not
       
   294      * be NULL
       
   295      *
       
   296      * @param fromStr wide string, must not be NULL, and it must
       
   297      * contain only the string representation for the value, nothing
       
   298      * more. Failure to eat all of the string and put it to the value
       
   299      * shall result in error.
       
   300      *
       
   301      * @return NULL if successful, and some string about what sort of
       
   302      * value/formatting was attempted on failure.
       
   303      */
       
   304     template<typename INT>
       
   305     const char * wconvertInteger(INT           * to,
       
   306                                  const wchar_t * fromStr);
       
   307 
       
   308 
       
   309     /**
       
   310      * Attempts to convert a given wide string to an unsigned integer
       
   311      * type. Octal base is used.
       
   312      *
       
   313      * @param to the pointer to the value to put the results, must not
       
   314      * be NULL
       
   315      *
       
   316      * @param fromStr wide string, must not be NULL, and it must
       
   317      * contain only the string representation for the value, nothing
       
   318      * more. Failure to eat all of the string and put it to the value
       
   319      * shall result in error.
       
   320      *
       
   321      * @return NULL if successful, and some string about what sort of
       
   322      * value/formatting was attempted on failure.
       
   323      */
       
   324     template<typename INT>
       
   325     const char * wconvertOctal(INT           * to,
       
   326                                const wchar_t * fromStr);
       
   327 
       
   328 
       
   329     /**
       
   330      * Attempts to convert a given wide string to an unsigned integer
       
   331      * type. Decimal base is used.
       
   332      *
       
   333      * @param to the pointer to the value to put the results, must not
       
   334      * be NULL
       
   335      *
       
   336      * @param fromStr wide string, must not be NULL, and it must
       
   337      * contain only the string representation for the value, nothing
       
   338      * more. Failure to eat all of the string and put it to the value
       
   339      * shall result in error.
       
   340      *
       
   341      * @return NULL if successful, and some string about what sort of
       
   342      * value/formatting was attempted on failure.
       
   343      */
       
   344     template<typename INT>
       
   345     const char * wconvertUnsignedInteger(INT           * to,
       
   346                                          const wchar_t * fromStr);
       
   347 
       
   348     /**
       
   349      * Attempts to convert a given wide string to an unsigned integer
       
   350      * type. Hexadecimal base is used.
       
   351      *
       
   352      * @param to the pointer to the value to put the results, must not
       
   353      * be NULL
       
   354      *
       
   355      * @param fromStr wide string, must not be NULL, and it must
       
   356      * contain only the string representation for the value, nothing
       
   357      * more. Failure to eat all of the string and put it to the value
       
   358      * shall result in error.
       
   359      *
       
   360      * @return NULL if successful, and some string about what sort of
       
   361      * value/formatting was attempted on failure.
       
   362      */
       
   363     template<typename INT>
       
   364     const char * wconvertHexadecimal(INT           * to,
       
   365                                      const wchar_t * fromStr);
       
   366 
       
   367 }
       
   368 
       
   369 
       
   370 
       
   371 
       
   372 /**************************************************************
       
   373  *
       
   374  *  IMPLEMENTATION OF TEMPLATES
       
   375  *
       
   376  */
       
   377 namespace Cpt
       
   378 {
       
   379 
       
   380     //////////////////////////////////////////////////////////
       
   381     //
       
   382     // auto_array
       
   383     //
       
   384     template<typename T>
       
   385     T * auto_array<T>::release()
       
   386     {
       
   387         T
       
   388             * rv = p_;
       
   389 
       
   390         p_ = NULL;
       
   391 
       
   392         return rv;
       
   393     }
       
   394 
       
   395 
       
   396     template<typename T>
       
   397     void auto_array<T>::reset(T * p)
       
   398     {
       
   399         if (p_ != p)
       
   400             {
       
   401                 delete[] p_;
       
   402                 p_ = p;
       
   403             }
       
   404     }
       
   405         
       
   406 
       
   407     template<typename T>
       
   408     T * auto_array<T>::get()
       
   409     {
       
   410         return p_;
       
   411     }
       
   412 
       
   413 
       
   414     template<typename T>
       
   415     auto_array<T>::auto_array()
       
   416         : p_(NULL)
       
   417     {
       
   418         ;
       
   419     }
       
   420 
       
   421 
       
   422     template<typename T>
       
   423     auto_array<T>::auto_array(T * p)
       
   424         : p_(p)
       
   425     {
       
   426         ;
       
   427     }
       
   428 
       
   429 
       
   430     //
       
   431     // namespace for auto_array copy-and-convert-string ctor impl
       
   432     // details
       
   433     namespace Impl
       
   434     {
       
   435         template<typename T>
       
   436         struct AssertCharType
       
   437         {
       
   438             ~AssertCharType()
       
   439             {
       
   440                 // For non-character types, we don't support the
       
   441                 // special auto_array templated conversion
       
   442                 // constructor. For decent compilers, a compile time
       
   443                 // error can be generated, for non-decent compilers
       
   444                 // like the old ARMCC version we use, we have to do
       
   445                 // with a runtime exception generated.
       
   446 #ifdef __ARMCC__
       
   447                 throw ConversionExc("PANIC auto_array conversion constructor is used for non-char type %s",
       
   448                                     typeid(T).name());
       
   449 #else
       
   450                 compile_error(Template_type_T_is_not_a_character_type);
       
   451 #endif
       
   452             }
       
   453         };
       
   454 
       
   455 
       
   456         template<>
       
   457         struct AssertCharType<char>
       
   458         {
       
   459             ~AssertCharType()
       
   460             {
       
   461                 ;
       
   462             }
       
   463         };
       
   464 
       
   465 
       
   466         template<>
       
   467         struct AssertCharType<wchar_t>
       
   468         {
       
   469             ~AssertCharType()
       
   470             {
       
   471                 ;
       
   472             }
       
   473         };
       
   474 
       
   475 
       
   476         /**
       
   477          * This template class (or rather, some of its specializations
       
   478          * for enabled types) will create a new buffer, copy an
       
   479          * original string into it converting.
       
   480          *
       
   481          * Allocation happens with new[] (you need to use delete[]).
       
   482          */
       
   483         template<typename DST_CHAR,
       
   484                  typename SRC_CHAR>
       
   485         struct CopyConverter
       
   486         {
       
   487         };
       
   488 
       
   489 
       
   490         /**
       
   491          * The OpenC wcstombs is impossible to use correctly AND
       
   492          * effectively (RAM consumptionwise) at the same time. It does
       
   493          * not tell how much original wchar_t-s it has consumed, and
       
   494          * it will not put a terminating zero at the end if there is
       
   495          * not place left. So we need our own (non-trivial) logic.
       
   496          *
       
   497          * Copies and converts the whole src string, and sets the dst
       
   498          * to the newly acquired buffer.
       
   499          *
       
   500          * @throws ConversionExc
       
   501          */
       
   502         void ProperWcsToMbs(char            * & dst,
       
   503                             const wchar_t     * src,
       
   504                             size_t              length);
       
   505 
       
   506 
       
   507         /**
       
   508          * Copies and converts the whole src string, and sets the dst
       
   509          * to the newly acquired buffer.
       
   510          *
       
   511          * @throws ConversionExc
       
   512          */
       
   513         void ProperMbsToWcs(wchar_t         * & dst,
       
   514                             const char        * src,
       
   515                             size_t              length);
       
   516 
       
   517 
       
   518         template<>
       
   519         struct CopyConverter<char, wchar_t>
       
   520         {
       
   521             static void CopyConvert(char            * & dst,
       
   522                                     const wchar_t     * src,
       
   523                                     size_t              length)
       
   524                 {
       
   525                     ProperWcsToMbs(dst,
       
   526                                    src,
       
   527                                    length);
       
   528                 }
       
   529         };
       
   530 
       
   531 
       
   532         template<>
       
   533         struct CopyConverter<wchar_t, char>
       
   534         {
       
   535             static void CopyConvert(wchar_t         * & dst,
       
   536                                     const char        * src,
       
   537                                     size_t              length)
       
   538                 {
       
   539                     ProperMbsToWcs(dst,
       
   540                                    src,
       
   541                                    length);
       
   542                 }
       
   543         };
       
   544 
       
   545     } // ns
       
   546 
       
   547 
       
   548     
       
   549     template<typename T>
       
   550     template<typename CHAR>
       
   551     auto_array<T>::auto_array(const CHAR * src,
       
   552                               size_t       length)
       
   553         : p_(NULL)
       
   554     {
       
   555         Impl::AssertCharType<T>
       
   556             a1;
       
   557         Impl::AssertCharType<CHAR>
       
   558             a2;
       
   559 
       
   560         Impl::CopyConverter<T, CHAR>::CopyConvert(p_,
       
   561                                                   src,
       
   562                                                   length);
       
   563     }
       
   564 
       
   565 
       
   566 
       
   567     template<typename T>
       
   568     auto_array<T>::~auto_array()
       
   569     {
       
   570         reset(NULL);
       
   571     }
       
   572 
       
   573 
       
   574     //////////////////////////////////////////////////////////
       
   575     //
       
   576     // conversion functions
       
   577     //
       
   578 
       
   579 
       
   580     /**
       
   581      * Implementation detail struct storing the conversion string for
       
   582      * scanf type of functions and the displayname of the type being
       
   583      * converted to (for error messages).
       
   584      */
       
   585     struct ValueType
       
   586     {
       
   587         const wchar_t *    formatStr_;
       
   588         const char    *    displayName_;
       
   589     };
       
   590 
       
   591 
       
   592     /**
       
   593      * Table of value-type structs specifying the conversion format
       
   594      * strings and display names.
       
   595      */
       
   596     extern const ValueType ValueTypes[];
       
   597 
       
   598 
       
   599     /************
       
   600      *
       
   601      * The table ValueTypes contains format specifications, but for a
       
   602      * typename-inputformat pair (V,INPUTFORMAT) we have to know what
       
   603      * is the index in the ValueTypes table where we can find the
       
   604      * format string and the display name for that tuple.
       
   605      *
       
   606      * For instance, format string for floats and int will look
       
   607      * different, as well well format strings for integers in decimal
       
   608      * notations and integers in hexadecimal notations will differ.
       
   609      */
       
   610     template<typename V,
       
   611              int      INPUTFORMAT>
       
   612     struct ValueTypeIndex
       
   613     {
       
   614         // If during compilation, you find that there is no IDX
       
   615         // member, then it means that you are attempting to convert a
       
   616         // value type - inputformat tuple that is not supported.
       
   617         //
       
   618         // There are two cases.
       
   619         //
       
   620         // It can be so, that you tuple (V,INPUTFORMAT) does not make
       
   621         // any sense. For instance, scanf expects unsigned integers
       
   622         // for hecadecimal strings, so you can't dream to put there
       
   623         // signed ints or floats.
       
   624         //
       
   625         // The other case is that the conversion is okay, but it is
       
   626         // just not enabled / supported yet. Steps for enabling:
       
   627         //
       
   628         //   1 Go to definition of valuetypes in cpixstrtools.cpp, and
       
   629         //     add a new entry with the proper scanf format and
       
   630         //     display name. NOTE: there will be two conversion
       
   631         //     specifiers, first the ones you define and the second a
       
   632         //     mandatory %n.
       
   633         //
       
   634         //   2 Define a template specialication below for your tuple
       
   635         //     and define the IDX enum value to be the index of your
       
   636         //     new entry in the ValueTypes table.
       
   637         //
       
   638         // enum { IDX = ??? };
       
   639     };
       
   640 
       
   641 
       
   642     /**
       
   643      * In the case of integer value types (char, short, int, long,
       
   644      * long long, and their unsigned counterpart), there are several
       
   645      * formats the string can use, these can be controlled with the
       
   646      * enums here.
       
   647      *
       
   648      * Most types will just used the default (INPUTFORMAT_DEFAULT).
       
   649      */
       
   650     enum InputFormat
       
   651         {
       
   652             // default, for integer types it is equivalent to
       
   653             // INPUTFORMAT_INTEGER
       
   654             INPUTFORMAT_DEFAULT     = 0,
       
   655 
       
   656             // target variable is signed
       
   657             INPUTFORMAT_DECIMAL     = 1,
       
   658 
       
   659             // target variable is signed
       
   660             INPUTFORMAT_INTEGER     = 2,
       
   661 
       
   662             // target variable is unsigned
       
   663             INPUTFORMAT_OCTAL       = 3,
       
   664 
       
   665             // target variable is unsigned
       
   666             INPUTFORMAT_UINTEGER    = 4,
       
   667 
       
   668             // target variable is unsigned
       
   669             INPUTFORMAT_HEXADECIMAL = 5
       
   670         };
       
   671 
       
   672 
       
   673     template<>
       
   674     struct ValueTypeIndex<int,
       
   675                           int(INPUTFORMAT_DEFAULT)>
       
   676     {
       
   677         enum { IDX = 0 };
       
   678     };
       
   679     
       
   680     template<>
       
   681     struct ValueTypeIndex<int,
       
   682                           int(INPUTFORMAT_DECIMAL)>
       
   683     {
       
   684         enum { IDX = 1 };
       
   685     };
       
   686 
       
   687     template<>
       
   688     struct ValueTypeIndex<int,
       
   689                           int(INPUTFORMAT_INTEGER)>
       
   690     {
       
   691         enum { IDX = 0 };
       
   692     };
       
   693 
       
   694     template<>
       
   695     struct ValueTypeIndex<unsigned int,
       
   696                           int(INPUTFORMAT_OCTAL)>
       
   697     {
       
   698         enum { IDX = 2 };
       
   699     };
       
   700 
       
   701     template<>
       
   702     struct ValueTypeIndex<unsigned int,
       
   703                           int(INPUTFORMAT_UINTEGER)>
       
   704     {
       
   705         enum { IDX = 3 };
       
   706     };
       
   707 
       
   708     template<>
       
   709     struct ValueTypeIndex<unsigned int,
       
   710                           int(INPUTFORMAT_HEXADECIMAL)>
       
   711     {
       
   712         enum { IDX = 4 };
       
   713     };
       
   714 
       
   715 
       
   716     template<>
       
   717     struct ValueTypeIndex<float,
       
   718                           int(INPUTFORMAT_DEFAULT)>
       
   719     {
       
   720         enum { IDX = 5 };
       
   721     };
       
   722 
       
   723     template<>
       
   724     struct ValueTypeIndex<double,
       
   725                           int(INPUTFORMAT_DEFAULT)>
       
   726     {
       
   727         enum { IDX = 6 };
       
   728     };
       
   729 
       
   730 
       
   731 
       
   732     /**
       
   733      * Attempts to convert the given wide string to the value. This is
       
   734      * the common workhorse function for all conversions.
       
   735      *
       
   736      * The template parameter INPUTFORMAT can be one of the
       
   737      * InputFormat enums. Mostly, you want to use INPUTFORMAT_DEFAULT
       
   738      * (cf overloaded convert function). If you are dealing with
       
   739      * integers and special formatted values (octal, hex, etc ...),
       
   740      * you can use the enum values above.
       
   741      *
       
   742      * NOTE: some of the input enum values imply signed, other imply
       
   743      * unsigned value. Trying to use the wrong type of variable for
       
   744      * 'to' will result in compilation error.
       
   745      *
       
   746      * @param to the pointer to the value to put the results, must not
       
   747      * be NULL
       
   748      *
       
   749      * @param wide string, must not be NULL, and it must contain only
       
   750      * the string representation for the value, nothing more. Failure
       
   751      * to eat all of the string and put it to the value shall result
       
   752      * in error.
       
   753      *
       
   754      * @return NULL if successful, and some string about what sort of
       
   755      * value/formatting was attempted on failure.
       
   756      */
       
   757     template<typename V,
       
   758              int      INPUTFORMAT>
       
   759     const char * wconvert(V             * to,
       
   760                           const wchar_t * fromStr)
       
   761     {
       
   762         const char
       
   763             * rv = NULL;
       
   764 
       
   765         int
       
   766             valueTypeIndex = ValueTypeIndex<V, INPUTFORMAT>::IDX;
       
   767 
       
   768         const ValueType
       
   769             & valueType = ValueTypes[valueTypeIndex];
       
   770 
       
   771         int
       
   772             charsRead = 0;
       
   773         int
       
   774             result = swscanf(fromStr,
       
   775                              valueType.formatStr_,
       
   776                              to,
       
   777                              &charsRead);
       
   778 
       
   779         if (result != 1
       
   780             || charsRead != (*wcslen)(fromStr))
       
   781             {
       
   782                 rv = valueType.displayName_;
       
   783             }
       
   784 
       
   785         return rv;
       
   786     }
       
   787 
       
   788 
       
   789     template<typename V>
       
   790     const char * wconvert(V             * to,
       
   791                           const wchar_t * fromStr)
       
   792     {
       
   793         return wconvert<V, INPUTFORMAT_DEFAULT>(to,
       
   794                                                 fromStr);
       
   795     }
       
   796 
       
   797 
       
   798     template<typename INT>
       
   799     const char * wconvertDecimal(INT           * to,
       
   800                                  const wchar_t * fromStr)
       
   801     {
       
   802         return wconvert<INT, INPUTFORMAT_DECIMAL>(to,
       
   803                                                   fromStr);
       
   804     }
       
   805 
       
   806 
       
   807     template<typename INT>
       
   808     const char * wconvertInteger(INT           * to,
       
   809                                  const wchar_t * fromStr)
       
   810     {
       
   811         return wconvert<INT, INPUTFORMAT_INTEGER>(to,
       
   812                                                   fromStr);
       
   813     }
       
   814 
       
   815 
       
   816     template<typename INT>
       
   817     const char * wconvertOctal(INT           * to,
       
   818                                const wchar_t * fromStr)
       
   819     {
       
   820         return wconvert<INT, INPUTFORMAT_OCTAL>(to,
       
   821                                                 fromStr);
       
   822     }
       
   823 
       
   824 
       
   825     template<typename INT>
       
   826     const char * wconvertUnsignedInteger(INT           * to,
       
   827                                          const wchar_t * fromStr)
       
   828     {
       
   829         return wconvert<INT, INPUTFORMAT_UINTEGER>(to,
       
   830                                                    fromStr);
       
   831     }
       
   832 
       
   833     template<typename INT>
       
   834     const char * wconvertHexadecimal(INT           * to,
       
   835                                      const wchar_t * fromStr)
       
   836     {
       
   837         return wconvert<INT, INPUTFORMAT_HEXADECIMAL>(to,
       
   838                                                       fromStr);
       
   839     }
       
   840 
       
   841     
       
   842         
       
   843 }
       
   844 
       
   845 
       
   846 #endif
       
   847 
       
   848 
       
   849 
       
   850