/********************************************************************** * * unicode.c: Functions to handle UTF8/UCS2 coded strings. * * Most of these functions have been adopted from Roland Krause's * UTF8.c, which is part of the XawPlus package. See * http://freenet-homepage.de/kra/ for details. * * int str16len() A strlen() on a char16 string * char16 *str16chr() A strchr() on a char16 string * void str16cpy() A strcpy() on a char16 string * void str16ncpy() A strncpy() on a char16 string * void str16cat() A strcat() on a char16 string * * int mbCharLen() Calc number of byte of the UTF8 character * int mbStrLen() Calc # of characters in UTF8 string * char16 *UTF8toUCS2() Convert UTF8 string to UCS2/UNICODE * char *UCS2toUTF8() Convert UCS2/UNICODE string to UTF8 * * int UCS2precompose() Canonically combine two UCS2 characters * * Copyright (c) Roland Krause 2002, roland_krause@freenet.de * Copyright (c) Michael Ulbrich 2007, mul@rentapacs.de * * This module is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * **********************************************************************/ #include #include "unicode.h" // Size of table: N = 997 static struct { int precomposed; unsigned int pattern; } table[] = { { 0x0000, 0x00000000}, // Dummy entry table[0] { 0x00C0, 0x00410300}, { 0x00C1, 0x00410301}, { 0x00C2, 0x00410302}, { 0x00C3, 0x00410303}, { 0x0100, 0x00410304}, { 0x0102, 0x00410306}, { 0x0226, 0x00410307}, { 0x00C4, 0x00410308}, { 0x1EA2, 0x00410309}, { 0x00C5, 0x0041030A}, { 0x01CD, 0x0041030C}, { 0x0200, 0x0041030F}, { 0x0202, 0x00410311}, { 0x1EA0, 0x00410323}, { 0x1E00, 0x00410325}, { 0x0104, 0x00410328}, { 0x1E02, 0x00420307}, { 0x1E04, 0x00420323}, { 0x1E06, 0x00420331}, { 0x0106, 0x00430301}, { 0x0108, 0x00430302}, { 0x010A, 0x00430307}, { 0x010C, 0x0043030C}, { 0x00C7, 0x00430327}, { 0x1E0A, 0x00440307}, { 0x010E, 0x0044030C}, { 0x1E0C, 0x00440323}, { 0x1E10, 0x00440327}, { 0x1E12, 0x0044032D}, { 0x1E0E, 0x00440331}, { 0x00C8, 0x00450300}, { 0x00C9, 0x00450301}, { 0x00CA, 0x00450302}, { 0x1EBC, 0x00450303}, { 0x0112, 0x00450304}, { 0x0114, 0x00450306}, { 0x0116, 0x00450307}, { 0x00CB, 0x00450308}, { 0x1EBA, 0x00450309}, { 0x011A, 0x0045030C}, { 0x0204, 0x0045030F}, { 0x0206, 0x00450311}, { 0x1EB8, 0x00450323}, { 0x0228, 0x00450327}, { 0x0118, 0x00450328}, { 0x1E18, 0x0045032D}, { 0x1E1A, 0x00450330}, { 0x1E1E, 0x00460307}, { 0x01F4, 0x00470301}, { 0x011C, 0x00470302}, { 0x1E20, 0x00470304}, { 0x011E, 0x00470306}, { 0x0120, 0x00470307}, { 0x01E6, 0x0047030C}, { 0x0122, 0x00470327}, { 0x0124, 0x00480302}, { 0x1E22, 0x00480307}, { 0x1E26, 0x00480308}, { 0x021E, 0x0048030C}, { 0x1E24, 0x00480323}, { 0x1E28, 0x00480327}, { 0x1E2A, 0x0048032E}, { 0x00CC, 0x00490300}, { 0x00CD, 0x00490301}, { 0x00CE, 0x00490302}, { 0x0128, 0x00490303}, { 0x012A, 0x00490304}, { 0x012C, 0x00490306}, { 0x0130, 0x00490307}, { 0x00CF, 0x00490308}, { 0x1EC8, 0x00490309}, { 0x01CF, 0x0049030C}, { 0x0208, 0x0049030F}, { 0x020A, 0x00490311}, { 0x1ECA, 0x00490323}, { 0x012E, 0x00490328}, { 0x1E2C, 0x00490330}, { 0x0134, 0x004A0302}, { 0x1E30, 0x004B0301}, { 0x01E8, 0x004B030C}, { 0x1E32, 0x004B0323}, { 0x0136, 0x004B0327}, { 0x1E34, 0x004B0331}, { 0x0139, 0x004C0301}, { 0x013D, 0x004C030C}, { 0x1E36, 0x004C0323}, { 0x013B, 0x004C0327}, { 0x1E3C, 0x004C032D}, { 0x1E3A, 0x004C0331}, { 0x1E3E, 0x004D0301}, { 0x1E40, 0x004D0307}, { 0x1E42, 0x004D0323}, { 0x01F8, 0x004E0300}, { 0x0143, 0x004E0301}, { 0x00D1, 0x004E0303}, { 0x1E44, 0x004E0307}, { 0x0147, 0x004E030C}, { 0x1E46, 0x004E0323}, { 0x0145, 0x004E0327}, { 0x1E4A, 0x004E032D}, { 0x1E48, 0x004E0331}, { 0x00D2, 0x004F0300}, { 0x00D3, 0x004F0301}, { 0x00D4, 0x004F0302}, { 0x00D5, 0x004F0303}, { 0x014C, 0x004F0304}, { 0x014E, 0x004F0306}, { 0x022E, 0x004F0307}, { 0x00D6, 0x004F0308}, { 0x1ECE, 0x004F0309}, { 0x0150, 0x004F030B}, { 0x01D1, 0x004F030C}, { 0x020C, 0x004F030F}, { 0x020E, 0x004F0311}, { 0x01A0, 0x004F031B}, { 0x1ECC, 0x004F0323}, { 0x01EA, 0x004F0328}, { 0x1E54, 0x00500301}, { 0x1E56, 0x00500307}, { 0x0154, 0x00520301}, { 0x1E58, 0x00520307}, { 0x0158, 0x0052030C}, { 0x0210, 0x0052030F}, { 0x0212, 0x00520311}, { 0x1E5A, 0x00520323}, { 0x0156, 0x00520327}, { 0x1E5E, 0x00520331}, { 0x015A, 0x00530301}, { 0x015C, 0x00530302}, { 0x1E60, 0x00530307}, { 0x0160, 0x0053030C}, { 0x1E62, 0x00530323}, { 0x0218, 0x00530326}, { 0x015E, 0x00530327}, { 0x1E6A, 0x00540307}, { 0x0164, 0x0054030C}, { 0x1E6C, 0x00540323}, { 0x021A, 0x00540326}, { 0x0162, 0x00540327}, { 0x1E70, 0x0054032D}, { 0x1E6E, 0x00540331}, { 0x00D9, 0x00550300}, { 0x00DA, 0x00550301}, { 0x00DB, 0x00550302}, { 0x0168, 0x00550303}, { 0x016A, 0x00550304}, { 0x016C, 0x00550306}, { 0x00DC, 0x00550308}, { 0x1EE6, 0x00550309}, { 0x016E, 0x0055030A}, { 0x0170, 0x0055030B}, { 0x01D3, 0x0055030C}, { 0x0214, 0x0055030F}, { 0x0216, 0x00550311}, { 0x01AF, 0x0055031B}, { 0x1EE4, 0x00550323}, { 0x1E72, 0x00550324}, { 0x0172, 0x00550328}, { 0x1E76, 0x0055032D}, { 0x1E74, 0x00550330}, { 0x1E7C, 0x00560303}, { 0x1E7E, 0x00560323}, { 0x1E80, 0x00570300}, { 0x1E82, 0x00570301}, { 0x0174, 0x00570302}, { 0x1E86, 0x00570307}, { 0x1E84, 0x00570308}, { 0x1E88, 0x00570323}, { 0x1E8A, 0x00580307}, { 0x1E8C, 0x00580308}, { 0x1EF2, 0x00590300}, { 0x00DD, 0x00590301}, { 0x0176, 0x00590302}, { 0x1EF8, 0x00590303}, { 0x0232, 0x00590304}, { 0x1E8E, 0x00590307}, { 0x0178, 0x00590308}, { 0x1EF6, 0x00590309}, { 0x1EF4, 0x00590323}, { 0x0179, 0x005A0301}, { 0x1E90, 0x005A0302}, { 0x017B, 0x005A0307}, { 0x017D, 0x005A030C}, { 0x1E92, 0x005A0323}, { 0x1E94, 0x005A0331}, { 0x00E0, 0x00610300}, { 0x00E1, 0x00610301}, { 0x00E2, 0x00610302}, { 0x00E3, 0x00610303}, { 0x0101, 0x00610304}, { 0x0103, 0x00610306}, { 0x0227, 0x00610307}, { 0x00E4, 0x00610308}, { 0x1EA3, 0x00610309}, { 0x00E5, 0x0061030A}, { 0x01CE, 0x0061030C}, { 0x0201, 0x0061030F}, { 0x0203, 0x00610311}, { 0x1EA1, 0x00610323}, { 0x1E01, 0x00610325}, { 0x0105, 0x00610328}, { 0x1E03, 0x00620307}, { 0x1E05, 0x00620323}, { 0x1E07, 0x00620331}, { 0x0107, 0x00630301}, { 0x0109, 0x00630302}, { 0x010B, 0x00630307}, { 0x010D, 0x0063030C}, { 0x00E7, 0x00630327}, { 0x1E0B, 0x00640307}, { 0x010F, 0x0064030C}, { 0x1E0D, 0x00640323}, { 0x1E11, 0x00640327}, { 0x1E13, 0x0064032D}, { 0x1E0F, 0x00640331}, { 0x00E8, 0x00650300}, { 0x00E9, 0x00650301}, { 0x00EA, 0x00650302}, { 0x1EBD, 0x00650303}, { 0x0113, 0x00650304}, { 0x0115, 0x00650306}, { 0x0117, 0x00650307}, { 0x00EB, 0x00650308}, { 0x1EBB, 0x00650309}, { 0x011B, 0x0065030C}, { 0x0205, 0x0065030F}, { 0x0207, 0x00650311}, { 0x1EB9, 0x00650323}, { 0x0229, 0x00650327}, { 0x0119, 0x00650328}, { 0x1E19, 0x0065032D}, { 0x1E1B, 0x00650330}, { 0x1E1F, 0x00660307}, { 0x01F5, 0x00670301}, { 0x011D, 0x00670302}, { 0x1E21, 0x00670304}, { 0x011F, 0x00670306}, { 0x0121, 0x00670307}, { 0x01E7, 0x0067030C}, { 0x0123, 0x00670327}, { 0x0125, 0x00680302}, { 0x1E23, 0x00680307}, { 0x1E27, 0x00680308}, { 0x021F, 0x0068030C}, { 0x1E25, 0x00680323}, { 0x1E29, 0x00680327}, { 0x1E2B, 0x0068032E}, { 0x1E96, 0x00680331}, { 0x00EC, 0x00690300}, { 0x00ED, 0x00690301}, { 0x00EE, 0x00690302}, { 0x0129, 0x00690303}, { 0x012B, 0x00690304}, { 0x012D, 0x00690306}, { 0x00EF, 0x00690308}, { 0x1EC9, 0x00690309}, { 0x01D0, 0x0069030C}, { 0x0209, 0x0069030F}, { 0x020B, 0x00690311}, { 0x1ECB, 0x00690323}, { 0x012F, 0x00690328}, { 0x1E2D, 0x00690330}, { 0x0135, 0x006A0302}, { 0x01F0, 0x006A030C}, { 0x1E31, 0x006B0301}, { 0x01E9, 0x006B030C}, { 0x1E33, 0x006B0323}, { 0x0137, 0x006B0327}, { 0x1E35, 0x006B0331}, { 0x013A, 0x006C0301}, { 0x013E, 0x006C030C}, { 0x1E37, 0x006C0323}, { 0x013C, 0x006C0327}, { 0x1E3D, 0x006C032D}, { 0x1E3B, 0x006C0331}, { 0x1E3F, 0x006D0301}, { 0x1E41, 0x006D0307}, { 0x1E43, 0x006D0323}, { 0x01F9, 0x006E0300}, { 0x0144, 0x006E0301}, { 0x00F1, 0x006E0303}, { 0x1E45, 0x006E0307}, { 0x0148, 0x006E030C}, { 0x1E47, 0x006E0323}, { 0x0146, 0x006E0327}, { 0x1E4B, 0x006E032D}, { 0x1E49, 0x006E0331}, { 0x00F2, 0x006F0300}, { 0x00F3, 0x006F0301}, { 0x00F4, 0x006F0302}, { 0x00F5, 0x006F0303}, { 0x014D, 0x006F0304}, { 0x014F, 0x006F0306}, { 0x022F, 0x006F0307}, { 0x00F6, 0x006F0308}, { 0x1ECF, 0x006F0309}, { 0x0151, 0x006F030B}, { 0x01D2, 0x006F030C}, { 0x020D, 0x006F030F}, { 0x020F, 0x006F0311}, { 0x01A1, 0x006F031B}, { 0x1ECD, 0x006F0323}, { 0x01EB, 0x006F0328}, { 0x1E55, 0x00700301}, { 0x1E57, 0x00700307}, { 0x0155, 0x00720301}, { 0x1E59, 0x00720307}, { 0x0159, 0x0072030C}, { 0x0211, 0x0072030F}, { 0x0213, 0x00720311}, { 0x1E5B, 0x00720323}, { 0x0157, 0x00720327}, { 0x1E5F, 0x00720331}, { 0x015B, 0x00730301}, { 0x015D, 0x00730302}, { 0x1E61, 0x00730307}, { 0x0161, 0x0073030C}, { 0x1E63, 0x00730323}, { 0x0219, 0x00730326}, { 0x015F, 0x00730327}, { 0x1E6B, 0x00740307}, { 0x1E97, 0x00740308}, { 0x0165, 0x0074030C}, { 0x1E6D, 0x00740323}, { 0x021B, 0x00740326}, { 0x0163, 0x00740327}, { 0x1E71, 0x0074032D}, { 0x1E6F, 0x00740331}, { 0x00F9, 0x00750300}, { 0x00FA, 0x00750301}, { 0x00FB, 0x00750302}, { 0x0169, 0x00750303}, { 0x016B, 0x00750304}, { 0x016D, 0x00750306}, { 0x00FC, 0x00750308}, { 0x1EE7, 0x00750309}, { 0x016F, 0x0075030A}, { 0x0171, 0x0075030B}, { 0x01D4, 0x0075030C}, { 0x0215, 0x0075030F}, { 0x0217, 0x00750311}, { 0x01B0, 0x0075031B}, { 0x1EE5, 0x00750323}, { 0x1E73, 0x00750324}, { 0x0173, 0x00750328}, { 0x1E77, 0x0075032D}, { 0x1E75, 0x00750330}, { 0x1E7D, 0x00760303}, { 0x1E7F, 0x00760323}, { 0x1E81, 0x00770300}, { 0x1E83, 0x00770301}, { 0x0175, 0x00770302}, { 0x1E87, 0x00770307}, { 0x1E85, 0x00770308}, { 0x1E98, 0x0077030A}, { 0x1E89, 0x00770323}, { 0x1E8B, 0x00780307}, { 0x1E8D, 0x00780308}, { 0x1EF3, 0x00790300}, { 0x00FD, 0x00790301}, { 0x0177, 0x00790302}, { 0x1EF9, 0x00790303}, { 0x0233, 0x00790304}, { 0x1E8F, 0x00790307}, { 0x00FF, 0x00790308}, { 0x1EF7, 0x00790309}, { 0x1E99, 0x0079030A}, { 0x1EF5, 0x00790323}, { 0x017A, 0x007A0301}, { 0x1E91, 0x007A0302}, { 0x017C, 0x007A0307}, { 0x017E, 0x007A030C}, { 0x1E93, 0x007A0323}, { 0x1E95, 0x007A0331}, { 0x1FED, 0x00A80300}, { 0x0385, 0x00A80301}, { 0x1FC1, 0x00A80342}, { 0x1EA6, 0x00C20300}, { 0x1EA4, 0x00C20301}, { 0x1EAA, 0x00C20303}, { 0x1EA8, 0x00C20309}, { 0x01DE, 0x00C40304}, { 0x01FA, 0x00C50301}, { 0x01FC, 0x00C60301}, { 0x01E2, 0x00C60304}, { 0x1E08, 0x00C70301}, { 0x1EC0, 0x00CA0300}, { 0x1EBE, 0x00CA0301}, { 0x1EC4, 0x00CA0303}, { 0x1EC2, 0x00CA0309}, { 0x1E2E, 0x00CF0301}, { 0x1ED2, 0x00D40300}, { 0x1ED0, 0x00D40301}, { 0x1ED6, 0x00D40303}, { 0x1ED4, 0x00D40309}, { 0x1E4C, 0x00D50301}, { 0x022C, 0x00D50304}, { 0x1E4E, 0x00D50308}, { 0x022A, 0x00D60304}, { 0x01FE, 0x00D80301}, { 0x01DB, 0x00DC0300}, { 0x01D7, 0x00DC0301}, { 0x01D5, 0x00DC0304}, { 0x01D9, 0x00DC030C}, { 0x1EA7, 0x00E20300}, { 0x1EA5, 0x00E20301}, { 0x1EAB, 0x00E20303}, { 0x1EA9, 0x00E20309}, { 0x01DF, 0x00E40304}, { 0x01FB, 0x00E50301}, { 0x01FD, 0x00E60301}, { 0x01E3, 0x00E60304}, { 0x1E09, 0x00E70301}, { 0x1EC1, 0x00EA0300}, { 0x1EBF, 0x00EA0301}, { 0x1EC5, 0x00EA0303}, { 0x1EC3, 0x00EA0309}, { 0x1E2F, 0x00EF0301}, { 0x1ED3, 0x00F40300}, { 0x1ED1, 0x00F40301}, { 0x1ED7, 0x00F40303}, { 0x1ED5, 0x00F40309}, { 0x1E4D, 0x00F50301}, { 0x022D, 0x00F50304}, { 0x1E4F, 0x00F50308}, { 0x022B, 0x00F60304}, { 0x01FF, 0x00F80301}, { 0x01DC, 0x00FC0300}, { 0x01D8, 0x00FC0301}, { 0x01D6, 0x00FC0304}, { 0x01DA, 0x00FC030C}, { 0x1EB0, 0x01020300}, { 0x1EAE, 0x01020301}, { 0x1EB4, 0x01020303}, { 0x1EB2, 0x01020309}, { 0x1EB1, 0x01030300}, { 0x1EAF, 0x01030301}, { 0x1EB5, 0x01030303}, { 0x1EB3, 0x01030309}, { 0x1E14, 0x01120300}, { 0x1E16, 0x01120301}, { 0x1E15, 0x01130300}, { 0x1E17, 0x01130301}, { 0x1E50, 0x014C0300}, { 0x1E52, 0x014C0301}, { 0x1E51, 0x014D0300}, { 0x1E53, 0x014D0301}, { 0x1E64, 0x015A0307}, { 0x1E65, 0x015B0307}, { 0x1E66, 0x01600307}, { 0x1E67, 0x01610307}, { 0x1E78, 0x01680301}, { 0x1E79, 0x01690301}, { 0x1E7A, 0x016A0308}, { 0x1E7B, 0x016B0308}, { 0x1E9B, 0x017F0307}, { 0x1EDC, 0x01A00300}, { 0x1EDA, 0x01A00301}, { 0x1EE0, 0x01A00303}, { 0x1EDE, 0x01A00309}, { 0x1EE2, 0x01A00323}, { 0x1EDD, 0x01A10300}, { 0x1EDB, 0x01A10301}, { 0x1EE1, 0x01A10303}, { 0x1EDF, 0x01A10309}, { 0x1EE3, 0x01A10323}, { 0x1EEA, 0x01AF0300}, { 0x1EE8, 0x01AF0301}, { 0x1EEE, 0x01AF0303}, { 0x1EEC, 0x01AF0309}, { 0x1EF0, 0x01AF0323}, { 0x1EEB, 0x01B00300}, { 0x1EE9, 0x01B00301}, { 0x1EEF, 0x01B00303}, { 0x1EED, 0x01B00309}, { 0x1EF1, 0x01B00323}, { 0x01EE, 0x01B7030C}, { 0x01EC, 0x01EA0304}, { 0x01ED, 0x01EB0304}, { 0x01E0, 0x02260304}, { 0x01E1, 0x02270304}, { 0x1E1C, 0x02280306}, { 0x1E1D, 0x02290306}, { 0x0230, 0x022E0304}, { 0x0231, 0x022F0304}, { 0x01EF, 0x0292030C}, { 0x0344, 0x03080301}, { 0x1FBA, 0x03910300}, { 0x0386, 0x03910301}, { 0x1FB9, 0x03910304}, { 0x1FB8, 0x03910306}, { 0x1F08, 0x03910313}, { 0x1F09, 0x03910314}, { 0x1FBC, 0x03910345}, { 0x1FC8, 0x03950300}, { 0x0388, 0x03950301}, { 0x1F18, 0x03950313}, { 0x1F19, 0x03950314}, { 0x1FCA, 0x03970300}, { 0x0389, 0x03970301}, { 0x1F28, 0x03970313}, { 0x1F29, 0x03970314}, { 0x1FCC, 0x03970345}, { 0x1FDA, 0x03990300}, { 0x038A, 0x03990301}, { 0x1FD9, 0x03990304}, { 0x1FD8, 0x03990306}, { 0x03AA, 0x03990308}, { 0x1F38, 0x03990313}, { 0x1F39, 0x03990314}, { 0x1FF8, 0x039F0300}, { 0x038C, 0x039F0301}, { 0x1F48, 0x039F0313}, { 0x1F49, 0x039F0314}, { 0x1FEC, 0x03A10314}, { 0x1FEA, 0x03A50300}, { 0x038E, 0x03A50301}, { 0x1FE9, 0x03A50304}, { 0x1FE8, 0x03A50306}, { 0x03AB, 0x03A50308}, { 0x1F59, 0x03A50314}, { 0x1FFA, 0x03A90300}, { 0x038F, 0x03A90301}, { 0x1F68, 0x03A90313}, { 0x1F69, 0x03A90314}, { 0x1FFC, 0x03A90345}, { 0x1FB4, 0x03AC0345}, { 0x1FC4, 0x03AE0345}, { 0x1F70, 0x03B10300}, { 0x03AC, 0x03B10301}, { 0x1FB1, 0x03B10304}, { 0x1FB0, 0x03B10306}, { 0x1F00, 0x03B10313}, { 0x1F01, 0x03B10314}, { 0x1FB6, 0x03B10342}, { 0x1FB3, 0x03B10345}, { 0x1F72, 0x03B50300}, { 0x03AD, 0x03B50301}, { 0x1F10, 0x03B50313}, { 0x1F11, 0x03B50314}, { 0x1F74, 0x03B70300}, { 0x03AE, 0x03B70301}, { 0x1F20, 0x03B70313}, { 0x1F21, 0x03B70314}, { 0x1FC6, 0x03B70342}, { 0x1FC3, 0x03B70345}, { 0x1F76, 0x03B90300}, { 0x03AF, 0x03B90301}, { 0x1FD1, 0x03B90304}, { 0x1FD0, 0x03B90306}, { 0x03CA, 0x03B90308}, { 0x1F30, 0x03B90313}, { 0x1F31, 0x03B90314}, { 0x1FD6, 0x03B90342}, { 0x1F78, 0x03BF0300}, { 0x03CC, 0x03BF0301}, { 0x1F40, 0x03BF0313}, { 0x1F41, 0x03BF0314}, { 0x1FE4, 0x03C10313}, { 0x1FE5, 0x03C10314}, { 0x1F7A, 0x03C50300}, { 0x03CD, 0x03C50301}, { 0x1FE1, 0x03C50304}, { 0x1FE0, 0x03C50306}, { 0x03CB, 0x03C50308}, { 0x1F50, 0x03C50313}, { 0x1F51, 0x03C50314}, { 0x1FE6, 0x03C50342}, { 0x1F7C, 0x03C90300}, { 0x03CE, 0x03C90301}, { 0x1F60, 0x03C90313}, { 0x1F61, 0x03C90314}, { 0x1FF6, 0x03C90342}, { 0x1FF3, 0x03C90345}, { 0x1FD2, 0x03CA0300}, { 0x0390, 0x03CA0301}, { 0x1FD7, 0x03CA0342}, { 0x1FE2, 0x03CB0300}, { 0x03B0, 0x03CB0301}, { 0x1FE7, 0x03CB0342}, { 0x1FF4, 0x03CE0345}, { 0x03D3, 0x03D20301}, { 0x03D4, 0x03D20308}, { 0x0407, 0x04060308}, { 0x04D0, 0x04100306}, { 0x04D2, 0x04100308}, { 0x0403, 0x04130301}, { 0x0400, 0x04150300}, { 0x04D6, 0x04150306}, { 0x0401, 0x04150308}, { 0x04C1, 0x04160306}, { 0x04DC, 0x04160308}, { 0x04DE, 0x04170308}, { 0x040D, 0x04180300}, { 0x04E2, 0x04180304}, { 0x0419, 0x04180306}, { 0x04E4, 0x04180308}, { 0x040C, 0x041A0301}, { 0x04E6, 0x041E0308}, { 0x04EE, 0x04230304}, { 0x040E, 0x04230306}, { 0x04F0, 0x04230308}, { 0x04F2, 0x0423030B}, { 0x04F4, 0x04270308}, { 0x04F8, 0x042B0308}, { 0x04EC, 0x042D0308}, { 0x04D1, 0x04300306}, { 0x04D3, 0x04300308}, { 0x0453, 0x04330301}, { 0x0450, 0x04350300}, { 0x04D7, 0x04350306}, { 0x0451, 0x04350308}, { 0x04C2, 0x04360306}, { 0x04DD, 0x04360308}, { 0x04DF, 0x04370308}, { 0x045D, 0x04380300}, { 0x04E3, 0x04380304}, { 0x0439, 0x04380306}, { 0x04E5, 0x04380308}, { 0x045C, 0x043A0301}, { 0x04E7, 0x043E0308}, { 0x04EF, 0x04430304}, { 0x045E, 0x04430306}, { 0x04F1, 0x04430308}, { 0x04F3, 0x0443030B}, { 0x04F5, 0x04470308}, { 0x04F9, 0x044B0308}, { 0x04ED, 0x044D0308}, { 0x0457, 0x04560308}, { 0x0476, 0x0474030F}, { 0x0477, 0x0475030F}, { 0x04DA, 0x04D80308}, { 0x04DB, 0x04D90308}, { 0x04EA, 0x04E80308}, { 0x04EB, 0x04E90308}, { 0xFB2E, 0x05D005B7}, { 0xFB2F, 0x05D005B8}, { 0xFB30, 0x05D005BC}, { 0xFB31, 0x05D105BC}, { 0xFB4C, 0x05D105BF}, { 0xFB32, 0x05D205BC}, { 0xFB33, 0x05D305BC}, { 0xFB34, 0x05D405BC}, { 0xFB4B, 0x05D505B9}, { 0xFB35, 0x05D505BC}, { 0xFB36, 0x05D605BC}, { 0xFB38, 0x05D805BC}, { 0xFB1D, 0x05D905B4}, { 0xFB39, 0x05D905BC}, { 0xFB3A, 0x05DA05BC}, { 0xFB3B, 0x05DB05BC}, { 0xFB4D, 0x05DB05BF}, { 0xFB3C, 0x05DC05BC}, { 0xFB3E, 0x05DE05BC}, { 0xFB40, 0x05E005BC}, { 0xFB41, 0x05E105BC}, { 0xFB43, 0x05E305BC}, { 0xFB44, 0x05E405BC}, { 0xFB4E, 0x05E405BF}, { 0xFB46, 0x05E605BC}, { 0xFB47, 0x05E705BC}, { 0xFB48, 0x05E805BC}, { 0xFB49, 0x05E905BC}, { 0xFB2A, 0x05E905C1}, { 0xFB2B, 0x05E905C2}, { 0xFB4A, 0x05EA05BC}, { 0xFB1F, 0x05F205B7}, { 0x0622, 0x06270653}, { 0x0623, 0x06270654}, { 0x0625, 0x06270655}, { 0x0624, 0x06480654}, { 0x0626, 0x064A0654}, { 0x06C2, 0x06C10654}, { 0x06D3, 0x06D20654}, { 0x06C0, 0x06D50654}, { 0x0958, 0x0915093C}, { 0x0959, 0x0916093C}, { 0x095A, 0x0917093C}, { 0x095B, 0x091C093C}, { 0x095C, 0x0921093C}, { 0x095D, 0x0922093C}, { 0x0929, 0x0928093C}, { 0x095E, 0x092B093C}, { 0x095F, 0x092F093C}, { 0x0931, 0x0930093C}, { 0x0934, 0x0933093C}, { 0x09DC, 0x09A109BC}, { 0x09DD, 0x09A209BC}, { 0x09DF, 0x09AF09BC}, { 0x09CB, 0x09C709BE}, { 0x09CC, 0x09C709D7}, { 0x0A59, 0x0A160A3C}, { 0x0A5A, 0x0A170A3C}, { 0x0A5B, 0x0A1C0A3C}, { 0x0A5E, 0x0A2B0A3C}, { 0x0A33, 0x0A320A3C}, { 0x0A36, 0x0A380A3C}, { 0x0B5C, 0x0B210B3C}, { 0x0B5D, 0x0B220B3C}, { 0x0B4B, 0x0B470B3E}, { 0x0B48, 0x0B470B56}, { 0x0B4C, 0x0B470B57}, { 0x0B94, 0x0B920BD7}, { 0x0BCA, 0x0BC60BBE}, { 0x0BCC, 0x0BC60BD7}, { 0x0BCB, 0x0BC70BBE}, { 0x0C48, 0x0C460C56}, { 0x0CC0, 0x0CBF0CD5}, { 0x0CCA, 0x0CC60CC2}, { 0x0CC7, 0x0CC60CD5}, { 0x0CC8, 0x0CC60CD6}, { 0x0CCB, 0x0CCA0CD5}, { 0x0D4A, 0x0D460D3E}, { 0x0D4C, 0x0D460D57}, { 0x0D4B, 0x0D470D3E}, { 0x0DDA, 0x0DD90DCA}, { 0x0DDC, 0x0DD90DCF}, { 0x0DDE, 0x0DD90DDF}, { 0x0DDD, 0x0DDC0DCA}, { 0x0F69, 0x0F400FB5}, { 0x0F43, 0x0F420FB7}, { 0x0F4D, 0x0F4C0FB7}, { 0x0F52, 0x0F510FB7}, { 0x0F57, 0x0F560FB7}, { 0x0F5C, 0x0F5B0FB7}, { 0x0F73, 0x0F710F72}, { 0x0F75, 0x0F710F74}, { 0x0F81, 0x0F710F80}, { 0x0FB9, 0x0F900FB5}, { 0x0F93, 0x0F920FB7}, { 0x0F9D, 0x0F9C0FB7}, { 0x0FA2, 0x0FA10FB7}, { 0x0FA7, 0x0FA60FB7}, { 0x0FAC, 0x0FAB0FB7}, { 0x0F76, 0x0FB20F80}, { 0x0F78, 0x0FB30F80}, { 0x1026, 0x1025102E}, { 0x1B06, 0x1B051B35}, { 0x1B08, 0x1B071B35}, { 0x1B0A, 0x1B091B35}, { 0x1B0C, 0x1B0B1B35}, { 0x1B0E, 0x1B0D1B35}, { 0x1B12, 0x1B111B35}, { 0x1B3B, 0x1B3A1B35}, { 0x1B3D, 0x1B3C1B35}, { 0x1B40, 0x1B3E1B35}, { 0x1B41, 0x1B3F1B35}, { 0x1B43, 0x1B421B35}, { 0x1E38, 0x1E360304}, { 0x1E39, 0x1E370304}, { 0x1E5C, 0x1E5A0304}, { 0x1E5D, 0x1E5B0304}, { 0x1E68, 0x1E620307}, { 0x1E69, 0x1E630307}, { 0x1EAC, 0x1EA00302}, { 0x1EB6, 0x1EA00306}, { 0x1EAD, 0x1EA10302}, { 0x1EB7, 0x1EA10306}, { 0x1EC6, 0x1EB80302}, { 0x1EC7, 0x1EB90302}, { 0x1ED8, 0x1ECC0302}, { 0x1ED9, 0x1ECD0302}, { 0x1F02, 0x1F000300}, { 0x1F04, 0x1F000301}, { 0x1F06, 0x1F000342}, { 0x1F80, 0x1F000345}, { 0x1F03, 0x1F010300}, { 0x1F05, 0x1F010301}, { 0x1F07, 0x1F010342}, { 0x1F81, 0x1F010345}, { 0x1F82, 0x1F020345}, { 0x1F83, 0x1F030345}, { 0x1F84, 0x1F040345}, { 0x1F85, 0x1F050345}, { 0x1F86, 0x1F060345}, { 0x1F87, 0x1F070345}, { 0x1F0A, 0x1F080300}, { 0x1F0C, 0x1F080301}, { 0x1F0E, 0x1F080342}, { 0x1F88, 0x1F080345}, { 0x1F0B, 0x1F090300}, { 0x1F0D, 0x1F090301}, { 0x1F0F, 0x1F090342}, { 0x1F89, 0x1F090345}, { 0x1F8A, 0x1F0A0345}, { 0x1F8B, 0x1F0B0345}, { 0x1F8C, 0x1F0C0345}, { 0x1F8D, 0x1F0D0345}, { 0x1F8E, 0x1F0E0345}, { 0x1F8F, 0x1F0F0345}, { 0x1F12, 0x1F100300}, { 0x1F14, 0x1F100301}, { 0x1F13, 0x1F110300}, { 0x1F15, 0x1F110301}, { 0x1F1A, 0x1F180300}, { 0x1F1C, 0x1F180301}, { 0x1F1B, 0x1F190300}, { 0x1F1D, 0x1F190301}, { 0x1F22, 0x1F200300}, { 0x1F24, 0x1F200301}, { 0x1F26, 0x1F200342}, { 0x1F90, 0x1F200345}, { 0x1F23, 0x1F210300}, { 0x1F25, 0x1F210301}, { 0x1F27, 0x1F210342}, { 0x1F91, 0x1F210345}, { 0x1F92, 0x1F220345}, { 0x1F93, 0x1F230345}, { 0x1F94, 0x1F240345}, { 0x1F95, 0x1F250345}, { 0x1F96, 0x1F260345}, { 0x1F97, 0x1F270345}, { 0x1F2A, 0x1F280300}, { 0x1F2C, 0x1F280301}, { 0x1F2E, 0x1F280342}, { 0x1F98, 0x1F280345}, { 0x1F2B, 0x1F290300}, { 0x1F2D, 0x1F290301}, { 0x1F2F, 0x1F290342}, { 0x1F99, 0x1F290345}, { 0x1F9A, 0x1F2A0345}, { 0x1F9B, 0x1F2B0345}, { 0x1F9C, 0x1F2C0345}, { 0x1F9D, 0x1F2D0345}, { 0x1F9E, 0x1F2E0345}, { 0x1F9F, 0x1F2F0345}, { 0x1F32, 0x1F300300}, { 0x1F34, 0x1F300301}, { 0x1F36, 0x1F300342}, { 0x1F33, 0x1F310300}, { 0x1F35, 0x1F310301}, { 0x1F37, 0x1F310342}, { 0x1F3A, 0x1F380300}, { 0x1F3C, 0x1F380301}, { 0x1F3E, 0x1F380342}, { 0x1F3B, 0x1F390300}, { 0x1F3D, 0x1F390301}, { 0x1F3F, 0x1F390342}, { 0x1F42, 0x1F400300}, { 0x1F44, 0x1F400301}, { 0x1F43, 0x1F410300}, { 0x1F45, 0x1F410301}, { 0x1F4A, 0x1F480300}, { 0x1F4C, 0x1F480301}, { 0x1F4B, 0x1F490300}, { 0x1F4D, 0x1F490301}, { 0x1F52, 0x1F500300}, { 0x1F54, 0x1F500301}, { 0x1F56, 0x1F500342}, { 0x1F53, 0x1F510300}, { 0x1F55, 0x1F510301}, { 0x1F57, 0x1F510342}, { 0x1F5B, 0x1F590300}, { 0x1F5D, 0x1F590301}, { 0x1F5F, 0x1F590342}, { 0x1F62, 0x1F600300}, { 0x1F64, 0x1F600301}, { 0x1F66, 0x1F600342}, { 0x1FA0, 0x1F600345}, { 0x1F63, 0x1F610300}, { 0x1F65, 0x1F610301}, { 0x1F67, 0x1F610342}, { 0x1FA1, 0x1F610345}, { 0x1FA2, 0x1F620345}, { 0x1FA3, 0x1F630345}, { 0x1FA4, 0x1F640345}, { 0x1FA5, 0x1F650345}, { 0x1FA6, 0x1F660345}, { 0x1FA7, 0x1F670345}, { 0x1F6A, 0x1F680300}, { 0x1F6C, 0x1F680301}, { 0x1F6E, 0x1F680342}, { 0x1FA8, 0x1F680345}, { 0x1F6B, 0x1F690300}, { 0x1F6D, 0x1F690301}, { 0x1F6F, 0x1F690342}, { 0x1FA9, 0x1F690345}, { 0x1FAA, 0x1F6A0345}, { 0x1FAB, 0x1F6B0345}, { 0x1FAC, 0x1F6C0345}, { 0x1FAD, 0x1F6D0345}, { 0x1FAE, 0x1F6E0345}, { 0x1FAF, 0x1F6F0345}, { 0x1FB2, 0x1F700345}, { 0x1FC2, 0x1F740345}, { 0x1FF2, 0x1F7C0345}, { 0x1FB7, 0x1FB60345}, { 0x1FCD, 0x1FBF0300}, { 0x1FCE, 0x1FBF0301}, { 0x1FCF, 0x1FBF0342}, { 0x1FC7, 0x1FC60345}, { 0x1FF7, 0x1FF60345}, { 0x1FDD, 0x1FFE0300}, { 0x1FDE, 0x1FFE0301}, { 0x1FDF, 0x1FFE0342}, { 0x219A, 0x21900338}, { 0x219B, 0x21920338}, { 0x21AE, 0x21940338}, { 0x21CD, 0x21D00338}, { 0x21CF, 0x21D20338}, { 0x21CE, 0x21D40338}, { 0x2204, 0x22030338}, { 0x2209, 0x22080338}, { 0x220C, 0x220B0338}, { 0x2224, 0x22230338}, { 0x2226, 0x22250338}, { 0x2241, 0x223C0338}, { 0x2244, 0x22430338}, { 0x2247, 0x22450338}, { 0x2249, 0x22480338}, { 0x226D, 0x224D0338}, { 0x2262, 0x22610338}, { 0x2270, 0x22640338}, { 0x2271, 0x22650338}, { 0x2274, 0x22720338}, { 0x2275, 0x22730338}, { 0x2278, 0x22760338}, { 0x2279, 0x22770338}, { 0x2280, 0x227A0338}, { 0x2281, 0x227B0338}, { 0x22E0, 0x227C0338}, { 0x22E1, 0x227D0338}, { 0x2284, 0x22820338}, { 0x2285, 0x22830338}, { 0x2288, 0x22860338}, { 0x2289, 0x22870338}, { 0x22E2, 0x22910338}, { 0x22E3, 0x22920338}, { 0x22AC, 0x22A20338}, { 0x22AD, 0x22A80338}, { 0x22AE, 0x22A90338}, { 0x22AF, 0x22AB0338}, { 0x22EA, 0x22B20338}, { 0x22EB, 0x22B30338}, { 0x22EC, 0x22B40338}, { 0x22ED, 0x22B50338}, { 0x2ADC, 0x2ADD0338}, { 0x3094, 0x30463099}, { 0x304C, 0x304B3099}, { 0x304E, 0x304D3099}, { 0x3050, 0x304F3099}, { 0x3052, 0x30513099}, { 0x3054, 0x30533099}, { 0x3056, 0x30553099}, { 0x3058, 0x30573099}, { 0x305A, 0x30593099}, { 0x305C, 0x305B3099}, { 0x305E, 0x305D3099}, { 0x3060, 0x305F3099}, { 0x3062, 0x30613099}, { 0x3065, 0x30643099}, { 0x3067, 0x30663099}, { 0x3069, 0x30683099}, { 0x3070, 0x306F3099}, { 0x3071, 0x306F309A}, { 0x3073, 0x30723099}, { 0x3074, 0x3072309A}, { 0x3076, 0x30753099}, { 0x3077, 0x3075309A}, { 0x3079, 0x30783099}, { 0x307A, 0x3078309A}, { 0x307C, 0x307B3099}, { 0x307D, 0x307B309A}, { 0x309E, 0x309D3099}, { 0x30F4, 0x30A63099}, { 0x30AC, 0x30AB3099}, { 0x30AE, 0x30AD3099}, { 0x30B0, 0x30AF3099}, { 0x30B2, 0x30B13099}, { 0x30B4, 0x30B33099}, { 0x30B6, 0x30B53099}, { 0x30B8, 0x30B73099}, { 0x30BA, 0x30B93099}, { 0x30BC, 0x30BB3099}, { 0x30BE, 0x30BD3099}, { 0x30C0, 0x30BF3099}, { 0x30C2, 0x30C13099}, { 0x30C5, 0x30C43099}, { 0x30C7, 0x30C63099}, { 0x30C9, 0x30C83099}, { 0x30D0, 0x30CF3099}, { 0x30D1, 0x30CF309A}, { 0x30D3, 0x30D23099}, { 0x30D4, 0x30D2309A}, { 0x30D6, 0x30D53099}, { 0x30D7, 0x30D5309A}, { 0x30D9, 0x30D83099}, { 0x30DA, 0x30D8309A}, { 0x30DC, 0x30DB3099}, { 0x30DD, 0x30DB309A}, { 0x30F7, 0x30EF3099}, { 0x30F8, 0x30F03099}, { 0x30F9, 0x30F13099}, { 0x30FA, 0x30F23099}, { 0x30FE, 0x30FD3099}, { 0xFB2C, 0xFB4905C1}, { 0xFB2D, 0xFB4905C2}, }; // If size of table changes, new delta values are needed !! // Here: table size N = 997 static int delta[] = { 499, 249, 125, 62, 31, 16, 8, 4, 2, 1, 0 }; /* Function Name: UCS2precompose * Description: Canonically combine two UCS2 characters, if matching * pattern is found in table. Uniform binary search * algorithm from D. Knuth TAOCP Vol.3 p.414. Uses static * arrays table[] and delta[] (see above). * Arguments: first - the first UCS2 character * second - the second UCS2 character * Returns: Canonical composition of first and second or * -1 if no such composition exists in table. */ int UCS2precompose(first, second) char16 first; char16 second; { int i = delta[0]; int j = 0; unsigned int needle = (first << 16) | second; /* uniform binary search */ while (delta[j++]) { if (needle < table[i].pattern) { i -= delta[j]; } else if (needle > table[i].pattern) { i += delta[j]; } else { return table[i].precomposed; } } /* precomposed unicode not found */ return -1; } /* ******************************************************************** * * String functions to deal with 16 bit characters. * These functions are used to handle strings with 16 bit encoding. * **********************************************************************/ /* Function Name: str16len * Description: Determine the string length of a char16 string * independent of the locale settings. * Arguments: str16 - A terminated string of char16's * Returns: Length in char16's */ int str16len(str16) char16 *str16; { int len = 0; while (*str16++) len++; return len; } /* Function Name: str16chr * Description: Search an 8 bit character in a char16 string. * The upper byte of *ch* is assumed as '0'! * Arguments: str16 - A terminated string of char16's * ch - An 8 bit character * Returns: Position of the leftmost occurance of *ch* * in str16 or NULL. */ char16 *str16chr(str16, ch) char16 *str16; char ch; { char *p; while (*str16) { p = (char *)str16; if ((*p++ == '\0') && (*p == ch)) return(str16); str16++; } return NULL; } /* Function Name: str16cpy * Description: Copy a string of char16's from *src* to *dest* * Arguments: dest - Destination string * src - Source string * Returns: None */ void str16cpy(dest, src) char16 *dest, *src; { while (*src) *dest++ = *src++; *dest = 0; /* To terminate the string */ } /* Function Name: str16ncpy * Description: Copy *n* char16's from *src* to *dest* and * terminate *dest*. * Arguments: dest - Destination string * src - Source string * n - # of characters to copy * Returns: None */ void str16ncpy(dest, src, n) char16 *dest, *src; size_t n; { while ((n > 0) && *src) { *dest++ = *src++; n--; } *dest = 0; /* We always terminate the string here */ } /* Function Name: str16cat * Description: Concatenate the string of char16's in *src* with *dest*. * Arguments: dest - Destination string * src - Source string * Returns: None */ void str16cat(dest, src) char16 *dest, *src; { while (*dest) dest++; /* search the end of the string */ while (*src) *dest++ = *src++; /* copy the other behind */ *dest = 0; /* and terminate the string */ } /* Function Name: mbCharLen * Description: Determine the length in byte of an UTF8 coded * character. * Arguments: str - Pointer into an UTF8 coded string * Returns: Number of byte of the next character in the string * or 0 in case of an error. */ int mbCharLen(str) char *str; { unsigned char c = (unsigned char)*str; unsigned char mask = 0x80; int count = 0; if (c) { while (c & mask) { count++; mask >>= 1; } switch (count) { case 0: return 1; /* Character is one byte long */ case 1: return 0; /* No multibyte string or wrong position */ default: return count; } } return 0; /* End of string reached */ } /* Function Name: mbStrLen * Description: Determine the string length of an UTF8 coded string * in characters (not in byte!). * Arguments: str - The UTF8 coded string * Returns: The length in characters, illegal coded bytes * are counted as one character per byte. * See UTF8toUCS2() for the reason! */ int mbStrLen(str) char *str; { char *p = str; int clen, len = 0; while ((clen = mbCharLen(p)) > 0) { len++; p += clen; } return len; } /* Function Name: UTF8toUCS2 * Description: Conversion of an UTF8 coded string into UCS2/UNICODE. * If the encoding of the character is not representable * in two bytes, the tilde sign ~ is written into the * result string at this position. * For an illegal UTF8 code an asterix * is stored in * the result string. * Arguments: str - The UTF8 coded string * Returns: The UCS2 coded result string. The allocated memory * for this string has to be freed by the caller! * The result string is stored independent of the * architecture in the high byte/low byte order and is * compatible to the XChar2b format! Type casting is valid. * char16 is used to increase the performance. */ char16 *UTF8toUCS2(str) char *str; { char16 *str16, *p16, testINTEL = 0, c16; int clen, cInString; char *p; /* In the first step we try to determine the string * length in characters. */ cInString = mbStrLen(str); cInString++; /* For the terminating null */ /* Now we need memory for our conversion result */ str16 = (char16 *)malloc(cInString * sizeof(char16)); if (str16) { /* Start the conversion: Determine the number of bytes * for the next character, decode it and store the * result in our result string */ p = str; p16 = str16; while ((clen = mbCharLen(p)) > 0) { switch (clen) { case 1: *p16 = (char16)*p; break; case 2: c16 = (p[1] & 0x3f) + ((p[0] & 0x1f) << 6); *p16 = ((c16 > 0x7f) && ((p[1] & 0xC0) == 0x80)) ? c16 : '*'; break; case 3: c16 = (p[2] & 0x3f) + ((p[1] & 0x3f) << 6) + ((p[0] & 0xf) << 12); *p16 = ((c16 > 0x7ff) && ((p[1] & 0xC0) == 0x80) && ((p[2] & 0xC0) == 0x80)) ? c16 : '*'; break; default: *p16 = '~'; /* character code is greater than 0xffff */ } p16++; /* Jump to the next character */ p += clen; } *p16 = 0; /* String termination */ /* Swap the bytes, if we are on a machine with an INTEL architecture */ if (*((char *)&testINTEL)) { char *src, *dest, c; src = dest = (char *)str16; src++; while (*src || *dest) { c = *dest; *dest = *src; *src = c; src += 2; dest += 2; } } return str16; } return NULL; } /* Function Name: UCS2toUTF8 * Description: Conversion of an UCS2 coded string into UTF8. * Arguments: str16 - The UCS2 coded string * Returns: The UTF8 coded result string. The allocated memory * for this string has to be freed by the caller! */ char *UCS2toUTF8(str16) char16 *str16; { char *str8, *p8, *p; char16 *p16; int len16 = str16len(str16); // worst case: 3 bytes of UTF8 per UCS2 char + terminal 0 str8 = malloc((len16 * 3 * sizeof(char)) + 1); p8 = str8; // reset pointers p16 = str16; while(*p16 > 0) { p = (char*)p16; if(*p16 < 0x0080) { *p8 = p[0]; p8++; } else if(*p16 < 0x0800) { *p8 = 0xc0 | ((p[1] & 0x7) << 2) | ((p[0] & 0xc0) >> 6); p8++; *p8 = 0x80 | (p[0] & 0x3f); p8++; } else { *p8 = 0xe0 | ((p[1] & 0xf0) >> 4); p8++; *p8 = 0x80 | ((p[1] & 0xf) << 2) | ((p[0] & 0xc0) >> 6); p8++; *p8 = 0x80 | (p[0] & 0x3f); p8++; } p16++; } *p8 = 0; // terminate UTF8 string return str8; }