Ignore:
Timestamp:
Sep 23, 2008, 7:11:04 PM (13 years ago)
Author:
charles
Message:

run libT, cli, daemon, gtk through the source-code formatter "uncrustify" as promised/threatened

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/ConvertUTF.c

    r5810 r6795  
    11/*
    22 * Copyright 2001-2004 Unicode, Inc.
    3  * 
     3 *
    44 * Disclaimer
    5  * 
     5 *
    66 * This source code is provided as is by Unicode, Inc. No claims are
    77 * made as to fitness for any particular purpose. No warranties of any
     
    1111 * sole remedy for any claim will be exchange of defective media
    1212 * within 90 days of receipt.
    13  * 
     13 *
    1414 * Limitations on Rights to Redistribute This Code
    15  * 
     15 *
    1616 * Unicode, Inc. hereby grants the right to freely use the information
    1717 * supplied in this file in the creation of products supporting the
     
    2727    Rev History: Rick McGowan, fixes & updates May 2001.
    2828    Sept 2001: fixed const & error conditions per
    29         mods suggested by S. Parent & A. Lillich.
     29    mods suggested by S. Parent & A. Lillich.
    3030    June 2002: Tim Dodd added detection and handling of incomplete
    31         source sequences, enhanced error detection, added casts
    32         to eliminate compiler warnings.
     31    source sequences, enhanced error detection, added casts
     32    to eliminate compiler warnings.
    3333    July 2003: slight mods to back out aggressive FFFE detection.
    3434    Jan 2004: updated switches in from-UTF8 conversions.
     
    3737    See the header file "ConvertUTF.h" for complete documentation.
    3838
    39 ------------------------------------------------------------------------ */
     39   ------------------------------------------------------------------------ */
    4040
    4141
    4242#include "ConvertUTF.h"
    4343#ifdef CVTUTF_DEBUG
    44 #include <stdio.h>
     44 #include <stdio.h>
    4545#endif
    4646
    47 static const int halfShift  = 10; /* used for shifting by 10 bits */
     47static const int   halfShift  = 10; /* used for shifting by 10 bits */
    4848
    4949static const UTF32 halfBase = 0x0010000UL;
     
    5454#define UNI_SUR_LOW_START   (UTF32)0xDC00
    5555#define UNI_SUR_LOW_END     (UTF32)0xDFFF
    56 #define false      0
    57 #define true        1
    58 
    59 /* --------------------------------------------------------------------- */
    60 
    61 ConversionResult ConvertUTF32toUTF16 (
    62         const UTF32** sourceStart, const UTF32* sourceEnd,
    63         UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
     56#define false      0
     57#define true        1
     58
     59/* --------------------------------------------------------------------- */
     60
     61ConversionResult
     62ConvertUTF32toUTF16( const UTF32**   sourceStart,
     63                     const UTF32*    sourceEnd,
     64                     UTF16**         targetStart,
     65                     UTF16*          targetEnd,
     66                     ConversionFlags flags )
     67{
    6468    ConversionResult result = conversionOK;
    65     const UTF32* source = *sourceStart;
    66     UTF16* target = *targetStart;
    67     while (source < sourceEnd) {
    68         UTF32 ch;
    69         if (target >= targetEnd) {
    70             result = targetExhausted; break;
    71         }
    72         ch = *source++;
    73         if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
    74             /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
    75             if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
    76                 if (flags == strictConversion) {
    77                     --source; /* return to the illegal value itself */
    78                     result = sourceIllegal;
    79                     break;
    80                 } else {
    81                     *target++ = UNI_REPLACEMENT_CHAR;
    82                 }
    83             } else {
    84                 *target++ = (UTF16)ch; /* normal case */
    85             }
    86         } else if (ch > UNI_MAX_LEGAL_UTF32) {
    87             if (flags == strictConversion) {
    88                 result = sourceIllegal;
    89             } else {
    90                 *target++ = UNI_REPLACEMENT_CHAR;
    91             }
    92         } else {
    93             /* target is a character in range 0xFFFF - 0x10FFFF. */
    94             if (target + 1 >= targetEnd) {
    95                 --source; /* Back up source pointer! */
    96                 result = targetExhausted; break;
    97             }
    98             ch -= halfBase;
    99             *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
    100             *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
    101         }
    102     }
     69    const UTF32*     source = *sourceStart;
     70    UTF16*           target = *targetStart;
     71
     72    while( source < sourceEnd )
     73    {
     74        UTF32 ch;
     75        if( target >= targetEnd )
     76        {
     77            result = targetExhausted; break;
     78        }
     79        ch = *source++;
     80        if( ch <= UNI_MAX_BMP ) /* Target is a character <= 0xFFFF */
     81        { /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are
     82            both reserved values */
     83            if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END )
     84            {
     85                if( flags == strictConversion )
     86                {
     87                    --source; /* return to the illegal value itself */
     88                    result = sourceIllegal;
     89                    break;
     90                }
     91                else
     92                {
     93                    *target++ = UNI_REPLACEMENT_CHAR;
     94                }
     95            }
     96            else
     97            {
     98                *target++ = (UTF16)ch; /* normal case */
     99            }
     100        }
     101        else if( ch > UNI_MAX_LEGAL_UTF32 )
     102        {
     103            if( flags == strictConversion )
     104            {
     105                result = sourceIllegal;
     106            }
     107            else
     108            {
     109                *target++ = UNI_REPLACEMENT_CHAR;
     110            }
     111        }
     112        else
     113        {
     114            /* target is a character in range 0xFFFF - 0x10FFFF. */
     115            if( target + 1 >= targetEnd )
     116            {
     117                --source; /* Back up source pointer! */
     118                result = targetExhausted; break;
     119            }
     120            ch -= halfBase;
     121            *target++ = (UTF16)( ( ch >> halfShift ) + UNI_SUR_HIGH_START );
     122            *target++ = (UTF16)( ( ch & halfMask ) + UNI_SUR_LOW_START );
     123        }
     124    }
     125
    103126    *sourceStart = source;
    104127    *targetStart = target;
     
    108131/* --------------------------------------------------------------------- */
    109132
    110 ConversionResult ConvertUTF16toUTF32 (
    111         const UTF16** sourceStart, const UTF16* sourceEnd,
    112         UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
     133ConversionResult
     134ConvertUTF16toUTF32( const UTF16**   sourceStart,
     135                     const UTF16*    sourceEnd,
     136                     UTF32**         targetStart,
     137                     UTF32*          targetEnd,
     138                     ConversionFlags flags )
     139{
    113140    ConversionResult result = conversionOK;
    114     const UTF16* source = *sourceStart;
    115     UTF32* target = *targetStart;
    116     UTF32 ch, ch2;
    117     while (source < sourceEnd) {
    118         const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
    119         ch = *source++;
    120         /* If we have a surrogate pair, convert to UTF32 first. */
    121         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
    122             /* If the 16 bits following the high surrogate are in the source buffer... */
    123             if (source < sourceEnd) {
    124                 ch2 = *source;
    125                 /* If it's a low surrogate, convert to UTF32. */
    126                 if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
    127                     ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
    128                         + (ch2 - UNI_SUR_LOW_START) + halfBase;
    129                     ++source;
    130                 } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
    131                     --source; /* return to the illegal value itself */
    132                     result = sourceIllegal;
    133                     break;
    134                 }
    135             } else { /* We don't have the 16 bits following the high surrogate. */
    136                 --source; /* return to the high surrogate */
    137                 result = sourceExhausted;
    138                 break;
    139             }
    140         } else if (flags == strictConversion) {
    141             /* UTF-16 surrogate values are illegal in UTF-32 */
    142             if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
    143                 --source; /* return to the illegal value itself */
    144                 result = sourceIllegal;
    145                 break;
    146             }
    147         }
    148         if (target >= targetEnd) {
    149             source = oldSource; /* Back up source pointer! */
    150             result = targetExhausted; break;
    151         }
    152         *target++ = ch;
    153     }
     141    const UTF16*     source = *sourceStart;
     142    UTF32*           target = *targetStart;
     143    UTF32            ch, ch2;
     144
     145    while( source < sourceEnd )
     146    {
     147        const UTF16* oldSource = source; /*  In case we have to back up because
     148                                           of target overflow. */
     149        ch = *source++;
     150        /* If we have a surrogate pair, convert to UTF32 first. */
     151        if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END )
     152        {
     153            /* If the 16 bits following the high surrogate are in the source
     154              buffer... */
     155            if( source < sourceEnd )
     156            {
     157                ch2 = *source;
     158                /* If it's a low surrogate, convert to UTF32. */
     159                if( ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END )
     160                {
     161                    ch = ( ( ch - UNI_SUR_HIGH_START ) << halfShift )
     162                         + ( ch2 - UNI_SUR_LOW_START ) + halfBase;
     163                    ++source;
     164                }
     165                else if( flags == strictConversion ) /* it's an unpaired high
     166                                                       surrogate */
     167                {
     168                    --source; /* return to the illegal value itself */
     169                    result = sourceIllegal;
     170                    break;
     171                }
     172            }
     173            else /* We don't have the 16 bits following the high surrogate. */
     174            {
     175                --source; /* return to the high surrogate */
     176                result = sourceExhausted;
     177                break;
     178            }
     179        }
     180        else if( flags == strictConversion )
     181        {
     182            /* UTF-16 surrogate values are illegal in UTF-32 */
     183            if( ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END )
     184            {
     185                --source; /* return to the illegal value itself */
     186                result = sourceIllegal;
     187                break;
     188            }
     189        }
     190        if( target >= targetEnd )
     191        {
     192            source = oldSource; /* Back up source pointer! */
     193            result = targetExhausted; break;
     194        }
     195        *target++ = ch;
     196    }
     197
    154198    *sourceStart = source;
    155199    *targetStart = target;
    156200#ifdef CVTUTF_DEBUG
    157 if (result == sourceIllegal) {
    158     fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
    159     fflush(stderr);
    160 }
     201    if( result == sourceIllegal )
     202    {
     203        fprintf( stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n",
     204                 ch,
     205                 ch2 );
     206        fflush( stderr );
     207    }
    161208#endif
    162209    return result;
     
    172219 * allowed in earlier algorithms.
    173220 */
    174 static const char trailingBytesForUTF8[256] = {
    175     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    176     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    177     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    178     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    179     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    180     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    181     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    182     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
     221static const char  trailingBytesForUTF8[256] = {
     222    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     223    0, 0, 0, 0, 0, 0, 0, 0,
     224    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     225    0, 0, 0, 0, 0, 0, 0, 0,
     226    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     227    0, 0, 0, 0, 0, 0, 0, 0,
     228    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     229    0, 0, 0, 0, 0, 0, 0, 0,
     230    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     231    0, 0, 0, 0, 0, 0, 0, 0,
     232    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     233    0, 0, 0, 0, 0, 0, 0, 0,
     234    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     235    1, 1, 1, 1, 1, 1, 1, 1,
     236    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
     237    4, 4, 4, 4, 5, 5, 5, 5
    183238};
    184239
     
    188243 * in a UTF-8 sequence.
    189244 */
    190 static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
    191                      0x03C82080UL, 0xFA082080UL, 0x82082080UL };
     245static const UTF32 offsetsFromUTF8[6] =
     246{ 0x00000000UL,                                           0x00003080UL,
     247  0x000E2080UL,
     248  0x03C82080UL, 0xFA082080UL,
     249  0x82082080UL };
    192250
    193251/*
     
    198256 * for *legal* UTF-8 will be 4 or fewer bytes total.
    199257 */
    200 static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
     258static const UTF8  firstByteMark[7] =
     259{ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
    201260
    202261/* --------------------------------------------------------------------- */
     
    212271/* --------------------------------------------------------------------- */
    213272
    214 ConversionResult ConvertUTF16toUTF8 (
    215         const UTF16** sourceStart, const UTF16* sourceEnd,
    216         UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
     273ConversionResult
     274ConvertUTF16toUTF8( const UTF16**   sourceStart,
     275                    const UTF16*    sourceEnd,
     276                    UTF8**          targetStart,
     277                    UTF8*           targetEnd,
     278                    ConversionFlags flags )
     279{
    217280    ConversionResult result = conversionOK;
    218     const UTF16* source = *sourceStart;
    219     UTF8* target = *targetStart;
    220     while (source < sourceEnd) {
    221         UTF32 ch;
    222         unsigned short bytesToWrite = 0;
    223         const UTF32 byteMask = 0xBF;
    224         const UTF32 byteMark = 0x80;
    225         const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
    226         ch = *source++;
    227         /* If we have a surrogate pair, convert to UTF32 first. */
    228         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
    229             /* If the 16 bits following the high surrogate are in the source buffer... */
    230             if (source < sourceEnd) {
    231                 UTF32 ch2 = *source;
    232                 /* If it's a low surrogate, convert to UTF32. */
    233                 if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
    234                     ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
    235                         + (ch2 - UNI_SUR_LOW_START) + halfBase;
    236                     ++source;
    237                 } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
    238                     --source; /* return to the illegal value itself */
    239                     result = sourceIllegal;
    240                     break;
    241                 }
    242             } else { /* We don't have the 16 bits following the high surrogate. */
    243                 --source; /* return to the high surrogate */
    244                 result = sourceExhausted;
    245                 break;
    246             }
    247         } else if (flags == strictConversion) {
    248             /* UTF-16 surrogate values are illegal in UTF-32 */
    249             if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
    250                 --source; /* return to the illegal value itself */
    251                 result = sourceIllegal;
    252                 break;
    253             }
    254         }
    255         /* Figure out how many bytes the result will require */
    256         if (ch < (UTF32)0x80) {      bytesToWrite = 1;
    257         } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
    258         } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
    259         } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
    260         } else {                            bytesToWrite = 3;
    261                                             ch = UNI_REPLACEMENT_CHAR;
    262         }
    263 
    264         target += bytesToWrite;
    265         if (target > targetEnd) {
    266             source = oldSource; /* Back up source pointer! */
    267             target -= bytesToWrite; result = targetExhausted; break;
    268         }
    269         switch (bytesToWrite) { /* note: everything falls through. */
    270             case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    271             case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    272             case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    273             case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
    274         }
    275         target += bytesToWrite;
    276     }
     281    const UTF16*     source = *sourceStart;
     282    UTF8*            target = *targetStart;
     283
     284    while( source < sourceEnd )
     285    {
     286        UTF32          ch;
     287        unsigned short bytesToWrite = 0;
     288        const UTF32    byteMask = 0xBF;
     289        const UTF32    byteMark = 0x80;
     290        const UTF16*   oldSource = source; /* In case we have to back up because
     291                                             of target overflow. */
     292        ch = *source++;
     293        /* If we have a surrogate pair, convert to UTF32 first. */
     294        if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END )
     295        {
     296            /* If the 16 bits following the high surrogate are in the source
     297              buffer... */
     298            if( source < sourceEnd )
     299            {
     300                UTF32 ch2 = *source;
     301                /* If it's a low surrogate, convert to UTF32. */
     302                if( ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END )
     303                {
     304                    ch = ( ( ch - UNI_SUR_HIGH_START ) << halfShift )
     305                         + ( ch2 - UNI_SUR_LOW_START ) + halfBase;
     306                    ++source;
     307                }
     308                else if( flags == strictConversion ) /* it's an unpaired high
     309                                                       surrogate */
     310                {
     311                    --source; /* return to the illegal value itself */
     312                    result = sourceIllegal;
     313                    break;
     314                }
     315            }
     316            else /* We don't have the 16 bits following the high surrogate. */
     317            {
     318                --source; /* return to the high surrogate */
     319                result = sourceExhausted;
     320                break;
     321            }
     322        }
     323        else if( flags == strictConversion )
     324        {
     325            /* UTF-16 surrogate values are illegal in UTF-32 */
     326            if( ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END )
     327            {
     328                --source; /* return to the illegal value itself */
     329                result = sourceIllegal;
     330                break;
     331            }
     332        }
     333        /* Figure out how many bytes the result will require */
     334        if( ch < (UTF32)0x80 )
     335        {
     336            bytesToWrite = 1;
     337        }
     338        else if( ch < (UTF32)0x800 )
     339        {
     340            bytesToWrite = 2;
     341        }
     342        else if( ch < (UTF32)0x10000 )
     343        {
     344            bytesToWrite = 3;
     345        }
     346        else if( ch < (UTF32)0x110000 )
     347        {
     348            bytesToWrite = 4;
     349        }
     350        else
     351        {
     352            bytesToWrite = 3;
     353            ch = UNI_REPLACEMENT_CHAR;
     354        }
     355
     356        target += bytesToWrite;
     357        if( target > targetEnd )
     358        {
     359            source = oldSource; /* Back up source pointer! */
     360            target -= bytesToWrite; result = targetExhausted; break;
     361        }
     362        switch( bytesToWrite ) /* note: everything falls through. */
     363        {
     364            case 4:
     365                *--target =
     366                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     367
     368            case 3:
     369                *--target =
     370                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     371
     372            case 2:
     373                *--target =
     374                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     375
     376            case 1:
     377                *--target =  (UTF8)( ch | firstByteMark[bytesToWrite] );
     378        }
     379        target += bytesToWrite;
     380    }
     381
    277382    *sourceStart = source;
    278383    *targetStart = target;
     
    293398 */
    294399
    295 static Boolean isLegalUTF8(const UTF8 *source, int length) {
    296     UTF8 a;
    297     const UTF8 *srcptr = source+length;
    298     switch (length) {
    299     default: return false;
    300         /* Everything else falls through when "true"... */
    301     case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
    302     case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
    303     case 2: if ((a = (*--srcptr)) > 0xBF) return false;
    304 
    305         switch (*source) {
    306             /* no fall-through in this inner switch */
    307             case 0xE0: if (a < 0xA0) return false; break;
    308             case 0xED: if (a > 0x9F) return false; break;
    309             case 0xF0: if (a < 0x90) return false; break;
    310             case 0xF4: if (a > 0x8F) return false; break;
    311             default:   if (a < 0x80) return false;
    312         }
    313 
    314     case 1: if (*source >= 0x80 && *source < 0xC2) return false;
    315     }
    316     if (*source > 0xF4) return false;
     400static Boolean
     401isLegalUTF8( const UTF8 *source,
     402             int         length )
     403{
     404    UTF8        a;
     405    const UTF8 *srcptr = source + length;
     406
     407    switch( length )
     408    {
     409        default:
     410            return false;
     411
     412        /* Everything else falls through when "true"... */
     413        case 4:
     414            if( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return false;
     415
     416        case 3:
     417            if( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return false;
     418
     419        case 2:
     420            if( ( a = ( *--srcptr ) ) > 0xBF ) return false;
     421
     422            switch( *source )
     423            {
     424                /* no fall-through in this inner switch */
     425                case 0xE0:
     426                    if( a < 0xA0 ) return false;break;
     427
     428                case 0xED:
     429                    if( a > 0x9F ) return false;break;
     430
     431                case 0xF0:
     432                    if( a < 0x90 ) return false;break;
     433
     434                case 0xF4:
     435                    if( a > 0x8F ) return false;break;
     436
     437                default:
     438                    if( a < 0x80 ) return false;
     439            }
     440
     441        case 1:
     442            if( *source >= 0x80 && *source < 0xC2 ) return false;
     443    }
     444    if( *source > 0xF4 ) return false;
    317445    return true;
    318446}
     
    324452 * This is not used here; it's just exported.
    325453 */
    326 Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
    327     int length = trailingBytesForUTF8[*source]+1;
    328     if (source+length > sourceEnd) {
    329         return false;
    330     }
    331     return isLegalUTF8(source, length);
     454Boolean
     455isLegalUTF8Sequence( const UTF8 *source,
     456                     const UTF8 *sourceEnd )
     457{
     458    int length = trailingBytesForUTF8[*source] + 1;
     459
     460    if( source + length > sourceEnd )
     461    {
     462        return false;
     463    }
     464    return isLegalUTF8( source, length );
    332465}
    333466
    334467/* --------------------------------------------------------------------- */
    335468
    336 ConversionResult ConvertUTF8toUTF16 (
    337         const UTF8** sourceStart, const UTF8* sourceEnd,
    338         UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
     469ConversionResult
     470ConvertUTF8toUTF16( const UTF8**    sourceStart,
     471                    const UTF8*     sourceEnd,
     472                    UTF16**         targetStart,
     473                    UTF16*          targetEnd,
     474                    ConversionFlags flags )
     475{
    339476    ConversionResult result = conversionOK;
    340     const UTF8* source = *sourceStart;
    341     UTF16* target = *targetStart;
    342     while (source < sourceEnd) {
    343         UTF32 ch = 0;
    344         unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
    345         if (source + extraBytesToRead >= sourceEnd) {
    346             result = sourceExhausted; break;
    347         }
    348         /* Do this check whether lenient or strict */
    349         if (! isLegalUTF8(source, extraBytesToRead+1)) {
    350             result = sourceIllegal;
    351             break;
    352         }
    353         /*
    354          * The cases all fall through. See "Note A" below.
    355          */
    356         switch (extraBytesToRead) {
    357             case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
    358             case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
    359             case 3: ch += *source++; ch <<= 6;
    360             case 2: ch += *source++; ch <<= 6;
    361             case 1: ch += *source++; ch <<= 6;
    362             case 0: ch += *source++;
    363         }
    364         ch -= offsetsFromUTF8[extraBytesToRead];
    365 
    366         if (target >= targetEnd) {
    367             source -= (extraBytesToRead+1); /* Back up source pointer! */
    368             result = targetExhausted; break;
    369         }
    370         if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
    371             /* UTF-16 surrogate values are illegal in UTF-32 */
    372             if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
    373                 if (flags == strictConversion) {
    374                     source -= (extraBytesToRead+1); /* return to the illegal value itself */
    375                     result = sourceIllegal;
    376                     break;
    377                 } else {
    378                     *target++ = UNI_REPLACEMENT_CHAR;
    379                 }
    380             } else {
    381                 *target++ = (UTF16)ch; /* normal case */
    382             }
    383         } else if (ch > UNI_MAX_UTF16) {
    384             if (flags == strictConversion) {
    385                 result = sourceIllegal;
    386                 source -= (extraBytesToRead+1); /* return to the start */
    387                 break; /* Bail out; shouldn't continue */
    388             } else {
    389                 *target++ = UNI_REPLACEMENT_CHAR;
    390             }
    391         } else {
    392             /* target is a character in range 0xFFFF - 0x10FFFF. */
    393             if (target + 1 >= targetEnd) {
    394                 source -= (extraBytesToRead+1); /* Back up source pointer! */
    395                 result = targetExhausted; break;
    396             }
    397             ch -= halfBase;
    398             *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
    399             *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
    400         }
    401     }
     477    const UTF8*      source = *sourceStart;
     478    UTF16*           target = *targetStart;
     479
     480    while( source < sourceEnd )
     481    {
     482        UTF32          ch = 0;
     483        unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
     484        if( source + extraBytesToRead >= sourceEnd )
     485        {
     486            result = sourceExhausted; break;
     487        }
     488        /* Do this check whether lenient or strict */
     489        if( !isLegalUTF8( source, extraBytesToRead + 1 ) )
     490        {
     491            result = sourceIllegal;
     492            break;
     493        }
     494        /*
     495         * The cases all fall through. See "Note A" below.
     496         */
     497        switch( extraBytesToRead )
     498        {
     499            case 5:
     500                ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
     501
     502            case 4:
     503                ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
     504
     505            case 3:
     506                ch += *source++; ch <<= 6;
     507
     508            case 2:
     509                ch += *source++; ch <<= 6;
     510
     511            case 1:
     512                ch += *source++; ch <<= 6;
     513
     514            case 0:
     515                ch += *source++;
     516        }
     517        ch -= offsetsFromUTF8[extraBytesToRead];
     518
     519        if( target >= targetEnd )
     520        {
     521            source -= ( extraBytesToRead + 1 ); /* Back up source pointer! */
     522            result = targetExhausted; break;
     523        }
     524        if( ch <= UNI_MAX_BMP ) /* Target is a character <= 0xFFFF */
     525        { /* UTF-16 surrogate values are illegal in UTF-32 */
     526            if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END )
     527            {
     528                if( flags == strictConversion )
     529                {
     530                    source -= ( extraBytesToRead + 1 ); /* return to the illegal
     531                                                          value itself */
     532                    result = sourceIllegal;
     533                    break;
     534                }
     535                else
     536                {
     537                    *target++ = UNI_REPLACEMENT_CHAR;
     538                }
     539            }
     540            else
     541            {
     542                *target++ = (UTF16)ch; /* normal case */
     543            }
     544        }
     545        else if( ch > UNI_MAX_UTF16 )
     546        {
     547            if( flags == strictConversion )
     548            {
     549                result = sourceIllegal;
     550                source -= ( extraBytesToRead + 1 ); /* return to the start */
     551                break; /* Bail out; shouldn't continue */
     552            }
     553            else
     554            {
     555                *target++ = UNI_REPLACEMENT_CHAR;
     556            }
     557        }
     558        else
     559        {
     560            /* target is a character in range 0xFFFF - 0x10FFFF. */
     561            if( target + 1 >= targetEnd )
     562            {
     563                source -= ( extraBytesToRead + 1 ); /* Back up source pointer!
     564                                                      */
     565                result = targetExhausted; break;
     566            }
     567            ch -= halfBase;
     568            *target++ = (UTF16)( ( ch >> halfShift ) + UNI_SUR_HIGH_START );
     569            *target++ = (UTF16)( ( ch & halfMask ) + UNI_SUR_LOW_START );
     570        }
     571    }
     572
    402573    *sourceStart = source;
    403574    *targetStart = target;
     
    407578/* --------------------------------------------------------------------- */
    408579
    409 ConversionResult ConvertUTF32toUTF8 (
    410         const UTF32** sourceStart, const UTF32* sourceEnd,
    411         UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
     580ConversionResult
     581ConvertUTF32toUTF8( const UTF32**   sourceStart,
     582                    const UTF32*    sourceEnd,
     583                    UTF8**          targetStart,
     584                    UTF8*           targetEnd,
     585                    ConversionFlags flags )
     586{
    412587    ConversionResult result = conversionOK;
    413     const UTF32* source = *sourceStart;
    414     UTF8* target = *targetStart;
    415     while (source < sourceEnd) {
    416         UTF32 ch;
    417         unsigned short bytesToWrite = 0;
    418         const UTF32 byteMask = 0xBF;
    419         const UTF32 byteMark = 0x80;
    420         ch = *source++;
    421         if (flags == strictConversion ) {
    422             /* UTF-16 surrogate values are illegal in UTF-32 */
    423             if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
    424                 --source; /* return to the illegal value itself */
    425                 result = sourceIllegal;
    426                 break;
    427             }
    428         }
    429         /*
    430          * Figure out how many bytes the result will require. Turn any
    431          * illegally large UTF32 things (> Plane 17) into replacement chars.
    432          */
    433         if (ch < (UTF32)0x80) {      bytesToWrite = 1;
    434         } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
    435         } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
    436         } else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
    437         } else {                            bytesToWrite = 3;
    438                                             ch = UNI_REPLACEMENT_CHAR;
    439                                             result = sourceIllegal;
    440         }
    441        
    442         target += bytesToWrite;
    443         if (target > targetEnd) {
    444             --source; /* Back up source pointer! */
    445             target -= bytesToWrite; result = targetExhausted; break;
    446         }
    447         switch (bytesToWrite) { /* note: everything falls through. */
    448             case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    449             case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    450             case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
    451             case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
    452         }
    453         target += bytesToWrite;
    454     }
     588    const UTF32*     source = *sourceStart;
     589    UTF8*            target = *targetStart;
     590
     591    while( source < sourceEnd )
     592    {
     593        UTF32          ch;
     594        unsigned short bytesToWrite = 0;
     595        const UTF32    byteMask = 0xBF;
     596        const UTF32    byteMark = 0x80;
     597        ch = *source++;
     598        if( flags == strictConversion )
     599        {
     600            /* UTF-16 surrogate values are illegal in UTF-32 */
     601            if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END )
     602            {
     603                --source; /* return to the illegal value itself */
     604                result = sourceIllegal;
     605                break;
     606            }
     607        }
     608        /*
     609         * Figure out how many bytes the result will require. Turn any
     610         * illegally large UTF32 things (> Plane 17) into replacement chars.
     611         */
     612        if( ch < (UTF32)0x80 )
     613        {
     614            bytesToWrite = 1;
     615        }
     616        else if( ch < (UTF32)0x800 )
     617        {
     618            bytesToWrite = 2;
     619        }
     620        else if( ch < (UTF32)0x10000 )
     621        {
     622            bytesToWrite = 3;
     623        }
     624        else if( ch <= UNI_MAX_LEGAL_UTF32 )
     625        {
     626            bytesToWrite = 4;
     627        }
     628        else
     629        {
     630            bytesToWrite = 3;
     631            ch = UNI_REPLACEMENT_CHAR;
     632            result = sourceIllegal;
     633        }
     634
     635        target += bytesToWrite;
     636        if( target > targetEnd )
     637        {
     638            --source; /* Back up source pointer! */
     639            target -= bytesToWrite; result = targetExhausted; break;
     640        }
     641        switch( bytesToWrite ) /* note: everything falls through. */
     642        {
     643            case 4:
     644                *--target =
     645                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     646
     647            case 3:
     648                *--target =
     649                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     650
     651            case 2:
     652                *--target =
     653                    (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6;
     654
     655            case 1:
     656                *--target = (UTF8) ( ch | firstByteMark[bytesToWrite] );
     657        }
     658        target += bytesToWrite;
     659    }
     660
    455661    *sourceStart = source;
    456662    *targetStart = target;
     
    460666/* --------------------------------------------------------------------- */
    461667
    462 ConversionResult ConvertUTF8toUTF32 (
    463         const UTF8** sourceStart, const UTF8* sourceEnd,
    464         UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
     668ConversionResult
     669ConvertUTF8toUTF32( const UTF8**    sourceStart,
     670                    const UTF8*     sourceEnd,
     671                    UTF32**         targetStart,
     672                    UTF32*          targetEnd,
     673                    ConversionFlags flags )
     674{
    465675    ConversionResult result = conversionOK;
    466     const UTF8* source = *sourceStart;
    467     UTF32* target = *targetStart;
    468     while (source < sourceEnd) {
    469         UTF32 ch = 0;
    470         unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
    471         if (source + extraBytesToRead >= sourceEnd) {
    472             result = sourceExhausted; break;
    473         }
    474         /* Do this check whether lenient or strict */
    475         if (! isLegalUTF8(source, extraBytesToRead+1)) {
    476             result = sourceIllegal;
    477             break;
    478         }
    479         /*
    480          * The cases all fall through. See "Note A" below.
    481          */
    482         switch (extraBytesToRead) {
    483             case 5: ch += *source++; ch <<= 6;
    484             case 4: ch += *source++; ch <<= 6;
    485             case 3: ch += *source++; ch <<= 6;
    486             case 2: ch += *source++; ch <<= 6;
    487             case 1: ch += *source++; ch <<= 6;
    488             case 0: ch += *source++;
    489         }
    490         ch -= offsetsFromUTF8[extraBytesToRead];
    491 
    492         if (target >= targetEnd) {
    493             source -= (extraBytesToRead+1); /* Back up the source pointer! */
    494             result = targetExhausted; break;
    495         }
    496         if (ch <= UNI_MAX_LEGAL_UTF32) {
    497             /*
    498              * UTF-16 surrogate values are illegal in UTF-32, and anything
    499              * over Plane 17 (> 0x10FFFF) is illegal.
    500              */
    501             if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
    502                 if (flags == strictConversion) {
    503                     source -= (extraBytesToRead+1); /* return to the illegal value itself */
    504                     result = sourceIllegal;
    505                     break;
    506                 } else {
    507                     *target++ = UNI_REPLACEMENT_CHAR;
    508                 }
    509             } else {
    510                 *target++ = ch;
    511             }
    512         } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
    513             result = sourceIllegal;
    514             *target++ = UNI_REPLACEMENT_CHAR;
    515         }
    516     }
     676    const UTF8*      source = *sourceStart;
     677    UTF32*           target = *targetStart;
     678
     679    while( source < sourceEnd )
     680    {
     681        UTF32          ch = 0;
     682        unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
     683        if( source + extraBytesToRead >= sourceEnd )
     684        {
     685            result = sourceExhausted; break;
     686        }
     687        /* Do this check whether lenient or strict */
     688        if( !isLegalUTF8( source, extraBytesToRead + 1 ) )
     689        {
     690            result = sourceIllegal;
     691            break;
     692        }
     693        /*
     694         * The cases all fall through. See "Note A" below.
     695         */
     696        switch( extraBytesToRead )
     697        {
     698            case 5:
     699                ch += *source++; ch <<= 6;
     700
     701            case 4:
     702                ch += *source++; ch <<= 6;
     703
     704            case 3:
     705                ch += *source++; ch <<= 6;
     706
     707            case 2:
     708                ch += *source++; ch <<= 6;
     709
     710            case 1:
     711                ch += *source++; ch <<= 6;
     712
     713            case 0:
     714                ch += *source++;
     715        }
     716        ch -= offsetsFromUTF8[extraBytesToRead];
     717
     718        if( target >= targetEnd )
     719        {
     720            source -= ( extraBytesToRead + 1 ); /* Back up the source pointer!
     721                                                  */
     722            result = targetExhausted; break;
     723        }
     724        if( ch <= UNI_MAX_LEGAL_UTF32 )
     725        {
     726            /*
     727             * UTF-16 surrogate values are illegal in UTF-32, and anything
     728             * over Plane 17 (> 0x10FFFF) is illegal.
     729             */
     730            if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END )
     731            {
     732                if( flags == strictConversion )
     733                {
     734                    source -= ( extraBytesToRead + 1 ); /* return to the illegal
     735                                                          value itself */
     736                    result = sourceIllegal;
     737                    break;
     738                }
     739                else
     740                {
     741                    *target++ = UNI_REPLACEMENT_CHAR;
     742                }
     743            }
     744            else
     745            {
     746                *target++ = ch;
     747            }
     748        }
     749        else /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
     750        {
     751            result = sourceIllegal;
     752            *target++ = UNI_REPLACEMENT_CHAR;
     753        }
     754    }
     755
    517756    *sourceStart = source;
    518757    *targetStart = target;
     
    526765    temp variable, some decrements & conditionals.  The switches
    527766    are equivalent to the following loop:
    528         {
    529             int tmpBytesToRead = extraBytesToRead+1;
    530             do {
    531                 ch += *source++;
    532                 --tmpBytesToRead;
    533                 if (tmpBytesToRead) ch <<= 6;
    534             } while (tmpBytesToRead > 0);
    535         }
     767    {
     768        int tmpBytesToRead = extraBytesToRead+1;
     769        do {
     770        ch += *source++;
     771        --tmpBytesToRead;
     772        if (tmpBytesToRead) ch <<= 6;
     773        } while (tmpBytesToRead > 0);
     774    }
    536775    In UTF-8 writing code, the switches on "bytesToWrite" are
    537776    similarly unrolled loops.
Note: See TracChangeset for help on using the changeset viewer.