Adapted from SciTE Utf8_16.cxx. Copyright (C) 2002 Scott Kirkwood. Modified for Artistic Style by Jim Pattee. Convert a utf-16 file to utf-8.
| 2234 | // |
| 2235 | // Convert a utf-16 file to utf-8. |
| 2236 | size_t ASConsole::Utf16ToUtf8(char* utf16In, size_t inLen, FileEncoding encoding, |
| 2237 | bool firstBlock, char* utf8Out) const |
| 2238 | { |
| 2239 | typedef unsigned short utf16; // 16 bits |
| 2240 | typedef unsigned char ubyte; // 8 bits |
| 2241 | enum { SURROGATE_LEAD_FIRST = 0xD800 }; |
| 2242 | enum { SURROGATE_LEAD_LAST = 0xDBFF }; |
| 2243 | enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; |
| 2244 | enum { SURROGATE_TRAIL_LAST = 0xDFFF }; |
| 2245 | enum { SURROGATE_FIRST_VALUE = 0x10000 }; |
| 2246 | enum eState { eStart, eSecondOf4Bytes, ePenultimate, eFinal }; |
| 2247 | |
| 2248 | int nCur16 = 0; |
| 2249 | int nCur = 0; |
| 2250 | ubyte* pRead = reinterpret_cast<ubyte*>(utf16In); |
| 2251 | ubyte* pCur = reinterpret_cast<ubyte*>(utf8Out); |
| 2252 | const ubyte* pEnd = pRead + inLen; |
| 2253 | const ubyte* pCurStart = pCur; |
| 2254 | static eState eState = eStart; // eState is retained for subsequent blocks |
| 2255 | if (firstBlock) |
| 2256 | eState = eStart; |
| 2257 | |
| 2258 | // the BOM will automatically be converted to utf-8 |
| 2259 | while (pRead < pEnd) |
| 2260 | { |
| 2261 | switch (eState) |
| 2262 | { |
| 2263 | case eStart: |
| 2264 | if (pRead >= pEnd) |
| 2265 | { |
| 2266 | ++pRead; |
| 2267 | break; |
| 2268 | } |
| 2269 | if (encoding == UTF_16LE) |
| 2270 | { |
| 2271 | nCur16 = *pRead++; |
| 2272 | nCur16 |= static_cast<utf16>(*pRead << 8); |
| 2273 | } |
| 2274 | else |
| 2275 | { |
| 2276 | nCur16 = static_cast<utf16>(*pRead++ << 8); |
| 2277 | nCur16 |= static_cast<utf16>(*pRead); |
| 2278 | } |
| 2279 | if (nCur16 >= SURROGATE_LEAD_FIRST && nCur16 <= SURROGATE_LEAD_LAST) |
| 2280 | { |
| 2281 | ++pRead; |
| 2282 | int trail; |
| 2283 | if (encoding == UTF_16LE) |
| 2284 | { |
| 2285 | trail = *pRead++; |
| 2286 | trail |= static_cast<utf16>(*pRead << 8); |
| 2287 | } |
| 2288 | else |
| 2289 | { |
| 2290 | trail = static_cast<utf16>(*pRead++ << 8); |
| 2291 | trail |= static_cast<utf16>(*pRead); |
| 2292 | } |
| 2293 | nCur16 = (((nCur16 & 0x3ff) << 10) | (trail & 0x3ff)) + SURROGATE_FIRST_VALUE; |
nothing calls this directly
no outgoing calls
no test coverage detected