Changeset 609

Show
Ignore:
Timestamp:
02/21/08 12:50:25 (9 months ago)
Author:
Janice Caron
Message:

Renamed from utf2.d
Added support for ascii, latin1 and windows1252 encodings

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • candidate/phobos/std/encoding.d

    r581 r609  
    11/** 
    2 Classes and functions for handling and transcoding between the three UTF formats. 
     2Classes and functions for handling and transcoding between various encodings. Encodings currently supported are 
     3UTF-8, UTF-16, UTF-32, ASCII, ISO-8859-1 (also known as LATIN-1), and WINDOWS-1252 
     4 
     5Functions are provided for arbitrary encoding and decoding of single characters, arbitrary transcoding between 
     6strings of different type, as well as validation and sanitization. 
     7 
     8The type eString!(ascii) represents an ASCII string; the type eString!(latin1) represents an ISO-8859-1 string, and 
     9so on. In general, eString!(E) is the string type for encoding E, and eString(utf8), eString(utf16) and eString(utf32) 
     10are aliases for string, wstring and dstring respectively. 
     11 
     12Future directions for this module include the ability to handle arbitrary encodings. 
    313 
    414Authors: Janice Caron 
    515 
    6 Date: 2006.02.12 
     16Date: 2006.02.21 
     17 
    718*/ 
    819 
    9 module std.utf2; 
    10 //import std.stdio; 
     20module std.encoding; 
    1121 
    1222unittest 
     
    2131 
    2232        // First possible sequence of a certain length 
    23         [ 0x00 ],                                   // U-00000000 one byte 
    24         [ 0xC2, 0x80 ],                             // U-00000080 two bytes 
    25         [ 0xE0, 0xA0, 0x80 ],                       // U-00000800 three bytes 
    26         [ 0xF0, 0x90, 0x80, 0x80 ],                 // U-00010000 three bytes 
     33        [ 0x00 ],                                   // U+00000000 one byte 
     34        [ 0xC2, 0x80 ],                             // U+00000080 two bytes 
     35        [ 0xE0, 0xA0, 0x80 ],                       // U+00000800 three bytes 
     36        [ 0xF0, 0x90, 0x80, 0x80 ],                 // U+00010000 three bytes 
    2737 
    2838        // Last possible sequence of a certain length 
    29         [ 0x7F ],                                   // U-0000007F one byte 
    30         [ 0xDF, 0xBF ],                             // U-000007FF two bytes 
    31         [ 0xEF, 0xBF, 0xBF ],                       // U-0000FFFF three bytes 
     39        [ 0x7F ],                                   // U+0000007F one byte 
     40        [ 0xDF, 0xBF ],                             // U+000007FF two bytes 
     41        [ 0xEF, 0xBF, 0xBF ],                       // U+0000FFFF three bytes 
    3242 
    3343        // Other boundary conditions 
    34         [ 0xED, 0x9F, 0xBF ],                       // U-0000D7FF Last character before surrogates 
    35         [ 0xEE, 0x80, 0x80 ],                       // U-0000E000 First character after surrogates 
    36         [ 0xEF, 0xBF, 0xBD ],                       // U-0000FFFD Unicode replacement character 
    37         [ 0xF4, 0x8F, 0xBF, 0xBF ],                 // U-0010FFFF Very last character 
     44        [ 0xED, 0x9F, 0xBF ],                       // U+0000D7FF Last character before surrogates 
     45        [ 0xEE, 0x80, 0x80 ],                       // U+0000E000 First character after surrogates 
     46        [ 0xEF, 0xBF, 0xBD ],                       // U+0000FFFD Unicode replacement character 
     47        [ 0xF4, 0x8F, 0xBF, 0xBF ],                 // U+0010FFFF Very last character 
    3848 
    3949        // Non-character codepoints 
     
    4454            used as characters. Since this module deals with UTF, and not with Unicode 
    4555            per se, we choose to accept them here. */ 
    46         [ 0xDF, 0xBE ],                             // U-0000FFFE 
    47         [ 0xDF, 0xBF ],                             // U-0000FFFF 
     56        [ 0xDF, 0xBE ],                             // U+0000FFFE 
     57        [ 0xDF, 0xBF ],                             // U+0000FFFF 
    4858    ]; 
    4959 
    5060    ubyte[][] invalidStrings = 
    5161    [ 
    52         // First possible sequence of a certain length, but greater than U-10FFFF 
    53         [ 0xF8, 0x88, 0x80, 0x80, 0x80 ],           // U-00200000 five bytes 
    54         [ 0xFC, 0x84, 0x80, 0x80, 0x80, 0x80 ],     // U-04000000 six bytes 
    55  
    56         // Last possible sequence of a certain length, but greater than U-10FFFF 
    57         [ 0xF7, 0xBF, 0xBF, 0xBF ],                 // U-001FFFFF four bytes 
    58         [ 0xFB, 0xBF, 0xBF, 0xBF, 0xBF ],           // U-03FFFFFF five bytes 
    59         [ 0xFD, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF ],     // U-7FFFFFFF six bytes 
     62        // First possible sequence of a certain length, but greater than U+10FFFF 
     63        [ 0xF8, 0x88, 0x80, 0x80, 0x80 ],           // U+00200000 five bytes 
     64        [ 0xFC, 0x84, 0x80, 0x80, 0x80, 0x80 ],     // U+04000000 six bytes 
     65 
     66        // Last possible sequence of a certain length, but greater than U+10FFFF 
     67        [ 0xF7, 0xBF, 0xBF, 0xBF ],                 // U+001FFFFF four bytes 
     68        [ 0xFB, 0xBF, 0xBF, 0xBF, 0xBF ],           // U+03FFFFFF five bytes 
     69        [ 0xFD, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF ],     // U+7FFFFFFF six bytes 
    6070 
    6171        // Other boundary conditions 
    62         [ 0xF4, 0x90, 0x80, 0x80 ],                 // U-00110000 First codepoint after last character 
     72        [ 0xF4, 0x90, 0x80, 0x80 ],                 // U+00110000 First codepoint after last character 
    6373 
    6474        // Unexpected continuation bytes 
     
    8696        [ 0xF3 ], 
    8797        [ 0xF4 ], 
    88         [ 0xF5 ],   // If this were legal it would start a character > U-10FFFF 
    89         [ 0xF6 ],   // If this were legal it would start a character > U-10FFFF 
    90         [ 0xF7 ],   // If this were legal it would start a character > U-10FFFF 
     98        [ 0xF5 ],   // If this were legal it would start a character > U+10FFFF 
     99        [ 0xF6 ],   // If this were legal it would start a character > U+10FFFF 
     100        [ 0xF7 ],   // If this were legal it would start a character > U+10FFFF 
    91101 
    92102        [ 0xEF, 0xBF ],             // Three byte sequence with third byte missing 
     
    111121        [ 0x20, 0xFF, 0x20 ], 
    112122 
    113         // Overlong sequences, all representing U-002F 
     123        // Overlong sequences, all representing U+002F 
    114124        /*  With a safe UTF-8 decoder, all of the following five overlong 
    115125            representations of the ASCII character slash ("/") should be rejected 
     
    126136            is a boundary test for safe UTF-8 decoders. All five characters should 
    127137            be rejected like malformed UTF-8 sequences. */ 
    128         [ 0xC1, 0xBF ],                             // U-0000007F 
    129         [ 0xE0, 0x9F, 0xBF ],                       // U-000007FF 
    130         [ 0xF0, 0x8F, 0xBF, 0xBF ],                 // U-0000FFFF 
    131         [ 0xF8, 0x87, 0xBF, 0xBF, 0xBF ],           // U-001FFFFF 
    132         [ 0xFC, 0x83, 0xBF, 0xBF, 0xBF, 0xBF ],     // U-03FFFFFF 
     138        [ 0xC1, 0xBF ],                             // U+0000007F 
     139        [ 0xE0, 0x9F, 0xBF ],                       // U+000007FF 
     140        [ 0xF0, 0x8F, 0xBF, 0xBF ],                 // U+0000FFFF 
     141        [ 0xF8, 0x87, 0xBF, 0xBF, 0xBF ],           // U+001FFFFF 
     142        [ 0xFC, 0x83, 0xBF, 0xBF, 0xBF, 0xBF ],     // U+03FFFFFF 
    133143 
    134144        // Overlong representation of the NUL character 
     
    147157            a UTF-8 decoder that accepts them might introduce security problems 
    148158            comparable to overlong UTF-8 sequences. */ 
    149         [ 0xED, 0xA0, 0x80 ],       // U-D800 
    150         [ 0xED, 0xAD, 0xBF ],       // U-DB7F 
    151         [ 0xED, 0xAE, 0x80 ],       // U-DB80 
    152         [ 0xED, 0xAF, 0xBF ],       // U-DBFF 
    153         [ 0xED, 0xB0, 0x80 ],       // U-DC00 
    154         [ 0xED, 0xBE, 0x80 ],       // U-DF80 
    155         [ 0xED, 0xBF, 0xBF ],       // U-DFFF 
     159        [ 0xED, 0xA0, 0x80 ],       // U+D800 
     160        [ 0xED, 0xAD, 0xBF ],       // U+DB7F 
     161        [ 0xED, 0xAE, 0x80 ],       // U+DB80 
     162        [ 0xED, 0xAF, 0xBF ],       // U+DBFF 
     163        [ 0xED, 0xB0, 0x80 ],       // U+DC00 
     164        [ 0xED, 0xBE, 0x80 ],       // U+DF80 
     165        [ 0xED, 0xBF, 0xBF ],       // U+DFFF 
    156166    ]; 
    157167 
     
    248258        assert(ds == ds2); 
    249259    } 
     260     
     261    // Make sure the non-UTF encodings work too 
     262    { 
     263        auto s = "\u20AC100"; 
     264        auto t = to!(windows1252)(s); 
     265        assert(t == [cast(windows1252)0x80, '1', '0', '0']); 
     266        auto u = to!(utf8)(s); 
     267        assert(s == u); 
     268        auto v = to!(latin1)(s); 
     269        assert(cast(string)v == "?100"); 
     270        auto w = to!(ascii)(v); 
     271        assert(cast(string)w == "?100"); 
     272    } 
    250273} 
    251274 
    252275// Unit tests over. Now for the code... 
    253276 
    254 private template UTF(T) 
     277/+private+/ template UTF(T) 
    255278{ 
    256279    static if (is(T==char)) 
     
    327350        } 
    328351 
    329         uint encode(uint c,T[] buffer) 
     352        uint encode(dchar c,T[] buffer) 
    330353        in 
    331354        { 
     
    459482        } 
    460483 
    461         uint encode(uint c,T[] buffer) 
     484        uint encode(dchar c,T[] buffer) 
    462485        in 
    463486        { 
     
    550573        } 
    551574 
    552         uint encode(uint c,T[] buffer) 
     575        uint encode(dchar c,T[] buffer) 
    553576        in 
    554577        { 
     
    587610        } 
    588611    } 
    589     else static if (is(T:achar)) 
    590     { 
    591         alias astring string; 
     612    else static if (is(T:ascii)) 
     613    { 
     614        alias invariant(ascii)[] string; 
    592615 
    593616        enum MAX_SEQUENCE_LENGTH = 1; 
     
    624647        } 
    625648 
    626         uint encode(uint c,T[] buffer) 
     649        uint encode(dchar c,T[] buffer) 
    627650        in 
    628651        { 
     
    661684        } 
    662685    } 
    663     else static if (is(T:lchar)) 
    664     { 
    665         alias lstring string; 
     686    else static if (is(T:latin1)) 
     687    { 
     688        alias invariant(latin1)[] string; 
    666689 
    667690        enum MAX_SEQUENCE_LENGTH = 1; 
    668691 
    669         invariant(char)[] encodingName = "UTF-32"; 
     692        invariant(char)[] encodingName = "ISO-8859-1"; 
    670693 
    671694        bool isValidCodeUnit(T c) 
     
    698721        } 
    699722 
    700         uint encode(uint c,T[] buffer) 
     723        uint encode(dchar c,T[] buffer) 
    701724        in 
    702725        { 
     
    732755        void appendReplacementChar(ref string s) 
    733756        { 
    734             s ~= cast(T)0xFFFD; 
    735         } 
    736     } 
     757            s ~= cast(T)'?'; 
     758        } 
     759    } 
     760    else static if (is(T:windows1252)) 
     761    { 
     762        alias invariant(windows1252)[] string; 
     763 
     764        enum MAX_SEQUENCE_LENGTH = 1; 
     765 
     766        invariant(char)[] encodingName = "WINDOWS-1252"; 
     767         
     768        wstring charMap = 
     769            "\u20AC\uFFFD\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\uFFFD\u017D\uFFFD" 
     770            "\uFFFD\u2018\u2019\u201C\u201D\u2022\u2103\u2014\u02DC\u2122\u0161\u203A\u0153\uFFFD\u017E\u0178" 
     771        ; 
     772 
     773        dchar win2uni(T c) 
     774        { 
     775            return isSingle(c) ? c : charMap[c-0x80]; 
     776        } 
     777         
     778        T uni2win(dchar c) 
     779        { 
     780            if (c < 0x80 || (c >= 0xA0 && c < 0x100)) return cast(T)c; 
     781            if (c != 0xFFFD) 
     782            { 
     783                foreach(n,d;charMap) 
     784                { 
     785                    if (c == d) return cast(T)(n + 0x80); 
     786                } 
     787            } 
     788            return '?'; 
     789        } 
     790         
     791        bool isValidCodeUnit(T c) 
     792        { 
     793            return(win2uni(c) != 0xFFFD); 
     794        } 
     795 
     796        bool isSingle(T c) 
     797        { 
     798            return c < 0x80 || c >= 0xA0; 
     799        } 
     800 
     801        int tails(T c) 
     802        { 
     803            return isSingle(c) ? -1 : 0; 
     804        } 
     805 
     806        bool isHead(T c) 
     807        { 
     808            return isSingle(c) ? false : isValidCodeUnit(c); 
     809        } 
     810 
     811        bool isTail(T c) 
     812        { 
     813            return false; 
     814        } 
     815 
     816        bool badTail(string s, uint n) 
     817        { 
     818            return false; 
     819        } 
     820 
     821        bool isInvalidHeadTail(T c, T d) 
     822        { 
     823            return false; 
     824        } 
     825 
     826        uint encode(dchar c,T[] buffer) 
     827        in 
     828        { 
     829            assert(isValidCodepoint(c)); 
     830            assert(buffer.length >= MAX_SEQUENCE_LENGTH); 
     831        } 
     832        body 
     833        { 
     834            buffer[0] = uni2win(c); 
     835            return 1; 
     836        } 
     837 
     838        dchar decodeSingleSequence(ref string s) 
     839        in 
     840        { 
     841            assert(s.length != 0); 
     842        } 
     843        body 
     844        { 
     845            dchar c = win2uni(s[0]); 
     846            s = s[1..$]; 
     847            return c; 
     848        } 
     849 
     850        dchar decodeSingleSequenceReverse(ref string s) 
     851        in 
     852        { 
     853            assert(s.length != 0); 
     854        } 
     855        body 
     856        { 
     857            dchar c = win2uni(s[$-1]); 
     858            s = s[0..$-1]; 
     859            return c; 
     860        } 
     861 
     862        void appendReplacementChar(ref string s) 
     863        { 
     864            s ~= cast(T)'?'; 
     865        } 
     866    } 
     867    // NOTE: The "else" case is commented out because it doesn't work (yet?) because of some template 
     868    // issues which have yet to be resolved. Expect this to work in some future release. 
     869/+ 
     870    else // The generic case. All other encodings. 
     871    { 
     872        alias invariant(T)[] string; 
     873 
     874        static if(is(T.MAX_SEQUENCE_LENGTH)) 
     875        { 
     876            enum MAX_SEQUENCE_LENGTH = T.MAX_SEQUENCE_LENGTH; 
     877        } 
     878        else 
     879        { 
     880            enum MAX_SEQUENCE_LENGTH = 1; 
     881        } 
     882 
     883        invariant(char)[] encodingName() 
     884        { 
     885            return T.encodingName; 
     886        } 
     887 
     888        bool isValidCodeUnit(T c) 
     889        { 
     890            return c.isValidCodeUnit; 
     891        } 
     892 
     893        bool isSingle(T c) 
     894        { 
     895            static if (is(T.isSingle == function)) 
     896            { 
     897                return c.isSingle; 
     898            } 
     899            else 
     900            { 
     901                return c.isValidCodeUnit; 
     902            } 
     903        } 
     904 
     905        int tails(T c) 
     906        { 
     907            static if (is(T.tails == function)) 
     908            { 
     909                return c.tails(); 
     910            } 
     911            else 
     912            { 
     913                return -1; 
     914            } 
     915        } 
     916 
     917        bool isHead(T c) 
     918        { 
     919            static if(is(T.isHead == function)) 
     920            { 
     921                return c.isHead; 
     922            } 
     923            else 
     924            { 
     925                return false; 
     926            } 
     927        } 
     928 
     929        bool isTail(T c) 
     930        { 
     931            static if(is(T.isTail == function)) 
     932            { 
     933                return c.isTail; 
     934            } 
     935            else 
     936            { 
     937                return false; 
     938            } 
     939        } 
     940 
     941        bool badTail(string s, uint n) 
     942        { 
     943            static if(is(T.badTail == function)) 
     944            { 
     945                return T.badTail(s,n); 
     946            } 
     947            else 
     948            { 
     949                return false; 
     950            } 
     951        } 
     952 
     953        bool isInvalidHeadTail(T c, T d) 
     954        { 
     955            static if(is(T.isInvalidHeadTail == function)) 
     956            { 
     957                return c.isInvalidHeadTail(d); 
     958            } 
     959            else 
     960            { 
     961                return false; 
     962            } 
     963        } 
     964 
     965        uint encode(dchar c,T[] buffer) 
     966        in 
     967        { 
     968            assert(isValidCodepoint(c)); 
     969            assert(buffer.length >= MAX_SEQUENCE_LENGTH); 
     970        } 
     971        body 
     972        { 
     973            return encode(c,buffer); 
     974        } 
     975 
     976        dchar decodeSingleSequence(ref string s) 
     977        { 
     978            static if(is(T.decodeSingleSequence == function)) 
     979            { 
     980                return T.decodeSingleSequence(s); 
     981            } 
     982            else 
     983            { 
     984                assert(false); 
     985                return 0; 
     986            } 
     987        } 
     988 
     989        dchar decodeSingleSequenceReverse(ref string s) 
     990        { 
     991            static if(is(T.decodeSingleSequenceReverse == function)) 
     992            { 
     993                return T.decodeSingleSequenceReverse(s); 
     994            } 
     995            else 
     996            { 
     997                assert(false); 
     998                return 0; 
     999            } 
     1000        } 
     1001 
     1002        void appendReplacementChar(ref string s) 
     1003        { 
     1004            if (is(T.replacementChar == function)) 
     1005            { 
     1006                s ~= T.replacementChar(); 
     1007            } 
     1008            else 
     1009            { 
     1010                s ~= cast(T)'?'; 
     1011            } 
     1012        } 
     1013    } 
     1014+/ 
    7371015 
    7381016    uint pseudoSequenceLength(string s) 
     
    8551133    body 
    8561134    { 
    857         uint c = s[0]; 
     1135        T c = s[0]; 
    8581136        if (isSingle(c)) 
    8591137        { 
     
    8721150    body 
    8731151    { 
    874         uint c = s[$-1]; 
     1152        T c = s[$-1]; 
    8751153        if (isSingle(c)) 
    8761154        { 
     
    9871265} 
    9881266 
    989 typedef char achar;                 // / A type representing an ASCII character 
    990 alias invariant(achar)[] astring;   // / A type representing an ASCII string 
    991 typedef ubyte lchar;                // / A type representing an ISO-8859-1 (aka Latin-1) character 
    992 alias invariant(lchar)[] lstring;   // / A type representing an ISO-8859-1 (aka Latin-1) string 
     1267alias char utf8;            /// A type representing the UTF-8 encoding (an alias of char) 
     1268alias wchar utf16;          /// A type representing the UTF-16 encoding (an alias of wchar) 
     1269alias dchar utf32;          /// A type representing the UTF-32 encoding (an alias of dchar) 
     1270typedef char ascii;         /// A type representing the ASCII encoding 
     1271typedef ubyte latin1;       /// A type representing the ISO-8859-1 (aka Latin-1) encoding 
     1272typedef ubyte windows1252;  /// A type representing the WINDOWS-1252 encoding 
    9931273 
    9941274/** 
    995  * Returns the name of a UTF. 
     1275 * A type representing a string of some specified encoding. The encoding is specified by the template parameter. 
     1276 */ 
     1277template eString(T) 
     1278
     1279    alias invariant(T)[] eString; 
     1280
     1281 
     1282/** 
     1283 * Returns the name of an encoding. 
    9961284 * 
    9971285 * The type of the output cannot be deduced. Therefore, it is necessary to explicitly 
    998  * specify the output type. 
    999  * 
    1000  * If the template type is char, this function returns the string "UTF-8"; 
    1001  * If the template type is wchar, this function returns the string "UTF-16"; 
    1002  * If the template type is dchar, this function returns the string "UTF-32"; 
    1003  * 
    1004  * Standards: Unicode 5.0 
     1286 * specify the encoding type. 
     1287 * 
     1288 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
     1289 * 
     1290 * Examples: 
     1291 * ----------------------------------- 
     1292 * writefln(encodingName!(latin1)); 
     1293 *     // writes ISO-8859-1 
     1294 * ----------------------------------- 
    10051295 */ 
    10061296string encodingName(T)() 
     
    10111301unittest 
    10121302{ 
    1013     assert(encodingName!(char) == "UTF-8"); 
    1014     assert(encodingName!(wchar) == "UTF-16"); 
    1015     assert(encodingName!(dchar) == "UTF-32"); 
     1303    assert(encodingName!(utf8) == "UTF-8"); 
     1304    assert(encodingName!(utf16) == "UTF-16"); 
     1305    assert(encodingName!(utf32) == "UTF-32"); 
     1306    assert(encodingName!(ascii) == "ASCII"); 
     1307    assert(encodingName!(latin1) == "ISO-8859-1"); 
    10161308} 
    10171309 
     
    10191311 * Returns true if the character is a valid codepoint 
    10201312 * 
    1021  * Note that this includes the non-character codepoints U-FFFE and U-FFFF, since these are 
     1313 * Note that this includes the non-character codepoints U+FFFE and U+FFFF, since these are 
    10221314 * valid codepoints (even though they are not valid characters). 
    10231315 * 
    1024  * This function supercedes std.utf.isValidDchar(), even if only because the older function 
    1025  * was badly named
    1026  * 
    1027  * Standards: Unicode 5.0 
     1316 * Supercedes: 
     1317 * This function supercedes std.utf.isValidDchar()
     1318 * 
     1319 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    10281320 * 
    10291321 * Params: 
     
    10361328 
    10371329/** 
    1038  * Returns true if the string is encoded with a valid UTF encoding 
    1039  * 
    1040  * If the input is a string, this function tests for UTF-8; 
    1041  * If the input is a wstring, this function tests for UTF-16; 
    1042  * If the input is a dstring, this function tests for UTF-32. 
    1043  * 
     1330 * Returns true if the string is encoded correctly 
     1331 * 
     1332 * Supercedes: 
    10441333 * This function supercedes std.utf.validate(), however note that this function returns 
    10451334 * a bool indicating whether the input was valid or not, wheras the older funtion would 
    10461335 * throw an exception. 
    10471336 * 
    1048  * Standards: Unicode 5.0 
     1337 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    10491338 * 
    10501339 * Params: 
     
    10571346 
    10581347/** 
    1059  * Sanitizes a string by replacing malformed UTF with valid UTF. The result is guaranteed to 
    1060  * be a valid UTF encoding. 
     1348 * Sanitizes a string by replacing malformed code unit sequences with valid code unit sequences. 
     1349 * The result is guaranteed to be valid for this encoding. 
    10611350 * 
    10621351 * If the input string is already valid, this function returns the original, otherwise 
    10631352 * it constructs a new string by replacing all illegal code unit sequences with the 
    1064  * Unicode replacement character, U-FFFD. 
    1065  * 
    1066  * If the input is a string, this function operates in UTF-8; 
    1067  * If the input is a wstring, this function operates in UTF-16; 
    1068  * If the input is a dstring, this function operates in UTF-32. 
    1069  * 
    1070  * Standards: Unicode 5.0 
     1353 * encoding's replacement character, Invalid sequences will be replaced with the 
     1354 * Unicode replacement character (U+FFFD) if the character repertoire contains it, 
     1355 * otherwise invalid sequences will be replaced with '?'. 
     1356 * 
     1357 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    10711358 * 
    10721359 * Params: 
     
    10851372/** 
    10861373 * Returns the slice of the input string from the first character to the end of the 
    1087  * first UTF sequence. The resulting string may consist of multiple code units, but 
     1374 * first encoded sequence. The resulting string may consist of multiple code units, but 
    10881375 * it will always represent at most one character. If the input is the empty string, 
    10891376 * the return value will be the empty string 
    10901377 * 
    1091  * The input to this function MUST be valid UTF
     1378 * The input to this function MUST be validly encoded
    10921379 * This is enforced by the function's in-contract. 
    10931380 * 
    1094  * If the input is a string, this function operates in UTF-8; 
    1095  * If the input is a wstring, this function operates in UTF-16; 
    1096  * If the input is a dstring, this function operates in UTF-32. 
    1097  * 
    1098  * Standards: Unicode 5.0 
     1381 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    10991382 * 
    11001383 * Params: 
     
    11071390 
    11081391/** 
    1109  * Returns the slice of the input string from the start of the last UTF sequence 
     1392 * Returns the slice of the input string from the start of the last encoded sequence 
    11101393 * to the end of the string. The resulting string may consist of multiple code units, 
    11111394 * but it will always represent at most one character. If the input is the empty string, 
    11121395 * the return value will be the empty string 
    11131396 * 
    1114  * The input to this function MUST be valid UTF
     1397 * The input to this function MUST be validly encoded
    11151398 * This is enforced by the function's in-contract. 
    11161399 * 
    1117  * If the input is a string, this function operates in UTF-8; 
    1118  * If the input is a wstring, this function operates in UTF-16; 
    1119  * If the input is a dstring, this function operates in UTF-32. 
    1120  * 
    1121  * Standards: Unicode 5.0 
     1400 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    11221401 * 
    11231402 * Params: 
     
    11321411 * Returns the total number of codepoints encoded in a string. 
    11331412 * 
    1134  * The input to this function MUST be valid UTF
     1413 * The input to this function MUST be validly encoded
    11351414 * This is enforced by the function's in-contract. 
    11361415 * 
    1137  * If the input is a string, this function operates in UTF-8; 
    1138  * If the input is a wstring, this function operates in UTF-16; 
    1139  * If the input is a dstring, this function operates in UTF-32. 
    1140  * 
     1416 * Supercedes: 
    11411417 * This function supercedes std.utf.toUCSindex(). 
    11421418 * 
    1143  * Standards: Unicode 5.0 
     1419 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    11441420 * 
    11451421 * Params: 
     
    11541430 * Returns the array index at which the (n+1)th codepoint begins. 
    11551431 * 
    1156  * The input to this function MUST be valid UTF
     1432 * The input to this function MUST be validly encoded
    11571433 * This is enforced by the function's in-contract. 
    11581434 * 
    1159  * If the input is a string, this function operates in UTF-8; 
    1160  * If the input is a wstring, this function operates in UTF-16; 
    1161  * If the input is a dstring, this function operates in UTF-32. 
    1162  * 
     1435 * Supercedes: 
    11631436 * This function supercedes std.utf.toUTFindex(). 
    11641437 * 
    1165  * Standards: Unicode 5.0 
     1438 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    11661439 * 
    11671440 * Params: 
     
    11761449 * Decodes a single codepoint. The decoded code units are removed from the start of the string. 
    11771450 * 
    1178  * The input to this function MUST be valid UTF
     1451 * The input to this function MUST be validly encoded
    11791452 * This is enforced by the function's in-contract. 
    11801453 * 
    1181  * If the input is a string, this function decodes UTF-8; 
    1182  * If the input is a wstring, this function decodes UTF-16; 
    1183  * If the input is a dstring, this function decodes UTF-32. 
    1184  * 
     1454 * Supercedes: 
    11851455 * This function supercedes std.utf.decode(), however, note that the 
    1186  * function dchars() superceds it better
    1187  * 
    1188  * Standards: Unicode 5.0 
     1456 * function dchars() supercedes it more conveniently
     1457 * 
     1458 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    11891459 * 
    11901460 * Params: 
     
    12021472 * 
    12031473 * The type of the output cannot be deduced. Therefore, it is necessary to explicitly 
    1204  * specify the output type. 
    1205  * 
     1474 * specify the encoding as a template parameter. 
     1475 * 
     1476 * Supercedes: 
    12061477 * This function supercedes std.utf.encode(), however, note that the 
    1207  * function chars() superceds it better
    1208  * 
    1209  * Standards: Unicode 5.0 
     1478 * function chars() supercedes it more conveniently
     1479 * 
     1480 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    12101481 * 
    12111482 * Params: 
     
    12151486{ 
    12161487    T[] buffer = new T[4]; 
    1217     uint len = encodeToBuffer(c,buffer); 
     1488    uint len = encode(c,buffer); 
    12181489    return cast(invariant(T)[])(buffer[0..len]); 
    12191490} 
     
    12241495 * The input to this function MUST be a valid codepoint. 
    12251496 * 
    1226  * If the buffer is a char[], this function encodes to UTF-8; 
    1227  * If the buffer is a wchar[], this function encodes to UTF-16; 
    1228  * If the buffer is a dchar[], this function encodes to UTF-32. 
    1229  * 
     1497 * The user-supplied buffer needs to be of type T[], where T is the encoding type 
     1498 * (currently one of utf8, utf16, utf32, ascii, latin1 or windows1252). Note that utf8, utf16 and utf32 
     1499 * are aliases for char, wchar and dchar respectively. 
     1500 * 
     1501 * Supercedes: 
    12301502 * This function supercedes std.utf.encode(), however, note that the 
    1231  * function chars() superceds it better
    1232  * 
    1233  * Standards: Unicode 5.0 
     1503 * function chars() supercedes it more conveniently
     1504 * 
     1505 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    12341506 * 
    12351507 * Params: 
     
    12371509 *    buffer = where to store the output 
    12381510 */ 
    1239 uint encodeToBuffer(T)(dchar c,T[] buffer) 
     1511uint encode(T)(dchar c,T[] buffer) 
    12401512in 
    12411513{ 
     
    12601532 * Returns a foreachable struct which can bidirectionally iterate over all codepoints in a string. 
    12611533 * 
    1262  * The input to this function MUST be valid UTF
     1534 * The input to this function MUST be validly encoded
    12631535 * This is enforced by the function's in-contract. 
    12641536 * 
     
    12671539 * iteration with the offset into the string at which the codepoint begins. 
    12681540 * 
    1269  * If the input is a string, this function decodes UTF-8; 
    1270  * If the input is a wstring, this function decodes UTF-16; 
    1271  * If the input is a dstring, this function decodes UTF-32. 
    1272  * 
     1541 * Supercedes: 
    12731542 * This function supercedes std.utf.decode(). 
    12741543 * 
    1275  * Standards: Unicode 5.0 
     1544 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    12761545 * 
    12771546 * Params: 
     
    12881557 * 
    12891558 * Note that, currently, foreach(c:dchars(s)) is superior to foreach(c;s) 
    1290  * in that the latter will fall over on encountering U-FFFF. 
     1559 * in that the latter will fall over on encountering U+FFFF. 
    12911560 */ 
    12921561Dchars!(T) dchars(T)(invariant(T)[] s) 
     
    13011570 * 
    13021571 * The type of the output cannot be deduced. Therefore, it is necessary to explicitly 
    1303  * specify the output type. 
    1304  * 
    1305  * If the output type is char, this function encodes to UTF-8; 
    1306  * If the output type is wchar, this function encodes to UTF-16; 
    1307  * If the output type is dchar, this function encodes to UTF-32. 
    1308  * 
     1572 * specify the encoding type in the template parameter. 
     1573 * 
     1574 * Supercedes: 
    13091575 * This function supercedes std.utf.encode(). 
    13101576 * 
    1311  * Standards: Unicode 5.0 
     1577 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    13121578 * 
    13131579 * Params: 
     
    13291595 
    13301596/** 
    1331  * Convert a string from one UTF to another
    1332  * 
    1333  * The input to this function MUST be valid UTF
     1597 * Convert a string from one encoding to another. (See also to!() below)
     1598 * 
     1599 * The input to this function MUST be validly encoded
    13341600 * This is enforced by the function's in-contract. 
    13351601 * 
    1336  * This function supercedes std.utf.toUTF8(), std.utf.toUTF16() and std.utf.toUTF32(). 
    1337  * 
    1338  * Standards: Unicode 5.0 
     1602 * Supercedes: 
     1603 * This function supercedes std.utf.toUTF8(), std.utf.toUTF16() and std.utf.toUTF32() 
     1604 * (but note that to!() supercedes it more conveniently). 
     1605 * 
     1606 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
    13391607 * 
    13401608 * Params: 
     
    13461614 * wstring ws; 
    13471615 * transcode(ws,"hello world"); 
     1616 *     // transcode from UTF-8 to UTF-16 
     1617 * 
     1618 * eString!(latin1) ls; 
     1619 * transcode(ls, ws); 
     1620 *     // transcode from UTF-16 to ISO-8859-1 
    13481621 * -------------------------------------------------------- 
    13491622 */ 
     
    13521625    static if(is(T==U)) 
    13531626    { 
    1354         return s; 
    1355     } 
    1356     else static if(is(T==achar)) 
     1627        r = s; 
     1628    } 
     1629    else static if(is(T==ascii)) 
    13571630    { 
    13581631        transcode!(U,char)(r,cast(string)s); 
    13591632    } 
    1360     else static if(is(T==lchar)) 
    1361     { 
    1362         transcode!(U,char)(r,cast(string)s); 
    1363     } 
    13641633    else 
    13651634    { 
     
    13721641        } 
    13731642    } 
     1643} 
     1644 
     1645/** 
     1646 * Convert a string from one encoding to another. (See also transcode() above). 
     1647 * 
     1648 * The input to this function MUST be validly encoded. 
     1649 * This is enforced by the function's in-contract. 
     1650 * 
     1651 * Supercedes: 
     1652 * This function supercedes std.utf.toUTF8(), std.utf.toUTF16() and std.utf.toUTF32(). 
     1653 * 
     1654 * Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252 
     1655 * 
     1656 * Params: 
     1657 *    U = the destination encoding type 
     1658 *    s = the sorrce string 
     1659 * 
     1660 * Examples: 
     1661 * ----------------------------------------------------------------------------- 
     1662 * auto ws = to!(utf16)("hello world");  // transcode from UTF-8 to UTF-16 
     1663 * auto ls = to!(latin1)(ws);            // transcode from UTF-16 to ISO-8859-1 
     1664 * ----------------------------------------------------------------------------- 
     1665 */ 
     1666invariant(U)[] to(U,T)(invariant(T)[] s) 
     1667{ 
     1668    invariant(U)[] r; 
     1669    transcode(r,s); 
     1670    return r; 
    13741671} 
    13751672 
     
    13831680            return s; 
    13841681        } 
    1385         else static if(is(T==achar)) 
     1682        else static if(is(T==ascii)) 
    13861683        { 
    13871684            transcodeReverse!(U,char)(r,cast(string)s); 
    13881685        } 
    1389         else static if(is(T==lchar)) 
     1686        else static if(is(T==latin1)) 
    13901687        { 
    13911688            transcodeReverse!(U,char)(r,cast(string)s);