Synesis Software STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ...

fastformat/util/bundle/windows_replacement_translation_functions.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////
00002  * File:        fastformat/util/bundle/windows_replacement_translation_functions.hpp
00003  *
00004  * Purpose:     Functions to assist with translation between Windows and
00005  *              FastFormat replacement parameters.
00006  *
00007  * Created:     24th April 2009
00008  * Updated:     11th August 2009
00009  *
00010  * Home:        http://www.fastformat.org/
00011  *
00012  * Copyright (c) 2009, Matthew Wilson and Synesis Software
00013  * All rights reserved.
00014  *
00015  * Redistribution and use in source and binary forms, with or without
00016  * modification, are permitted provided that the following conditions are
00017  * met:
00018  *
00019  * - Redistributions of source code must retain the above copyright notice,
00020  *   this list of conditions and the following disclaimer.
00021  * - Redistributions in binary form must reproduce the above copyright
00022  *   notice, this list of conditions and the following disclaimer in the
00023  *   documentation and/or other materials provided with the distribution.
00024  * - Neither the names of Matthew Wilson and Synesis Software nor the names
00025  *   of any contributors may be used to endorse or promote products derived
00026  *   from this software without specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00029  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00030  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00031  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00032  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00033  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00034  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00035  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00036  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00037  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00038  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  * ////////////////////////////////////////////////////////////////////// */
00041 
00042 
00049 #ifndef FASTFORMAT_INCL_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS
00050 #define FASTFORMAT_INCL_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS
00051 
00052 /* /////////////////////////////////////////////////////////////////////////
00053  * Version information
00054  */
00055 
00056 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00057 # define FASTFORMAT_VER_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS_MAJOR      1
00058 # define FASTFORMAT_VER_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS_MINOR      0
00059 # define FASTFORMAT_VER_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS_REVISION   1
00060 # define FASTFORMAT_VER_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS_EDIT       3
00061 #endif /* !FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00062 
00063 /* /////////////////////////////////////////////////////////////////////////
00064  * Language
00065  */
00066 
00067 #ifndef __cplusplus
00068 # error This file can only be included in C++ compilation units
00069 #endif /* !__cplusplus */
00070 
00071 /* /////////////////////////////////////////////////////////////////////////
00072  * Includes
00073  */
00074 
00075 #include <fastformat/fastformat.h>
00076 #include <fastformat/quality/contract.h>
00077 #include <fastformat/util/string/snprintf.h>
00078 
00079 /* /////////////////////////////////////////////////////////////////////////
00080  * Namespace
00081  */
00082 
00083 #if !defined(FASTFORMAT_NO_NAMESPACE)
00084 namespace fastformat
00085 {
00086 namespace util
00087 {
00088 #endif /* !FASTFORMAT_NO_NAMESPACE */
00089 
00090 /* /////////////////////////////////////////////////////////////////////////
00091  * Functions
00092  */
00093 
00102 inline size_t calculate_number_of_windows_replacement_parameters(ff_char_t const* str, size_t len)
00103 {
00104     enum state_t
00105     {
00106         normal, percent
00107     }                   state   =   normal;
00108     ff_char_t const*    begin   =   str;
00109     ff_char_t const*    end     =   str + len;
00110     size_t              n       =   0;
00111 
00112     for(; begin != end; ++begin)
00113     {
00114         switch(*begin)
00115         {
00116             case    '%':
00117                 state = (normal == state) ? percent : normal;
00118                 break;
00119             case    '0':
00120             case    '1':
00121             case    '2':
00122             case    '3':
00123             case    '4':
00124             case    '5':
00125             case    '6':
00126             case    '7':
00127             case    '8':
00128             case    '9':
00129                 if(percent == state)
00130                 {
00131                     ++n;
00132                 }
00133                 // fall through
00134             default:
00135                 state = normal;
00136                 break;
00137         }
00138     }
00139 
00140     return n;
00141 }
00142 
00151 inline size_t calculate_number_of_fastformat_replacement_parameters(ff_char_t const* str, size_t len)
00152 {
00153     enum state_t
00154     {
00155         normal, replacement
00156     }                   state   =   normal;
00157     ff_char_t const*    begin   =   str;
00158     ff_char_t const*    end     =   str + len;
00159     size_t              n       =   0;
00160 
00161     for(; begin != end; ++begin)
00162     {
00163         switch(*begin)
00164         {
00165             case    '{':
00166                 state = (normal == state) ? replacement : normal;
00167                 break;
00168             case    '0':
00169             case    '1':
00170             case    '2':
00171             case    '3':
00172             case    '4':
00173             case    '5':
00174             case    '6':
00175             case    '7':
00176             case    '8':
00177             case    '9':
00178                 if(replacement == state)
00179                 {
00180                     ++n;
00181                 }
00182                 // fall through
00183             default:
00184                 state = normal;
00185                 break;
00186         }
00187     }
00188 
00189     return n;
00190 }
00191 
00192 
00195 template <typename S>
00196 inline S change_windows_replacement_parameters_to_fastformat(S const& str)
00197 {
00198     typedef ss_typename_type_k S::const_iterator    iter_t;
00199 
00200     enum state_t
00201     {
00202         normal, percent, number
00203     }       state   =   normal;
00204     S       str2;
00205     int     index   =   0;
00206 
00207     str2.reserve(str.size() + 10);
00208 
00209     { for(iter_t begin = str.begin(); begin != str.end(); ++begin)
00210     {
00211         bool isNumber = false;
00212 
00213         switch(*begin)
00214         {
00215             case    '0':
00216             case    '1':
00217             case    '2':
00218             case    '3':
00219             case    '4':
00220             case    '5':
00221             case    '6':
00222             case    '7':
00223             case    '8':
00224             case    '9':
00225                 isNumber = true;
00226         }
00227 
00228         if( number == state &&
00229             !isNumber)
00230         {
00231             ff_char_t   parameter[32];
00232             int         cch = fastformat_util_snprintf(&parameter[0], STLSOFT_NUM_ELEMENTS(parameter), FASTFORMAT_LITERAL_STRING("{%d}"), index - 1);
00233 
00234             str2.append(parameter, size_t(cch));
00235             str2.append(1u, *begin);
00236 
00237             state = normal;
00238         }
00239         else
00240         {
00241             switch(*begin)
00242             {
00243                 case    '%':
00244                     switch(state)
00245                     {
00246                         default:
00247                         case    number:
00248                             FASTFORMAT_CONTRACT_ENFORCE_UNEXPECTED_CONDITION_INTERNAL("unexpected state");
00249                         case    normal:
00250                             state = percent;
00251                             break;
00252                         case    percent:
00253                             state = normal;
00254                             str2.append(1, '%');
00255                             break;
00256                     }
00257                     break;
00258                 case    '0':
00259                 case    '1':
00260                 case    '2':
00261                 case    '3':
00262                 case    '4':
00263                 case    '5':
00264                 case    '6':
00265                 case    '7':
00266                 case    '8':
00267                 case    '9':
00268                     switch(state)
00269                     {
00270                         default:
00271                             FASTFORMAT_CONTRACT_ENFORCE_UNEXPECTED_CONDITION_INTERNAL("unexpected state");
00272                         case    normal:
00273                             str2.append(1, *begin);
00274                             break;
00275                         case    percent:
00276                             state = number;
00277                             index = (*begin - '0');
00278                             break;
00279                         case    number:
00280                             index = (10 * index) + (*begin - '0');
00281                             break;
00282                     }
00283                     break;
00284                 default:
00285                     state = normal;
00286                     str2.append(1, *begin);
00287                     break;
00288             }
00289         }
00290     }}
00291 
00292     return str2;
00293 }
00294 
00298 template <typename S>
00299 inline S escape_fastformat_replacement_parameters(S const& str)
00300 {
00301     typedef ss_typename_type_k S::const_iterator    iter_t;
00302 
00303     S   str2;
00304 
00305     str2.reserve(str.size() + 10);
00306 
00307     { for(iter_t begin = str.begin(); begin != str.end(); ++begin)
00308     {
00309         switch(*begin)
00310         {
00311             case    '{':
00312                 str2.append(1, '{');
00313             default:
00314                 str2.append(1, *begin);
00315                 break;
00316         }
00317     }}
00318 
00319     return str2;
00320 }
00321 
00322 /* /////////////////////////////////////////////////////////////////////////
00323  * Namespace
00324  */
00325 
00326 #if !defined(FASTFORMAT_NO_NAMESPACE)
00327 } /* namespace util */
00328 } /* namespace fastformat */
00329 #endif /* !FASTFORMAT_NO_NAMESPACE */
00330 
00331 /* ////////////////////////////////////////////////////////////////////// */
00332 
00333 #endif /* FASTFORMAT_INCL_FASTFORMAT_UTIL_BUNDLE_HPP_WINDOWS_REPLACEMENT_TRANSLATION_FUNCTIONS */
00334 
00335 /* ///////////////////////////// end of file //////////////////////////// */

FastFormat Library documentation © Matthew Wilson, 2006-2009 SourceForge.net Logo