searchengine/util/cpixtools/src/cpixstrtools.cpp
changeset 0 671dee74050a
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 #include "cpixstrtools.h"
       
    18 #include <e32std.h>
       
    19 
       
    20 
       
    21 namespace Cpt
       
    22 {
       
    23 
       
    24     void splitstring(const char             * orig,
       
    25                      const char             * delimiters,
       
    26                      std::list<std::string> & target)
       
    27     {
       
    28         using namespace std;
       
    29 
       
    30         target.clear();
       
    31 
       
    32         if (orig == NULL)
       
    33             {
       
    34                 return;
       
    35             }
       
    36 
       
    37         const char
       
    38             * curBegin = orig,
       
    39             * curEnd = strpbrk(curBegin,
       
    40                                delimiters);
       
    41 
       
    42         while (curBegin != NULL)
       
    43             {
       
    44                 if (curEnd == NULL)
       
    45                     {
       
    46                         target.push_back(string(curBegin,
       
    47                                                 strlen(curBegin)));
       
    48                         curBegin = NULL;
       
    49                     }
       
    50                 else
       
    51                     {
       
    52                         target.push_back(string(curBegin,
       
    53                                                 curEnd));
       
    54                         curBegin = curEnd + 1;
       
    55                         if (*curBegin != 0)
       
    56                             {
       
    57                                 curEnd = strpbrk(curBegin,
       
    58                                                  delimiters);
       
    59                             }
       
    60                         else
       
    61                             {
       
    62                                 curBegin = NULL;
       
    63                             }
       
    64                     }
       
    65             } 
       
    66     }
       
    67 
       
    68     int wsnprintdouble(wchar_t* target, size_t n, double number, int decimals)
       
    69 	{
       
    70 		// NOTE, this printing mechanism is FAR from perfect
       
    71 		// It tries to avoid integer/long overflowing, but 
       
    72 		// at the same time it is vulnerable to double -> int 
       
    73 		// conversion inaccuracies.
       
    74 		int integer_part = static_cast<int>(number); 
       
    75 		
       
    76 		// print integer part and dot 
       
    77 		int loc = 
       
    78 			snwprintf(target, n, L"%d", integer_part);
       
    79 		loc += snwprintf(target + loc, n-loc, L".");
       
    80 		number -= integer_part; // Number is in form 0.12345
       
    81 		number *= number < 0 ? -1. : 1.;  
       
    82 				
       
    83 		while (decimals-- > 0) {
       
    84 			// extract one decimal out of number
       
    85 			number*=10.; // Number is in form 1.234 
       
    86 			int decimal = static_cast<int>(number);
       
    87 			number -= decimal; // Returned into form 0.123
       
    88 			
       
    89 			loc += 
       
    90 				snwprintf(target+loc, n-loc, L"%d", decimal); 
       
    91 		}
       
    92 		return loc; 
       
    93 	}
       
    94 
       
    95     uint32_t getUsedDynamicMemory()
       
    96     {
       
    97         // TODO this is symbian specific code here
       
    98 
       
    99         TInt 
       
   100             largestBlock;
       
   101         TInt 
       
   102             mem = User::Heap().Size() - User::Heap().Available(largestBlock);
       
   103 
       
   104         return static_cast<uint32_t>(mem);
       
   105     }
       
   106 
       
   107 
       
   108 
       
   109     // conversion information for the convert... family of functions
       
   110     const ValueType ValueTypes[] = {
       
   111         
       
   112         // 0 : integer, %i
       
   113         { L"%i%n",       "integer (generic format)" },
       
   114             
       
   115         // 1 : integer, %d
       
   116         { L"%d%n",       "integer (decimal format)" },
       
   117 
       
   118         // 2 : unsigned integer, %o
       
   119         { L"%o%n",       "unsigned integer (octal format)" },
       
   120 
       
   121         // 3 : unsigned integer, %u
       
   122         { L"%u%n",       "unsigned integer (decimal)" },
       
   123 
       
   124         // 4 : unsigned integer, %x
       
   125         { L"%x%n",       "unsigned integer (hexadecimal format)" },
       
   126 
       
   127         // 5 : float, %f
       
   128         { L"%f%n",       "float" },
       
   129 
       
   130         // 6 : double, %lf
       
   131         { L"%lf%n",       "double" },
       
   132 
       
   133     };
       
   134     
       
   135 }
       
   136 
       
   137 
       
   138 
       
   139 
       
   140 
       
   141 //
       
   142 // Implementation detail functions for proper, wchar_t -> char and
       
   143 // char -> wchar_t copy-conversions
       
   144 //
       
   145 namespace Cpt
       
   146 {
       
   147     //
       
   148     //
       
   149     // ConversionExc
       
   150     //
       
   151     //
       
   152     const char * ConversionExc::what() const throw()
       
   153     {
       
   154         return what_.c_str();
       
   155     }
       
   156     
       
   157 
       
   158 
       
   159     ConversionExc::ConversionExc(const char * format,
       
   160                                  ...)
       
   161     {
       
   162         char
       
   163             msg[96];
       
   164 
       
   165         va_list
       
   166             args;
       
   167         va_start(args,
       
   168                  format);
       
   169 
       
   170         vsnprintf(msg,
       
   171                   sizeof(msg),
       
   172                   format,
       
   173                   args);
       
   174 
       
   175         va_end(args);
       
   176 
       
   177         what_ = msg;
       
   178     }
       
   179         
       
   180         
       
   181 
       
   182     namespace Impl
       
   183     {
       
   184         //
       
   185         // Conversion functions
       
   186         //
       
   187         void ProperWcsToMbs(char            * & dst,
       
   188                             const wchar_t     * src,
       
   189                             size_t              length)
       
   190         {
       
   191             enum { INVALID_MB_PER_WC_RATE  = 0 };
       
   192 
       
   193             // we don't want to allocate MB_LEN_MAX number of bytes
       
   194             // for each wide character, because that many is certainly
       
   195             // not needed for western languages. (For instance,
       
   196             // Symbian example codes of OpenC usage only use 2 as a
       
   197             // multibyte-per-widechar factor, which is wrong
       
   198             // generally, as a unicode code point may require at most
       
   199             // 4 bytes in a utf8 sequence.)
       
   200             const static size_t
       
   201                 MB_PER_WC_RATES[] = {
       
   202                 // first we alloc 2 bytes for each wide char, as
       
   203                 // recommended by symbian examples
       
   204                 2,
       
   205 
       
   206                 // then we use the theoretical max
       
   207                 MB_LEN_MAX,
       
   208 
       
   209                 // this should not happen - we should not need more
       
   210                 // than the theoretical max
       
   211                 INVALID_MB_PER_WC_RATE
       
   212             };
       
   213             
       
   214             const size_t
       
   215                 * mbPerWcRate = MB_PER_WC_RATES;
       
   216 
       
   217             size_t
       
   218                 srcSize = std::min(wcslen(src), length);
       
   219 
       
   220             const wchar_t
       
   221                 * curSrc = src;
       
   222 
       
   223             size_t
       
   224                 tmpSize = *mbPerWcRate * srcSize;
       
   225             auto_array<char>
       
   226                 tmp(new char[tmpSize + 1]);
       
   227 
       
   228             char
       
   229                 * curDst = tmp.get(),
       
   230                 * curLastDst = tmp.get() + tmpSize;
       
   231             
       
   232             while (curSrc - src < srcSize)
       
   233                 {
       
   234                     // a single wide-char can take up MB_LEN_MAX bytes
       
   235                     // at most: we have to make sure to have that
       
   236                     // amount of space
       
   237                     if (curLastDst - curDst >= MB_LEN_MAX)
       
   238                         {
       
   239                             int
       
   240                                 result = wctomb(curDst,
       
   241                                                 *curSrc);
       
   242 
       
   243                             if (result < 0)
       
   244                                 {
       
   245                                     throw ConversionExc("Could not convert w string %S at position %d: %d",
       
   246                                                         src,
       
   247                                                         curSrc - src,
       
   248                                                         result);
       
   249                                 }
       
   250 
       
   251                             curDst += result;
       
   252 
       
   253                             if (curLastDst <= curDst)
       
   254                                 {
       
   255                                     throw ConversionExc("ASSERT wctomb() / MB_LEN_MAX(%d) are inconsistent",
       
   256                                                         MB_LEN_MAX);
       
   257                                 }
       
   258 
       
   259                             ++curSrc;
       
   260                         }
       
   261                     else
       
   262                         {
       
   263                             ++mbPerWcRate;
       
   264 
       
   265                             if (*mbPerWcRate == INVALID_MB_PER_WC_RATE)
       
   266                                 {
       
   267                                     throw ConversionExc("ASSERT Too many reallocs during wc->mb conversion, shouldn't happen: %S",
       
   268                                                         src);
       
   269                                 }
       
   270 
       
   271                             size_t
       
   272                                 newTmpSize = *mbPerWcRate * srcSize;
       
   273                             auto_array<char>
       
   274                                 newTmp(new char[newTmpSize + 1]);
       
   275                             memcpy(newTmp.get(),
       
   276                                    tmp.get(),
       
   277                                    curDst - tmp.get());
       
   278 
       
   279                             curDst = newTmp.get() + (curDst - tmp.get());
       
   280                             curLastDst = newTmp.get() + newTmpSize;
       
   281 
       
   282                             tmp.reset(newTmp.release());
       
   283                             tmpSize = newTmpSize;
       
   284                         }
       
   285                 }
       
   286 
       
   287             *curDst = '\0';
       
   288 
       
   289             dst = tmp.release();
       
   290         }
       
   291 
       
   292 
       
   293 
       
   294         void ProperMbsToWcs(wchar_t         * & dst,
       
   295                             const char        * src,
       
   296                             size_t              length)
       
   297         {
       
   298             size_t
       
   299                 size = std::min(length, strlen(src)) + 1;
       
   300 
       
   301             dst = new wchar_t[size];
       
   302 
       
   303             int
       
   304                 result = mbstowcs(dst,
       
   305                                   src,
       
   306                                   size);
       
   307 
       
   308             if (result < 0)
       
   309                 {
       
   310                     throw ConversionExc("Could not convert %s: %d",
       
   311                                         src,
       
   312                                         errno);
       
   313                 }
       
   314         }
       
   315         
       
   316 
       
   317     } // ns
       
   318 } // ns