Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 5349

Show
Ignore:
Timestamp:
02/07/10 13:42:00 (2 years ago)
Author:
h3r3tic
Message:

closes #1835; Thanks, darkdragon.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tango/core/rt/compiler/ldc/rt/lifetime.d

    r5248 r5349  
    894894 
    895895/** 
     896 * Append dchar to char[] 
     897 */ 
     898extern (C) char[] _d_arrayappendcd(ref char[] x, dchar c) 
     899{ 
     900    const sizeelem = c.sizeof;            // array element size 
     901    auto info = gc_query(x.ptr); 
     902    auto length = x.length; 
     903 
     904    // c could encode into from 1 to 4 characters 
     905    int nchars; 
     906    if (c <= 0x7F) 
     907        nchars = 1; 
     908    else if (c <= 0x7FF) 
     909        nchars = 2; 
     910    else if (c <= 0xFFFF) 
     911        nchars = 3; 
     912    else if (c <= 0x10FFFF) 
     913        nchars = 4; 
     914    else 
     915    assert(0);  // invalid utf character - should we throw an exception instead? 
     916 
     917    auto newlength = length + nchars; 
     918    auto newsize = newlength * sizeelem; 
     919 
     920    assert(info.size == 0 || length * sizeelem <= info.size); 
     921 
     922    debug(PRINTF) printf("_d_arrayappendcd(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size); 
     923 
     924    if (info.size <= newsize || info.base != x.ptr) 
     925    {   byte* newdata; 
     926 
     927        if (info.size >= PAGESIZE && info.base == x.ptr) 
     928        {   // Try to extend in-place 
     929            auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size); 
     930            if (u) 
     931            { 
     932                goto L1; 
     933            } 
     934        } 
     935        debug(PRINTF) printf("_d_arrayappendcd(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size); 
     936        auto newcap = newCapacity(newlength, sizeelem); 
     937        assert(newcap >= newlength * sizeelem); 
     938        newdata = cast(byte *)gc_malloc(newcap + 1, BlkAttr.NO_SCAN); 
     939        memcpy(newdata, x.ptr, length * sizeelem); 
     940        (cast(void**)(&x))[1] = newdata; 
     941    } 
     942  L1: 
     943    *cast(size_t *)&x = newlength; 
     944    char* ptr = &x.ptr[length]; 
     945 
     946    if (c <= 0x7F) 
     947    { 
     948        ptr[0] = cast(char) c; 
     949    } 
     950    else if (c <= 0x7FF) 
     951    { 
     952        ptr[0] = cast(char)(0xC0 | (c >> 6)); 
     953        ptr[1] = cast(char)(0x80 | (c & 0x3F)); 
     954    } 
     955    else if (c <= 0xFFFF) 
     956    { 
     957        ptr[0] = cast(char)(0xE0 | (c >> 12)); 
     958        ptr[1] = cast(char)(0x80 | ((c >> 6) & 0x3F)); 
     959        ptr[2] = cast(char)(0x80 | (c & 0x3F)); 
     960    } 
     961    else if (c <= 0x10FFFF) 
     962    { 
     963        ptr[0] = cast(char)(0xF0 | (c >> 18)); 
     964        ptr[1] = cast(char)(0x80 | ((c >> 12) & 0x3F)); 
     965        ptr[2] = cast(char)(0x80 | ((c >> 6) & 0x3F)); 
     966        ptr[3] = cast(char)(0x80 | (c & 0x3F)); 
     967    } 
     968    else 
     969    assert(0); 
     970 
     971    assert((cast(size_t)x.ptr & 15) == 0); 
     972    assert(gc_sizeOf(x.ptr) > x.length * sizeelem); 
     973    return x; 
     974} 
     975 
     976 
     977/** 
     978 * Append dchar to wchar[] 
     979 */ 
     980extern (C) wchar[] _d_arrayappendwd(ref wchar[] x, dchar c) 
     981{ 
     982    const sizeelem = c.sizeof;            // array element size 
     983    auto info = gc_query(x.ptr); 
     984    auto length = x.length; 
     985 
     986    // c could encode into from 1 to 2 w characters 
     987    int nchars; 
     988    if (c <= 0xFFFF) 
     989        nchars = 1; 
     990    else 
     991        nchars = 2; 
     992 
     993    auto newlength = length + nchars; 
     994    auto newsize = newlength * sizeelem; 
     995 
     996    assert(info.size == 0 || length * sizeelem <= info.size); 
     997 
     998    debug(PRINTF) printf("_d_arrayappendwd(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size); 
     999 
     1000    if (info.size <= newsize || info.base != x.ptr) 
     1001    {   byte* newdata; 
     1002 
     1003        if (info.size >= PAGESIZE && info.base == x.ptr) 
     1004        {   // Try to extend in-place 
     1005            auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size); 
     1006            if (u) 
     1007            { 
     1008                goto L1; 
     1009            } 
     1010        } 
     1011        debug(PRINTF) printf("_d_arrayappendwd(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size); 
     1012        auto newcap = newCapacity(newlength, sizeelem); 
     1013        assert(newcap >= newlength * sizeelem); 
     1014        newdata = cast(byte *)gc_malloc(newcap + 1, BlkAttr.NO_SCAN); 
     1015        memcpy(newdata, x.ptr, length * sizeelem); 
     1016        (cast(void**)(&x))[1] = newdata; 
     1017    } 
     1018  L1: 
     1019    *cast(size_t *)&x = newlength; 
     1020    wchar* ptr = &x.ptr[length]; 
     1021 
     1022    if (c <= 0xFFFF) 
     1023    { 
     1024        ptr[0] = cast(wchar) c; 
     1025    } 
     1026    else 
     1027    { 
     1028        ptr[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800); 
     1029        ptr[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00); 
     1030    } 
     1031 
     1032    assert((cast(size_t)x.ptr & 15) == 0); 
     1033    assert(gc_sizeOf(x.ptr) > x.length * sizeelem); 
     1034    return x; 
     1035} 
     1036 
     1037 
     1038/** 
    8961039 * 
    8971040 */