Show
Ignore:
Timestamp:
08/25/07 22:49:09 (15 months ago)
Author:
krobillard
Message:

UTF-8 strings can now be read.
ur_makeString() now takes UCell argument.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/thune/thread_safe/make.c

    r452 r453  
    11/*============================================================================ 
    22    Thune Interpreter 
    3     Copyright (C) 2005-2006  Karl Robillard 
     3    Copyright (C) 2005-2007  Karl Robillard 
    44 
    55    This library is free software; you can redistribute it and/or 
     
    335335 
    336336 
    337 #ifndef UR_CONFIG_UDS 
    338337/* 
    339338   Create context from initializer block. 
     
    458457    } 
    459458} 
    460 #endif 
    461459 
    462460 
     
    614612 
    615613 
     614/* 
     615   Convert UTF-8 to UCS-2 
     616*/ 
     617static void _makeString16( UBinary* str, const uint8_t* cp, int len ) 
     618{ 
     619    uint16_t  ch; 
     620    uint16_t* out; 
     621    const uint8_t* end; 
     622 
     623    ur_arrayReserve( str, 1, len * sizeof(uint16_t) ); 
     624    out = str->ptr.u16; 
     625 
     626    end = cp + len; 
     627    while( cp != end ) 
     628    { 
     629        ch = *cp++; 
     630 
     631        if( ch <= 0x7f ) 
     632        { 
     633            *out++ = ch; 
     634        } 
     635        else if( ch >= 0xc2 && ch <= 0xdf ) 
     636        { 
     637            if( cp != end ) 
     638            { 
     639                *out++ = ((ch & 0x1f) << 6) | (*cp & 0x3f); 
     640                ++cp; 
     641            } 
     642        } 
     643        else if( ch >= 0xe0 && ch <= 0xef ) 
     644        { 
     645            if( (end - cp) < 2 ) 
     646                break; 
     647            *out++ = ((ch    & 0x0f) << 12) | 
     648                     ((cp[0] & 0x3f) <<  6) | 
     649                      (cp[1] & 0x3f); 
     650            cp += 2; 
     651        } 
     652        else if( ch >= 0xf0 && ch <= 0xf3 ) 
     653        { 
     654            if( (end - cp) < 3 ) 
     655                break; 
     656            *out++ = 0;     // Only handle UCS-2 
     657            cp += 3; 
     658        } 
     659    } 
     660 
     661    str->avail /= 2; 
     662    str->used = out - str->ptr.u16; 
     663} 
     664 
     665 
    616666/** 
    617667  If len is less than zero then the length is automatically determined. 
    618668  Special characters are translated. 
    619669*/ 
    620 UIndex ur_makeStringT( UThread* ut, const char* txt, int len ) 
     670UIndex ur_makeStringT( UThread* ut, UCell* res, const char* txt, int len ) 
    621671{ 
    622672    UIndex strN; 
     
    625675    const char* end; 
    626676    char* out; 
     677    int ch; 
    627678 
    628679    if( len == 0 ) 
    629680    { 
    630         return ur_makeBinary( 0, 0 ); 
     681        strN = ur_makeBinary( 0, 0 ); 
     682        goto init; 
    631683    } 
    632684 
     
    653705        else 
    654706        { 
    655             *out++ = *cp++; 
     707            ch = *cp++; 
     708            if( ((unsigned int) ch) > 0x7f ) 
     709            { 
     710                _makeString16( str, (const uint8_t*) txt, len ); 
     711                ur_initString( res, strN, 0 ); 
     712                ur_setEncoding( res, UR_ENC_UTF16 ); 
     713                return strN; 
     714            } 
     715            *out++ = ch; 
    656716        } 
    657717    } 
    658718 
    659719    str->used = out - str->ptr.c; 
    660  
    661720    str->ptr.c[ str->used ] = '\0'; 
     721 
     722init: 
     723 
     724    ur_initString( res, strN, 0 ); 
    662725    return strN; 
    663726} 
     
    13261389 
    13271390 
    1328 #ifndef UR_CONFIG_UDS 
    13291391/* 
    13301392  (datatype! proto -- value) 
     
    17201782            { 
    17211783                if( spA ) 
    1722                     binN = ur_makeString( spA, spB - spA ); 
     1784                { 
     1785                    binN = ur_makeString( res, spA, spB - spA ); 
     1786                } 
    17231787                else 
     1788                { 
    17241789                    binN = ur_makeBinary( 0, 0 ); 
    17251790init_str: 
    1726                 ur_initString( res, binN, 0 ); 
     1791                    ur_initString( res, binN, 0 ); 
     1792                } 
    17271793            } 
    17281794        } 
     
    18711937    ur_throwErr( UR_ERR_DATATYPE, "Invalid make values" ); 
    18721938} 
    1873 #endif 
    18741939 
    18751940