LCOV - code coverage report
Current view: directory - objdir/dist/include - nsCharTraits.h (source / functions) Found Hit Coverage
Test: app.info Lines: 146 123 84.2 %
Date: 2012-06-02 Functions: 49 44 89.8 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2000
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Scott Collins <scc@mozilla.org> (original author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifndef nsCharTraits_h___
      40                 : #define nsCharTraits_h___
      41                 : 
      42                 : #include <ctype.h>
      43                 :   // for |EOF|, |WEOF|
      44                 : 
      45                 : #define FORCED_CPP_2BYTE_WCHAR_T
      46                 :   // disable special optimizations for now through this hack
      47                 : 
      48                 : #if defined(HAVE_CPP_2BYTE_WCHAR_T) && !defined(FORCED_CPP_2BYTE_WCHAR_T)
      49                 : #define USE_CPP_WCHAR_FUNCS
      50                 : #endif
      51                 : 
      52                 : #ifdef USE_CPP_WCHAR_FUNCS
      53                 : #include <wchar.h>
      54                 :   // for |wmemset|, et al
      55                 : #endif
      56                 : 
      57                 : #include <string.h>
      58                 :   // for |memcpy|, et al
      59                 : 
      60                 : #ifndef nscore_h___
      61                 : #include "nscore.h"
      62                 :   // for |PRUnichar|
      63                 : #endif
      64                 : 
      65                 : // This file may be used (through nsUTF8Utils.h) from non-XPCOM code, in
      66                 : // particular the standalone software updater. In that case stub out
      67                 : // the macros provided by nsDebug.h which are only usable when linking XPCOM
      68                 : 
      69                 : #ifdef NS_NO_XPCOM
      70                 : #define NS_WARNING(msg)
      71                 : #define NS_ASSERTION(cond, msg)
      72                 : #define NS_ERROR(msg)
      73                 : #else
      74                 : #ifndef nsDebug_h__
      75                 : #include "nsDebug.h"
      76                 :   // for NS_ASSERTION
      77                 : #endif
      78                 : #endif
      79                 : 
      80                 : /*
      81                 :  * Some macros for converting PRUnichar (UTF-16) to and from Unicode scalar
      82                 :  * values.
      83                 :  *
      84                 :  * Note that UTF-16 represents all Unicode scalar values up to U+10FFFF by
      85                 :  * using "surrogate pairs". These consist of a high surrogate, i.e. a code
      86                 :  * point in the range U+D800 - U+DBFF, and a low surrogate, i.e. a code point
      87                 :  * in the range U+DC00 - U+DFFF, like this:
      88                 :  *
      89                 :  *  U+D800 U+DC00 =  U+10000
      90                 :  *  U+D800 U+DC01 =  U+10001
      91                 :  *  ...
      92                 :  *  U+DBFF U+DFFE = U+10FFFE
      93                 :  *  U+DBFF U+DFFF = U+10FFFF
      94                 :  *
      95                 :  * These surrogate code points U+D800 - U+DFFF are not themselves valid Unicode
      96                 :  * scalar values and are not well-formed UTF-16 except as high-surrogate /
      97                 :  * low-surrogate pairs.
      98                 :  */
      99                 : 
     100                 : #define PLANE1_BASE          PRUint32(0x00010000)
     101                 : // High surrogates are in the range 0xD800 -- OxDBFF
     102                 : #define NS_IS_HIGH_SURROGATE(u) ((PRUint32(u) & 0xFFFFFC00) == 0xD800)
     103                 : // Low surrogates are in the range 0xDC00 -- 0xDFFF
     104                 : #define NS_IS_LOW_SURROGATE(u)  ((PRUint32(u) & 0xFFFFFC00) == 0xDC00)
     105                 : // Faster than testing NS_IS_HIGH_SURROGATE || NS_IS_LOW_SURROGATE
     106                 : #define IS_SURROGATE(u)      ((PRUint32(u) & 0xFFFFF800) == 0xD800)
     107                 : 
     108                 : // Everything else is not a surrogate: 0x000 -- 0xD7FF, 0xE000 -- 0xFFFF
     109                 : 
     110                 : // N = (H - 0xD800) * 0x400 + 0x10000 + (L - 0xDC00)
     111                 : // I wonder whether we could somehow assert that H is a high surrogate
     112                 : // and L is a low surrogate
     113                 : #define SURROGATE_TO_UCS4(h, l) (((PRUint32(h) & 0x03FF) << 10) + \
     114                 :                                  (PRUint32(l) & 0x03FF) + PLANE1_BASE)
     115                 : 
     116                 : // Extract surrogates from a UCS4 char
     117                 : // Reference: the Unicode standard 4.0, section 3.9
     118                 : // Since (c - 0x10000) >> 10 == (c >> 10) - 0x0080 and 
     119                 : // 0xD7C0 == 0xD800 - 0x0080,
     120                 : // ((c - 0x10000) >> 10) + 0xD800 can be simplified to
     121                 : #define H_SURROGATE(c) PRUnichar(PRUnichar(PRUint32(c) >> 10) + \
     122                 :                                  PRUnichar(0xD7C0)) 
     123                 : // where it's to be noted that 0xD7C0 is not bitwise-OR'd
     124                 : // but added.
     125                 : 
     126                 : // Since 0x10000 & 0x03FF == 0, 
     127                 : // (c - 0x10000) & 0x03FF == c & 0x03FF so that
     128                 : // ((c - 0x10000) & 0x03FF) | 0xDC00 is equivalent to
     129                 : #define L_SURROGATE(c) PRUnichar(PRUnichar(PRUint32(c) & PRUint32(0x03FF)) | \
     130                 :                                  PRUnichar(0xDC00))
     131                 : 
     132                 : #define IS_IN_BMP(ucs) (PRUint32(ucs) < PLANE1_BASE)
     133                 : #define UCS2_REPLACEMENT_CHAR PRUnichar(0xFFFD)
     134                 : 
     135                 : #define UCS_END PRUint32(0x00110000)
     136                 : #define IS_VALID_CHAR(c) ((PRUint32(c) < UCS_END) && !IS_SURROGATE(c))
     137                 : #define ENSURE_VALID_CHAR(c) (IS_VALID_CHAR(c) ? (c) : UCS2_REPLACEMENT_CHAR)
     138                 : 
     139                 : template <class CharT> struct nsCharTraits {};
     140                 : 
     141                 : template <>
     142                 : struct nsCharTraits<PRUnichar>
     143                 :   {
     144                 :     typedef PRUnichar char_type;
     145                 :     typedef PRUint16  unsigned_char_type;
     146                 :     typedef char      incompatible_char_type;
     147                 : 
     148                 :     static char_type *sEmptyBuffer;
     149                 : 
     150                 :     static
     151                 :     void
     152                 :     assign( char_type& lhs, char_type rhs )
     153                 :       {
     154                 :         lhs = rhs;
     155                 :       }
     156                 : 
     157                 : 
     158                 :       // integer representation of characters:
     159                 : 
     160                 : #ifdef USE_CPP_WCHAR_FUNCS
     161                 :     typedef wint_t int_type;
     162                 : #else
     163                 :     typedef int int_type;
     164                 : #endif
     165                 : 
     166                 :     static
     167                 :     char_type
     168           99502 :     to_char_type( int_type c )
     169                 :       {
     170           99502 :         return char_type(c);
     171                 :       }
     172                 : 
     173                 :     static
     174                 :     int_type
     175         1507676 :     to_int_type( char_type c )
     176                 :       {
     177         1507676 :         return int_type( static_cast<unsigned_char_type>(c) );
     178                 :       }
     179                 : 
     180                 :     static
     181                 :     bool
     182          680790 :     eq_int_type( int_type lhs, int_type rhs )
     183                 :       {
     184          680790 :         return lhs == rhs;
     185                 :       }
     186                 : 
     187                 : 
     188                 :       // |char_type| comparisons:
     189                 : 
     190                 :     static
     191                 :     bool
     192        19402404 :     eq( char_type lhs, char_type rhs )
     193                 :       {
     194        19402404 :         return lhs == rhs;
     195                 :       }
     196                 : 
     197                 :     static
     198                 :     bool
     199                 :     lt( char_type lhs, char_type rhs )
     200                 :       {
     201                 :         return lhs < rhs;
     202                 :       }
     203                 : 
     204                 : 
     205                 :       // operations on s[n] arrays:
     206                 : 
     207                 :     static
     208                 :     char_type*
     209         1321079 :     move( char_type* s1, const char_type* s2, size_t n )
     210                 :       {
     211         1321079 :         return static_cast<char_type*>(memmove(s1, s2, n * sizeof(char_type)));
     212                 :       }
     213                 : 
     214                 :     static
     215                 :     char_type*
     216         3174857 :     copy( char_type* s1, const char_type* s2, size_t n )
     217                 :       {
     218         3174857 :         return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(char_type)));
     219                 :       }
     220                 : 
     221                 :     static
     222                 :     char_type*
     223          210583 :     copyASCII( char_type* s1, const char* s2, size_t n )
     224                 :       {
     225         3472670 :         for (char_type* s = s1; n--; ++s, ++s2) {
     226         3262087 :           NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     227         3262087 :           *s = *s2;
     228                 :         }
     229          210583 :         return s1;
     230                 :       }
     231                 : 
     232                 :     static
     233                 :     char_type*
     234                 :     assign( char_type* s, size_t n, char_type c )
     235                 :       {
     236                 : #ifdef USE_CPP_WCHAR_FUNCS
     237                 :         return static_cast<char_type*>(wmemset(s, to_int_type(c), n));
     238                 : #else
     239                 :         char_type* result = s;
     240                 :         while ( n-- )
     241                 :           assign(*s++, c);
     242                 :         return result;
     243                 : #endif
     244                 :       }
     245                 : 
     246                 :     static
     247                 :     int
     248          606041 :     compare( const char_type* s1, const char_type* s2, size_t n )
     249                 :       {
     250                 : #ifdef USE_CPP_WCHAR_FUNCS
     251                 :         return wmemcmp(s1, s2, n);
     252                 : #else
     253         8828261 :         for ( ; n--; ++s1, ++s2 )
     254                 :           {
     255         8285264 :             if ( !eq(*s1, *s2) )
     256           63042 :               return to_int_type(*s1) - to_int_type(*s2);
     257                 :           }
     258                 : 
     259          542997 :         return 0;
     260                 : #endif
     261                 :       }
     262                 : 
     263                 :     static
     264                 :     int
     265           19273 :     compareASCII( const char_type* s1, const char* s2, size_t n )
     266                 :       {
     267          699097 :         for ( ; n--; ++s1, ++s2 )
     268                 :           {
     269          680490 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     270          680490 :             if ( !eq_int_type(to_int_type(*s1), to_int_type(*s2)) )
     271             666 :               return to_int_type(*s1) - to_int_type(*s2);
     272                 :           }
     273                 : 
     274           18607 :         return 0;
     275                 :       }
     276                 : 
     277                 :     // this version assumes that s2 is null-terminated and s1 has length n.
     278                 :     // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
     279                 :     // we return 1.
     280                 :     static
     281                 :     int
     282              84 :     compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
     283                 :       {
     284             300 :         for ( ; n--; ++s1, ++s2 )
     285                 :           {
     286             300 :             if ( !*s2 )
     287               0 :               return 1;
     288             300 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     289             300 :             if ( !eq_int_type(to_int_type(*s1), to_int_type(*s2)) )
     290              84 :               return to_int_type(*s1) - to_int_type(*s2);
     291                 :           }
     292                 : 
     293               0 :         if ( *s2 )
     294               0 :           return -1;
     295                 : 
     296               0 :         return 0;
     297                 :       }
     298                 : 
     299                 :     /**
     300                 :      * Convert c to its lower-case form, but only if the lower-case form is
     301                 :      * ASCII. Otherwise leave it alone.
     302                 :      *
     303                 :      * There are only two non-ASCII Unicode characters whose lowercase
     304                 :      * equivalents are ASCII: KELVIN SIGN and LATIN CAPITAL LETTER I WITH
     305                 :      * DOT ABOVE. So it's a simple matter to handle those explicitly.
     306                 :      */
     307                 :     static
     308                 :     char_type
     309           99502 :     ASCIIToLower( char_type c )
     310                 :       {
     311           99502 :         if (c < 0x100)
     312                 :           {
     313           99502 :             if (c >= 'A' && c <= 'Z')
     314           27566 :               return char_type(c + ('a' - 'A'));
     315                 :           
     316           71936 :             return c;
     317                 :           }
     318                 :         else
     319                 :           {
     320               0 :             if (c == 0x212A) // KELVIN SIGN
     321               0 :               return 'k';
     322               0 :             if (c == 0x0130) // LATIN CAPITAL LETTER I WITH DOT ABOVE
     323               0 :               return 'i';
     324               0 :             return c;
     325                 :           }
     326                 :       }
     327                 : 
     328                 :     static
     329                 :     int
     330           21401 :     compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
     331                 :       {
     332          111647 :         for ( ; n--; ++s1, ++s2 )
     333                 :           {
     334           99502 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     335           99502 :             NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
     336                 :                          "Unexpected uppercase character");
     337           99502 :             char_type lower_s1 = ASCIIToLower(*s1);
     338           99502 :             if ( lower_s1 != to_char_type(*s2) )
     339            9256 :               return to_int_type(lower_s1) - to_int_type(*s2);
     340                 :           }
     341                 : 
     342           12145 :         return 0;
     343                 :       }
     344                 : 
     345                 :     // this version assumes that s2 is null-terminated and s1 has length n.
     346                 :     // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
     347                 :     // we return 1.
     348                 :     static
     349                 :     int
     350               0 :     compareLowerCaseToASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
     351                 :       {
     352               0 :         for ( ; n--; ++s1, ++s2 )
     353                 :           {
     354               0 :             if ( !*s2 )
     355               0 :               return 1;
     356               0 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     357               0 :             NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
     358                 :                          "Unexpected uppercase character");
     359               0 :             char_type lower_s1 = ASCIIToLower(*s1);
     360               0 :             if ( lower_s1 != to_char_type(*s2) )
     361               0 :               return to_int_type(lower_s1) - to_int_type(*s2);
     362                 :           }
     363                 : 
     364               0 :         if ( *s2 )
     365               0 :           return -1;
     366                 : 
     367               0 :         return 0;
     368                 :       }
     369                 : 
     370                 :     static
     371                 :     size_t
     372          503720 :     length( const char_type* s )
     373                 :       {
     374                 : #ifdef USE_CPP_WCHAR_FUNCS
     375                 :         return wcslen(s);
     376                 : #else
     377          503720 :         size_t result = 0;
     378        10735688 :         while ( !eq(*s++, char_type(0)) )
     379         9728248 :           ++result;
     380          503720 :         return result;
     381                 : #endif
     382                 :       }
     383                 : 
     384                 :     static
     385                 :     const char_type*
     386           89409 :     find( const char_type* s, size_t n, char_type c )
     387                 :       {
     388                 : #ifdef USE_CPP_WCHAR_FUNCS
     389                 :         return reinterpret_cast<const char_type*>(wmemchr(s, to_int_type(c), n));
     390                 : #else
     391         1021635 :         while ( n-- )
     392                 :           {
     393          885188 :             if ( eq(*s, c) )
     394           42371 :               return s;
     395          842817 :             ++s;
     396                 :           }
     397                 : 
     398           47038 :         return 0;
     399                 : #endif
     400                 :       }
     401                 : 
     402                 : #if 0
     403                 :       // I/O related:
     404                 : 
     405                 :     typedef streamoff off_type;
     406                 :     typedef streampos pos_type;
     407                 :     typedef mbstate_t state_type;
     408                 : 
     409                 :     static
     410                 :     int_type
     411                 :     eof()
     412                 :       {
     413                 : #ifdef USE_CPP_WCHAR_FUNCS
     414                 :         return WEOF;
     415                 : #else
     416                 :         return EOF;
     417                 : #endif
     418                 :       }
     419                 : 
     420                 :     static
     421                 :     int_type
     422                 :     not_eof( int_type c )
     423                 :       {
     424                 :         return eq_int_type(c, eof()) ? ~eof() : c;
     425                 :       }
     426                 : 
     427                 :     // static state_type get_state( pos_type );
     428                 : #endif
     429                 :   };
     430                 : 
     431                 : template <>
     432                 : struct nsCharTraits<char>
     433                 :   {
     434                 :     typedef char           char_type;
     435                 :     typedef unsigned char  unsigned_char_type;
     436                 :     typedef PRUnichar      incompatible_char_type;
     437                 : 
     438                 :     static char_type *sEmptyBuffer;
     439                 : 
     440                 :     static
     441                 :     void
     442                 :     assign( char_type& lhs, char_type rhs )
     443                 :       {
     444                 :         lhs = rhs;
     445                 :       }
     446                 : 
     447                 : 
     448                 :       // integer representation of characters:
     449                 : 
     450                 :     typedef int int_type;
     451                 : 
     452                 :     static
     453                 :     char_type
     454                 :     to_char_type( int_type c )
     455                 :       {
     456                 :         return char_type(c);
     457                 :       }
     458                 : 
     459                 :     static
     460                 :     int_type
     461         1833554 :     to_int_type( char_type c )
     462                 :       {
     463         1833554 :         return int_type( static_cast<unsigned_char_type>(c) );
     464                 :       }
     465                 : 
     466                 :     static
     467                 :     bool
     468                 :     eq_int_type( int_type lhs, int_type rhs )
     469                 :       {
     470                 :         return lhs == rhs;
     471                 :       }
     472                 : 
     473                 : 
     474                 :       // |char_type| comparisons:
     475                 : 
     476                 :     static
     477                 :     bool
     478                 :     eq( char_type lhs, char_type rhs )
     479                 :       {
     480                 :         return lhs == rhs;
     481                 :       }
     482                 : 
     483                 :     static
     484                 :     bool
     485                 :     lt( char_type lhs, char_type rhs )
     486                 :       {
     487                 :         return lhs < rhs;
     488                 :       }
     489                 : 
     490                 : 
     491                 :       // operations on s[n] arrays:
     492                 : 
     493                 :     static
     494                 :     char_type*
     495          186754 :     move( char_type* s1, const char_type* s2, size_t n )
     496                 :       {
     497          186754 :         return static_cast<char_type*>(memmove(s1, s2, n * sizeof(char_type)));
     498                 :       }
     499                 : 
     500                 :     static
     501                 :     char_type*
     502        15899423 :     copy( char_type* s1, const char_type* s2, size_t n )
     503                 :       {
     504        15899423 :         return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(char_type)));
     505                 :       }
     506                 : 
     507                 :     static
     508                 :     char_type*
     509          560049 :     copyASCII( char_type* s1, const char* s2, size_t n )
     510                 :       {
     511          560049 :         return copy(s1, s2, n);
     512                 :       }
     513                 : 
     514                 :     static
     515                 :     char_type*
     516                 :     assign( char_type* s, size_t n, char_type c )
     517                 :       {
     518                 :         return static_cast<char_type*>(memset(s, to_int_type(c), n));
     519                 :       }
     520                 : 
     521                 :     static
     522                 :     int
     523        38023262 :     compare( const char_type* s1, const char_type* s2, size_t n )
     524                 :       {
     525        38023262 :         return memcmp(s1, s2, n);
     526                 :       }
     527                 : 
     528                 :     static
     529                 :     int
     530          671323 :     compareASCII( const char_type* s1, const char* s2, size_t n )
     531                 :       {
     532                 : #ifdef DEBUG
     533         2361393 :         for (size_t i = 0; i < n; ++i)
     534                 :           {
     535         1690070 :             NS_ASSERTION(!(s2[i] & ~0x7F), "Unexpected non-ASCII character");
     536                 :           }
     537                 : #endif
     538          671323 :         return compare(s1, s2, n);
     539                 :       }
     540                 : 
     541                 :     // this version assumes that s2 is null-terminated and s1 has length n.
     542                 :     // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
     543                 :     // we return 1.
     544                 :     static
     545                 :     int
     546            7162 :     compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
     547                 :       {
     548                 :         // can't use strcmp here because we don't want to stop when s1
     549                 :         // contains a null
     550            7226 :         for ( ; n--; ++s1, ++s2 )
     551                 :           {
     552            7213 :             if ( !*s2 )
     553               9 :               return 1;
     554            7204 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     555            7204 :             if ( *s1 != *s2 )
     556            7140 :               return to_int_type(*s1) - to_int_type(*s2);
     557                 :           }
     558                 : 
     559              13 :         if ( *s2 )
     560               0 :           return -1;
     561                 : 
     562              13 :         return 0;
     563                 :       }
     564                 : 
     565                 :     /**
     566                 :      * Convert c to its lower-case form, but only if c is ASCII.
     567                 :      */
     568                 :     static
     569                 :     char_type
     570          129889 :     ASCIIToLower( char_type c )
     571                 :       {
     572          129889 :         if (c >= 'A' && c <= 'Z')
     573            1041 :           return char_type(c + ('a' - 'A'));
     574                 : 
     575          128848 :         return c;
     576                 :       }
     577                 : 
     578                 :     static
     579                 :     int
     580           31345 :     compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
     581                 :       {
     582          140222 :         for ( ; n--; ++s1, ++s2 )
     583                 :           {
     584          124453 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     585          124453 :             NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
     586                 :                          "Unexpected uppercase character");
     587          124453 :             char_type lower_s1 = ASCIIToLower(*s1);
     588          124453 :             if ( lower_s1 != *s2 )
     589           15576 :               return to_int_type(lower_s1) - to_int_type(*s2);
     590                 :           }
     591           15769 :         return 0;
     592                 :       }
     593                 : 
     594                 :     // this version assumes that s2 is null-terminated and s1 has length n.
     595                 :     // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
     596                 :     // we return 1.
     597                 :     static
     598                 :     int
     599            4061 :     compareLowerCaseToASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
     600                 :       {
     601            5974 :         for ( ; n--; ++s1, ++s2 )
     602                 :           {
     603            5443 :             if ( !*s2 )
     604               7 :               return 1;
     605            5436 :             NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
     606            5436 :             NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
     607                 :                          "Unexpected uppercase character");
     608            5436 :             char_type lower_s1 = ASCIIToLower(*s1);
     609            5436 :             if ( lower_s1 != *s2 )
     610            3523 :               return to_int_type(lower_s1) - to_int_type(*s2);
     611                 :           }
     612                 : 
     613             531 :         if ( *s2 )
     614               0 :           return -1;
     615                 : 
     616             531 :         return 0;
     617                 :       }
     618                 : 
     619                 :     static
     620                 :     size_t
     621        17371859 :     length( const char_type* s )
     622                 :       {
     623        17371859 :         return strlen(s);
     624                 :       }
     625                 : 
     626                 :     static
     627                 :     const char_type*
     628         1781076 :     find( const char_type* s, size_t n, char_type c )
     629                 :       {
     630         1781076 :         return reinterpret_cast<const char_type*>(memchr(s, to_int_type(c), n));
     631                 :       }
     632                 : 
     633                 : #if 0
     634                 :       // I/O related:
     635                 : 
     636                 :     typedef streamoff off_type;
     637                 :     typedef streampos pos_type;
     638                 :     typedef mbstate_t state_type;
     639                 : 
     640                 :     static
     641                 :     int_type
     642                 :     eof()
     643                 :       {
     644                 :         return EOF;
     645                 :       }
     646                 : 
     647                 :     static
     648                 :     int_type
     649                 :     not_eof( int_type c )
     650                 :       {
     651                 :         return eq_int_type(c, eof()) ? ~eof() : c;
     652                 :       }
     653                 : 
     654                 :     // static state_type get_state( pos_type );
     655                 : #endif
     656                 :   };
     657                 : 
     658                 : template <class InputIterator>
     659                 : struct nsCharSourceTraits
     660                 :   {
     661                 :     typedef typename InputIterator::difference_type difference_type;
     662                 : 
     663                 :     static
     664                 :     PRUint32
     665         5724295 :     readable_distance( const InputIterator& first, const InputIterator& last )
     666                 :       {
     667                 :         // assumes single fragment
     668         5724295 :         return PRUint32(last.get() - first.get());
     669                 :       }
     670                 : 
     671                 :     static
     672                 :     const typename InputIterator::value_type*
     673         5724295 :     read( const InputIterator& iter )
     674                 :       {
     675         5724295 :         return iter.get();
     676                 :       }
     677                 : 
     678                 :     static
     679                 :     void
     680                 :     advance( InputIterator& s, difference_type n )
     681                 :       {
     682                 :         s.advance(n);
     683                 :       }
     684                 :   };
     685                 : 
     686                 : #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
     687                 : 
     688                 : template <class CharT>
     689                 : struct nsCharSourceTraits<CharT*>
     690                 :   {
     691                 :     typedef ptrdiff_t difference_type;
     692                 : 
     693                 :     static
     694                 :     PRUint32
     695                 :     readable_distance( CharT* s )
     696                 :       {
     697                 :         return PRUint32(nsCharTraits<CharT>::length(s));
     698                 : //      return numeric_limits<PRUint32>::max();
     699                 :       }
     700                 : 
     701                 :     static
     702                 :     PRUint32
     703           20936 :     readable_distance( CharT* first, CharT* last )
     704                 :       {
     705           20936 :         return PRUint32(last-first);
     706                 :       }
     707                 : 
     708                 :     static
     709                 :     const CharT*
     710           20936 :     read( CharT* s )
     711                 :       {
     712           20936 :         return s;
     713                 :       }
     714                 : 
     715                 :     static
     716                 :     void
     717                 :     advance( CharT*& s, difference_type n )
     718                 :       {
     719                 :         s += n;
     720                 :       }
     721                 :   };
     722                 : 
     723                 : #else
     724                 : 
     725                 : template <>
     726                 : struct nsCharSourceTraits<const char*>
     727                 :   {
     728                 :     typedef ptrdiff_t difference_type;
     729                 : 
     730                 :     static
     731                 :     PRUint32
     732                 :     readable_distance( const char* s )
     733                 :       {
     734                 :         return PRUint32(nsCharTraits<char>::length(s));
     735                 : //      return numeric_limits<PRUint32>::max();
     736                 :       }
     737                 : 
     738                 :     static
     739                 :     PRUint32
     740                 :     readable_distance( const char* first, const char* last )
     741                 :       {
     742                 :         return PRUint32(last-first);
     743                 :       }
     744                 : 
     745                 :     static
     746                 :     const char*
     747                 :     read( const char* s )
     748                 :       {
     749                 :         return s;
     750                 :       }
     751                 : 
     752                 :     static
     753                 :     void
     754                 :     advance( const char*& s, difference_type n )
     755                 :       {
     756                 :         s += n;
     757                 :       }
     758                 :  };
     759                 : 
     760                 : 
     761                 : template <>
     762                 : struct nsCharSourceTraits<const PRUnichar*>
     763                 :   {
     764                 :     typedef ptrdiff_t difference_type;
     765                 : 
     766                 :     static
     767                 :     PRUint32
     768                 :     readable_distance( const PRUnichar* s )
     769                 :       {
     770                 :         return PRUint32(nsCharTraits<PRUnichar>::length(s));
     771                 : //      return numeric_limits<PRUint32>::max();
     772                 :       }
     773                 : 
     774                 :     static
     775                 :     PRUint32
     776                 :     readable_distance( const PRUnichar* first, const PRUnichar* last )
     777                 :       {
     778                 :         return PRUint32(last-first);
     779                 :       }
     780                 : 
     781                 :     static
     782                 :     const PRUnichar*
     783                 :     read( const PRUnichar* s )
     784                 :       {
     785                 :         return s;
     786                 :       }
     787                 : 
     788                 :     static
     789                 :     void
     790                 :     advance( const PRUnichar*& s, difference_type n )
     791                 :       {
     792                 :         s += n;
     793                 :       }
     794                 :  };
     795                 : 
     796                 : #endif
     797                 : 
     798                 : 
     799                 : template <class OutputIterator>
     800                 : struct nsCharSinkTraits
     801                 :   {
     802                 :     static
     803                 :     void
     804         4277217 :     write( OutputIterator& iter, const typename OutputIterator::value_type* s, PRUint32 n )
     805                 :       {
     806         1383391 :         iter.write(s, n);
     807         4277217 :       }
     808                 :   };
     809                 : 
     810                 : #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
     811                 : 
     812                 : template <class CharT>
     813                 : struct nsCharSinkTraits<CharT*>
     814                 :   {
     815                 :     static
     816                 :     void
     817         1472032 :     write( CharT*& iter, const CharT* s, PRUint32 n )
     818                 :       {
     819         1472032 :         nsCharTraits<CharT>::move(iter, s, n);
     820         1472032 :         iter += n;
     821         1472032 :       }
     822                 :   };
     823                 : 
     824                 : #else
     825                 : 
     826                 : template <>
     827                 : struct nsCharSinkTraits<char*>
     828                 :   {
     829                 :     static
     830                 :     void
     831                 :     write( char*& iter, const char* s, PRUint32 n )
     832                 :       {
     833                 :         nsCharTraits<char>::move(iter, s, n);
     834                 :         iter += n;
     835                 :       }
     836                 :   };
     837                 : 
     838                 : template <>
     839                 : struct nsCharSinkTraits<PRUnichar*>
     840                 :   {
     841                 :     static
     842                 :     void
     843                 :     write( PRUnichar*& iter, const PRUnichar* s, PRUint32 n )
     844                 :       {
     845                 :         nsCharTraits<PRUnichar>::move(iter, s, n);
     846                 :         iter += n;
     847                 :       }
     848                 :   };
     849                 : 
     850                 : #endif
     851                 : 
     852                 : #endif // !defined(nsCharTraits_h___)

Generated by: LCOV version 1.7