16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2003-2013, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: ucnv_ext.cpp 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2003jun13 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Conversion extensions 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uset.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_bld.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_cnv.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_ext.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* to Unicode --------------------------------------------------------------- */ 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return lookup value for the byte, if found; else 0 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline uint32_t 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extFindToU(const uint32_t *toUSection, int32_t length, uint8_t byte) { 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t word0, word; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, start, limit; 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the input byte against the lowest and highest section bytes */ 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=(int32_t)UCNV_EXT_TO_U_GET_BYTE(toUSection[0]); 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=(int32_t)UCNV_EXT_TO_U_GET_BYTE(toUSection[length-1]); 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(byte<start || limit<byte) { 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* the byte is out of range */ 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==((limit-start)+1)) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* direct access on a linear array */ 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UCNV_EXT_TO_U_GET_VALUE(toUSection[byte-start]); /* could be 0 */ 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* word0 is suitable for <=toUSection[] comparison, word for <toUSection[] */ 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org word0=UCNV_EXT_TO_U_MAKE_WORD(byte, 0); 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Shift byte once instead of each section word and add 0xffffff. 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We will compare the shifted/added byte (bbffffff) against 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * section words which have byte values in the same bit position. 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If and only if byte bb < section byte ss then bbffffff<ssvvvvvv 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for all v=0..f 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * so we need not mask off the lower 24 bits of each section word. 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org word=word0|UCNV_EXT_TO_U_VALUE_MASK; 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* binary search */ 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=length; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=limit-start; 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<=1) { 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; /* done */ 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* start<limit-1 */ 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<=4) { 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* linear search for the last part */ 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(word0<=toUSection[start]) { 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(++start<limit && word0<=toUSection[start]) { 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(++start<limit && word0<=toUSection[start]) { 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* always break at start==limit-1 */ 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++start; 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=(start+limit)/2; 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(word<toUSection[i]) { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=i; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=i; 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* did we really find it? */ 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start<limit && byte==UCNV_EXT_TO_U_GET_BYTE(word=toUSection[start])) { 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UCNV_EXT_TO_U_GET_VALUE(word); /* never 0 */ 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* not found */ 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * TRUE if not an SI/SO stateful converter, 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or if the match length fits with the current converter state 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UCNV_EXT_TO_U_VERIFY_SISO_MATCH(sisoState, match) \ 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((sisoState)<0 || ((sisoState)==0) == (match==1)) 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * this works like ucnv_extMatchFromU() except 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - the first character is in pre 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - no trie is used 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - the returned matchLength is not offset by 2 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extMatchToU(const int32_t *cx, int8_t sisoState, 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *pre, int32_t preLength, 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *src, int32_t srcLength, 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *pMatchValue, 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool /*useFallback*/, UBool flush) { 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *toUTable, *toUSection; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value, matchValue; 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, j, idx, length, matchLength; 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t b; 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cx==NULL || cx[UCNV_EXT_TO_U_LENGTH]<=0) { 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* no extension data, no match */ 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize */ 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTable=UCNV_EXT_ARRAY(cx, UCNV_EXT_TO_U_INDEX, uint32_t); 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=0; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=0; 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=j=matchLength=0; 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sisoState==0) { 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* SBCS state of an SI/SO stateful converter, look at only exactly 1 byte */ 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(preLength>1) { 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* no match of a DBCS sequence in SBCS mode */ 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(preLength==1) { 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength=0; 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* preLength==0 */ { 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength>1) { 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength=1; 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flush=TRUE; 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we must not remember fallback matches when not using fallbacks */ 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* match input units until there is a full match or the input is consumed */ 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* go to the next section */ 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUSection=toUTable+idx; 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* read first pair of the section */ 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=*toUSection++; 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=UCNV_EXT_TO_U_GET_BYTE(value); 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=UCNV_EXT_TO_U_GET_VALUE(value); 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( value!=0 && 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (UCNV_EXT_TO_U_IS_ROUNDTRIP(value) || 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TO_U_USE_FALLBACK(useFallback)) && 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_TO_U_VERIFY_SISO_MATCH(sisoState, i+j) 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remember longest match so far */ 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=value; 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchLength=i+j; 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* match pre[] then src[] */ 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<preLength) { 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b=(uint8_t)pre[i++]; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(j<srcLength) { 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b=(uint8_t)src[j++]; 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all input consumed, partial match */ 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flush || (length=(i+j))>UCNV_EXT_MAX_BYTES) { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * end of the entire input stream, stop with the longest match so far 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or: partial match must not be longer than UCNV_EXT_MAX_BYTES 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * because it must fit into state buffers 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* continue with more input next time */ 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -length; 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* search for the current UChar */ 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=ucnv_extFindToU(toUSection, length, b); 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==0) { 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no match here, stop with the longest match so far */ 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(UCNV_EXT_TO_U_IS_PARTIAL(value)) { 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* partial match, continue */ 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=(int32_t)UCNV_EXT_TO_U_GET_PARTIAL_INDEX(value); 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( (UCNV_EXT_TO_U_IS_ROUNDTRIP(value) || 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TO_U_USE_FALLBACK(useFallback)) && 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_TO_U_VERIFY_SISO_MATCH(sisoState, i+j) 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* full match, stop with result */ 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=value; 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchLength=i+j; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* full match on fallback not taken, stop with the longest match so far */ 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(matchLength==0) { 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no match at all */ 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* return result */ 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pMatchValue=UCNV_EXT_TO_U_MASK_ROUNDTRIP(matchValue); 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return matchLength; 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline void 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extWriteToU(UConverter *cnv, const int32_t *cx, 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value, 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **target, const UChar *targetLimit, 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **offsets, int32_t srcIndex, 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the result */ 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(UCNV_EXT_TO_U_IS_CODE_POINT(value)) { 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output a single code point */ 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_toUWriteCodePoint( 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv, UCNV_EXT_TO_U_GET_CODE_POINT(value), 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetLimit, 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets, srcIndex, 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output a string - with correct data we have resultLength>0 */ 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_toUWriteUChars( 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv, 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_ARRAY(cx, UCNV_EXT_TO_U_UCHARS_INDEX, UChar)+ 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_TO_U_GET_INDEX(value), 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_TO_U_GET_LENGTH(value), 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetLimit, 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets, srcIndex, 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * get the SI/SO toU state (state 0 is for SBCS, 1 for DBCS), 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or 1 for DBCS-only, 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or -1 if the converter is not SI/SO stateful 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Note: For SI/SO stateful converters getting here, 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * cnv->mode==0 is equivalent to firstLength==1. 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UCNV_SISO_STATE(cnv) \ 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((cnv)->sharedData->mbcs.outputType==MBCS_OUTPUT_2_SISO ? (int8_t)(cnv)->mode : \ 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (cnv)->sharedData->mbcs.outputType==MBCS_OUTPUT_DBCS_ONLY ? 1 : -1) 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * target<targetLimit; set error code for overflow 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBool 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extInitialMatchToU(UConverter *cnv, const int32_t *cx, 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t firstLength, 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char **src, const char *srcLimit, 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **target, const UChar *targetLimit, 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **offsets, int32_t srcIndex, 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool flush, 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value = 0; /* initialize output-only param to 0 to silence gcc */ 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match; 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* try to match */ 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchToU(cx, (int8_t)UCNV_SISO_STATE(cnv), 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (const char *)cnv->toUBytes, firstLength, 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src, (int32_t)(srcLimit-*src), 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useFallback, flush); 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>0) { 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* advance src pointer for the consumed input */ 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src+=match-firstLength; 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result to target */ 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extWriteToU(cnv, cx, 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value, 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetLimit, 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets, srcIndex, 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(match<0) { 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* save state for partial match */ 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j; 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the first code point */ 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=(const char *)cnv->toUBytes; 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToUFirstLength=(int8_t)firstLength; 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=0; j<firstLength; ++j) { 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToU[j]=*s++; 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* now copy the newly consumed input */ 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*src; 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=-match; 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(; j<match; ++j) { 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToU[j]=*s++; 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src=s; /* same as *src=srcLimit; because we reached the end of input */ 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=(int8_t)match; 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* match==0 no match */ { 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UChar32 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extSimpleMatchToU(const int32_t *cx, 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t length, 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool useFallback) { 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value = 0; /* initialize output-only param to 0 to silence gcc */ 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match; 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length<=0) { 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* try to match */ 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchToU(cx, -1, 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source, length, 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 0, 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org useFallback, TRUE); 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match==length) { 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result for simple, single-character conversion */ 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(UCNV_EXT_TO_U_IS_CODE_POINT(value)) { 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UCNV_EXT_TO_U_GET_CODE_POINT(value); 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * return no match because 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match>0 && value points to string: simple conversion cannot handle multiple code points 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match>0 && match!=length: not all input consumed, forbidden for this function 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match==0: no match found in the first place 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match<0: partial match, not supported for simple conversion (and flush==TRUE) 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xfffe; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue partial match with new input 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * never called for simple, single-character conversion 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extContinueMatchToU(UConverter *cnv, 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs *pArgs, int32_t srcIndex, 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value = 0; /* initialize output-only param to 0 to silence gcc */ 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match, length; 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchToU(cnv->sharedData->mbcs.extIndexes, (int8_t)UCNV_SISO_STATE(cnv), 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToU, cnv->preToULength, 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source, (int32_t)(pArgs->sourceLimit-pArgs->source), 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useFallback, pArgs->flush); 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>0) { 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>=cnv->preToULength) { 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* advance src pointer for the consumed input */ 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source+=match-cnv->preToULength; 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=0; 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the match did not use all of preToU[] - keep the rest for replay */ 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=cnv->preToULength-match; 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->preToU, cnv->preToU+match, length); 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=(int8_t)-length; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result */ 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extWriteToU(cnv, cnv->sharedData->mbcs.extIndexes, 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value, 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &pArgs->target, pArgs->targetLimit, 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &pArgs->offsets, srcIndex, 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(match<0) { 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* save state for partial match */ 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j; 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* just _append_ the newly consumed input to preToU[] */ 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=-match; 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=cnv->preToULength; j<match; ++j) { 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToU[j]=*s++; 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=s; /* same as *src=srcLimit; because we reached the end of input */ 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=(int8_t)match; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* match==0 */ { 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * no match 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to split the previous input into two parts: 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1. The first codepage character is unmappable - that's how we got into 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * trying the extension data in the first place. 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to move it from the preToU buffer 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to the error buffer, set an error code, 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and prepare the rest of the previous input for 2. 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2. The rest of the previous input must be converted once we 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * come back from the callback for the first character. 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * At that time, we have to try again from scratch to convert 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * these input characters. 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The replay will be handled by the ucnv.c conversion code. 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move the first codepage character to the error field */ 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(cnv->toUBytes, cnv->preToU, cnv->preToUFirstLength); 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toULength=cnv->preToUFirstLength; 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move the rest up inside the buffer */ 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=cnv->preToULength-cnv->preToUFirstLength; 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>0) { 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->preToU, cnv->preToU+cnv->preToUFirstLength, length); 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* mark preToU for replay */ 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=(int8_t)-length; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the error code for unassigned */ 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INVALID_CHAR_FOUND; 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* from Unicode ------------------------------------------------------------- */ 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Use roundtrips, "good one-way" mappings, and some normal fallbacks. 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UBool 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgextFromUUseMapping(UBool useFallback, uint32_t value, UChar32 firstCP) { 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((value&UCNV_EXT_FROM_U_STATUS_MASK)!=0 || 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FROM_U_USE_FALLBACK(useFallback, firstCP)) && 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (value&UCNV_EXT_FROM_U_RESERVED_MASK)==0; 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return index of the UChar, if found; else <0 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline int32_t 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extFindFromU(const UChar *fromUSection, int32_t length, UChar u) { 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, start, limit; 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* binary search */ 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=length; 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=limit-start; 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<=1) { 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; /* done */ 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* start<limit-1 */ 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<=4) { 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* linear search for the last part */ 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(u<=fromUSection[start]) { 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(++start<limit && u<=fromUSection[start]) { 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(++start<limit && u<=fromUSection[start]) { 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* always break at start==limit-1 */ 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++start; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=(start+limit)/2; 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(u<fromUSection[i]) { 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=i; 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=i; 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* did we really find it? */ 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start<limit && u==fromUSection[start]) { 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return start; 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; /* not found */ 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param cx pointer to extension data; if NULL, returns 0 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param firstCP the first code point before all the other UChars 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param pre UChars that must match; !initialMatch: partial match with them 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param preLength length of pre, >=0 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param src UChars that can be used to complete a match 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param srcLength length of src, >=0 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param pMatchValue [out] output result value for the match from the data structure 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param useFallback "use fallback" flag, usually from cnv->useFallback 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param flush TRUE if the end of the input stream is reached 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return >1: matched, return value=total match length (number of input units matched) 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1: matched, no mapping but request for <subchar1> 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (only for the first code point) 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 0: no match 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <0: partial match, return value=negative total match length 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (partial matches are never returned for flush==TRUE) 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (partial matches are never returned as being longer than UCNV_EXT_MAX_UCHARS) 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the matchLength is 2 if only firstCP matched, and >2 if firstCP and 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * further code units matched 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extMatchFromU(const int32_t *cx, 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 firstCP, 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *pre, int32_t preLength, 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *src, int32_t srcLength, 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *pMatchValue, 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool useFallback, UBool flush) { 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *stage12, *stage3; 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *stage3b; 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *fromUTableUChars, *fromUSectionUChars; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *fromUTableValues, *fromUSectionValues; 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value, matchValue; 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, j, idx, length, matchLength; 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cx==NULL) { 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* no extension data, no match */ 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* trie lookup of firstCP */ 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=firstCP>>10; /* stage 1 index */ 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(idx>=cx[UCNV_EXT_FROM_U_STAGE_1_LENGTH]) { 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; /* the first code point is outside the trie */ 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage12=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_12_INDEX, uint16_t); 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage3=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_3_INDEX, uint16_t); 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=UCNV_EXT_FROM_U(stage12, stage3, idx, firstCP); 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage3b=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_3B_INDEX, uint32_t); 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=stage3b[idx]; 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==0) { 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Tests for (value&UCNV_EXT_FROM_U_RESERVED_MASK)==0: 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Do not interpret values with reserved bits used, for forward compatibility, 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and do not even remember intermediate results with reserved bits used. 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(UCNV_EXT_TO_U_IS_PARTIAL(value)) { 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* partial match, enter the loop below */ 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=(int32_t)UCNV_EXT_FROM_U_GET_PARTIAL_INDEX(value); 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize */ 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUTableUChars=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_UCHARS_INDEX, UChar); 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUTableValues=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_VALUES_INDEX, uint32_t); 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=0; 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=j=matchLength=0; 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we must not remember fallback matches when not using fallbacks */ 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* match input units until there is a full match or the input is consumed */ 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* go to the next section */ 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUSectionUChars=fromUTableUChars+idx; 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUSectionValues=fromUTableValues+idx; 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* read first pair of the section */ 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*fromUSectionUChars++; 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=*fromUSectionValues++; 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value!=0 && extFromUUseMapping(useFallback, value, firstCP)) { 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remember longest match so far */ 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=value; 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchLength=2+i+j; 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* match pre[] then src[] */ 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<preLength) { 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=pre[i++]; 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(j<srcLength) { 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=src[j++]; 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all input consumed, partial match */ 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flush || (length=(i+j))>UCNV_EXT_MAX_UCHARS) { 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * end of the entire input stream, stop with the longest match so far 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or: partial match must not be longer than UCNV_EXT_MAX_UCHARS 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * because it must fit into state buffers 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* continue with more input next time */ 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -(2+length); 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* search for the current UChar */ 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=ucnv_extFindFromU(fromUSectionUChars, length, c); 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(idx<0) { 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no match here, stop with the longest match so far */ 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=fromUSectionValues[idx]; 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(UCNV_EXT_FROM_U_IS_PARTIAL(value)) { 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* partial match, continue */ 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idx=(int32_t)UCNV_EXT_FROM_U_GET_PARTIAL_INDEX(value); 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(extFromUUseMapping(useFallback, value, firstCP)) { 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* full match, stop with result */ 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=value; 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchLength=2+i+j; 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* full match on fallback not taken, stop with the longest match so far */ 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(matchLength==0) { 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no match at all */ 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* result from firstCP trie lookup */ { 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(extFromUUseMapping(useFallback, value, firstCP)) { 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* full match, stop with result */ 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchValue=value; 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchLength=2; 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* fallback not taken */ 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* return result */ 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(matchValue==UCNV_EXT_FROM_U_SUBCHAR1) { 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 1; /* assert matchLength==2 */ 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pMatchValue=matchValue; 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return matchLength; 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param value fromUnicode mapping table value; ignores roundtrip and reserved bits 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline void 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extWriteFromU(UConverter *cnv, const int32_t *cx, 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value, 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char **target, const char *targetLimit, 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **offsets, int32_t srcIndex, 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t buffer[1+UCNV_EXT_MAX_BYTES]; 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint8_t *result; 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length, prevLength; 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=UCNV_EXT_FROM_U_GET_LENGTH(value); 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=(uint32_t)UCNV_EXT_FROM_U_GET_DATA(value); 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the result */ 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length<=UCNV_EXT_FROM_U_MAX_DIRECT_LENGTH) { 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Generate a byte array and then write it below. 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is not the fastest possible way, but it should be ok for 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * extension mappings, and it is much simpler. 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Offset and overflow handling are only done once this way. 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t *p=buffer+1; /* reserve buffer[0] for shiftByte below */ 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(length) { 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 3: 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p++=(uint8_t)(value>>16); 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 2: /*fall through*/ 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p++=(uint8_t)(value>>8); 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 1: /*fall through*/ 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p++=(uint8_t)value; 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; /* will never occur */ 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result=buffer+1; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_BYTES_INDEX, uint8_t)+value; 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* with correct data we have length>0 */ 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((prevLength=cnv->fromUnicodeStatus)!=0) { 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* handle SI/SO stateful output */ 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t shiftByte; 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prevLength>1 && length==1) { 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* change from double-byte mode to single-byte */ 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org shiftByte=(uint8_t)UCNV_SI; 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUnicodeStatus=1; 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(prevLength==1 && length>1) { 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* change from single-byte mode to double-byte */ 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org shiftByte=(uint8_t)UCNV_SO; 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUnicodeStatus=2; 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org shiftByte=0; 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(shiftByte!=0) { 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prepend the shift byte to the result bytes */ 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org buffer[0]=shiftByte; 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result!=buffer+1) { 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(buffer+1, result, length); 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result=buffer; 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++length; 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_fromUWriteBytes(cnv, (const char *)result, length, 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetLimit, 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets, srcIndex, 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * target<targetLimit; set error code for overflow 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBool 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extInitialMatchFromU(UConverter *cnv, const int32_t *cx, 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 cp, 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar **src, const UChar *srcLimit, 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char **target, const char *targetLimit, 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **offsets, int32_t srcIndex, 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool flush, 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value = 0; /* initialize output-only param to 0 to silence gcc */ 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match; 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* try to match */ 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchFromU(cx, cp, 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 0, 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src, (int32_t)(srcLimit-*src), 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useFallback, flush); 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reject a match if the result is a single byte for DBCS-only */ 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( match>=2 && 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org !(UCNV_EXT_FROM_U_GET_LENGTH(value)==1 && 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->sharedData->mbcs.outputType==MBCS_OUTPUT_DBCS_ONLY) 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* advance src pointer for the consumed input */ 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src+=match-2; /* remove 2 for the initial code point */ 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result to target */ 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extWriteFromU(cnv, cx, 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value, 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetLimit, 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets, srcIndex, 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(match<0) { 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* save state for partial match */ 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s; 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j; 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the first code point */ 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromUFirstCP=cp; 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* now copy the newly consumed input */ 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*src; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=-match-2; /* remove 2 for the initial code point */ 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=0; j<match; ++j) { 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromU[j]=*s++; 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *src=s; /* same as *src=srcLimit; because we reached the end of input */ 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=(int8_t)match; 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(match==1) { 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* matched, no mapping but request for <subchar1> */ 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useSubChar1=TRUE; 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* match==0 no match */ { 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Used by ISO 2022 implementation. 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return number of bytes in *pValue; negative number if fallback; 0 for no mapping 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extSimpleMatchFromU(const int32_t *cx, 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 cp, uint32_t *pValue, 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool useFallback) { 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value; 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match; 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* try to match */ 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchFromU(cx, 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cp, 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 0, 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 0, 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org useFallback, TRUE); 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>=2) { 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result for simple, single-character conversion */ 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int isRoundtrip; 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isRoundtrip=UCNV_EXT_FROM_U_IS_ROUNDTRIP(value); 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=UCNV_EXT_FROM_U_GET_LENGTH(value); 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=(uint32_t)UCNV_EXT_FROM_U_GET_DATA(value); 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length<=UCNV_EXT_FROM_U_MAX_DIRECT_LENGTH) { 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pValue=value; 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return isRoundtrip ? length : -length; 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 /* not currently used */ 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(length==4) { 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* de-serialize a 4-byte result */ 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint8_t *result=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_BYTES_INDEX, uint8_t)+value; 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pValue= 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((uint32_t)result[0]<<24)| 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((uint32_t)result[1]<<16)| 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((uint32_t)result[2]<<8)| 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result[3]; 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return isRoundtrip ? 4 : -4; 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * return no match because 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match>1 && resultLength>4: result too long for simple conversion 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match==1: no match found, <subchar1> preferred 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match==0: no match found in the first place 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - match<0: partial match, not supported for simple conversion (and flush==TRUE) 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue partial match with new input, requires cnv->preFromUFirstCP>=0 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * never called for simple, single-character conversion 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extContinueMatchFromU(UConverter *cnv, 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs *pArgs, int32_t srcIndex, 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value = 0; /* initialize output-only param to 0 to silence gcc */ 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t match; 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=ucnv_extMatchFromU(cnv->sharedData->mbcs.extIndexes, 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromUFirstCP, 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromU, cnv->preFromULength, 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source, (int32_t)(pArgs->sourceLimit-pArgs->source), 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &value, 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useFallback, pArgs->flush); 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>=2) { 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match-=2; /* remove 2 for the initial code point */ 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match>=cnv->preFromULength) { 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* advance src pointer for the consumed input */ 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source+=match-cnv->preFromULength; 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=0; 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the match did not use all of preFromU[] - keep the rest for replay */ 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=cnv->preFromULength-match; 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->preFromU, cnv->preFromU+match, length*U_SIZEOF_UCHAR); 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=(int8_t)-length; 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* finish the partial match */ 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromUFirstCP=U_SENTINEL; 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write result */ 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extWriteFromU(cnv, cnv->sharedData->mbcs.extIndexes, 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value, 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &pArgs->target, pArgs->targetLimit, 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &pArgs->offsets, srcIndex, 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(match<0) { 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* save state for partial match */ 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s; 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j; 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* just _append_ the newly consumed input to preFromU[] */ 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=-match-2; /* remove 2 for the initial code point */ 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=cnv->preFromULength; j<match; ++j) { 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(j>=0); 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromU[j]=*s++; 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=s; /* same as *src=srcLimit; because we reached the end of input */ 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=(int8_t)match; 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* match==0 or 1 */ { 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * no match 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to split the previous input into two parts: 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1. The first code point is unmappable - that's how we got into 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * trying the extension data in the first place. 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to move it from the preFromU buffer 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to the error buffer, set an error code, 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and prepare the rest of the previous input for 2. 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2. The rest of the previous input must be converted once we 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * come back from the callback for the first code point. 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * At that time, we have to try again from scratch to convert 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * these input characters. 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The replay will be handled by the ucnv.c conversion code. 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match==1) { 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* matched, no mapping but request for <subchar1> */ 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useSubChar1=TRUE; 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move the first code point to the error field */ 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUChar32=cnv->preFromUFirstCP; 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromUFirstCP=U_SENTINEL; 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* mark preFromU for replay */ 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=-cnv->preFromULength; 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the error code for unassigned */ 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INVALID_CHAR_FOUND; 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgextSetUseMapping(UConverterUnicodeSet which, int32_t minLength, uint32_t value) { 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(which==UCNV_ROUNDTRIP_SET) { 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Add only code points for which the roundtrip flag is set. 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not add any fallbacks, even if ucnv_fromUnicode() would use them 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // (fallbacks from PUA). See the API docs for ucnv_getUnicodeSet(). 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // By analogy, also do not add "good one-way" mappings. 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not add entries with reserved bits set. 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(((value&(UCNV_EXT_FROM_U_ROUNDTRIP_FLAG|UCNV_EXT_FROM_U_RESERVED_MASK))!= 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCNV_EXT_FROM_U_ROUNDTRIP_FLAG)) { 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* UCNV_ROUNDTRIP_AND_FALLBACK_SET */ { 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not add entries with reserved bits set. 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((value&UCNV_EXT_FROM_U_RESERVED_MASK)!=0) { 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not add <subchar1> entries or other (future?) pseudo-entries 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // with an output length of 0. 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UCNV_EXT_FROM_U_GET_LENGTH(value)>=minLength; 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extGetUnicodeSetString(const UConverterSharedData *sharedData, 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *cx, 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const USetAdder *sa, 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterUnicodeSet which, 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t minLength, 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 firstCP, 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar s[UCNV_EXT_MAX_UCHARS], int32_t length, 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sectionIndex, 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *fromUSectionUChars; 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *fromUSectionValues; 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value; 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, count; 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUSectionUChars=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_UCHARS_INDEX, UChar)+sectionIndex; 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUSectionValues=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_VALUES_INDEX, uint32_t)+sectionIndex; 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* read first pair of the section */ 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=*fromUSectionUChars++; 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=*fromUSectionValues++; 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(extSetUseMapping(which, minLength, value)) { 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==U16_LENGTH(firstCP)) { 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* add the initial code point */ 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sa->add(sa->set, firstCP); 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* add the string so far */ 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sa->addString(sa->set, s, length); 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* append this code unit and recurse or add the string */ 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s[length]=fromUSectionUChars[i]; 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=fromUSectionValues[i]; 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==0) { 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no mapping, do nothing */ 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(UCNV_EXT_FROM_U_IS_PARTIAL(value)) { 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extGetUnicodeSetString( 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sharedData, cx, sa, which, minLength, 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstCP, s, length+1, 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (int32_t)UCNV_EXT_FROM_U_GET_PARTIAL_INDEX(value), 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(extSetUseMapping(which, minLength, value)) { 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sa->addString(sa->set, s, length+1); 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_extGetUnicodeSet(const UConverterSharedData *sharedData, 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const USetAdder *sa, 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterUnicodeSet which, 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterSetFilter filter, 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *cx; 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *stage12, *stage3, *ps2, *ps3; 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *stage3b; 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value; 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t st1, stage1Length, st2, st3, minLength; 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar s[UCNV_EXT_MAX_UCHARS]; 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 c; 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cx=sharedData->mbcs.extIndexes; 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cx==NULL) { 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage12=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_12_INDEX, uint16_t); 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage3=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_3_INDEX, uint16_t); 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage3b=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_STAGE_3B_INDEX, uint32_t); 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stage1Length=cx[UCNV_EXT_FROM_U_STAGE_1_LENGTH]; 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* enumerate the from-Unicode trie table */ 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=0; /* keep track of the current code point while enumerating */ 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(filter==UCNV_SET_FILTER_2022_CN) { 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org minLength=3; 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if( sharedData->mbcs.outputType==MBCS_OUTPUT_DBCS_ONLY || 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter!=UCNV_SET_FILTER_NONE 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* DBCS-only, ignore single-byte results */ 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org minLength=2; 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org minLength=1; 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the trie enumeration is almost the same as 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in MBCSGetUnicodeSet() for MBCS_OUTPUT_1 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(st1=0; st1<stage1Length; ++st1) { 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org st2=stage12[st1]; 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(st2>stage1Length) { 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ps2=stage12+st2; 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(st2=0; st2<64; ++st2) { 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((st3=(int32_t)ps2[st2]<<UCNV_EXT_STAGE_2_LEFT_SHIFT)!=0) { 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* read the stage 3 block */ 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ps3=stage3+st3; 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=stage3b[*ps3++]; 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==0) { 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no mapping, do nothing */ 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(UCNV_EXT_FROM_U_IS_PARTIAL(value)) { 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Recurse for partial results. 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=0; 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_APPEND_UNSAFE(s, length, c); 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_extGetUnicodeSetString( 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sharedData, cx, sa, which, minLength, 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c, s, length, 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (int32_t)UCNV_EXT_FROM_U_GET_PARTIAL_INDEX(value), 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(extSetUseMapping(which, minLength, value)) { 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(filter) { 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_SET_FILTER_2022_CN: 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(UCNV_EXT_FROM_U_GET_LENGTH(value)==3 && UCNV_EXT_FROM_U_GET_DATA(value)<=0x82ffff)) { 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_SET_FILTER_SJIS: 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(UCNV_EXT_FROM_U_GET_LENGTH(value)==2 && (value=UCNV_EXT_FROM_U_GET_DATA(value))>=0x8140 && value<=0xeffc)) { 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_SET_FILTER_GR94DBCS: 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(UCNV_EXT_FROM_U_GET_LENGTH(value)==2 && 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (uint16_t)((value=UCNV_EXT_FROM_U_GET_DATA(value))-0xa1a1)<=(0xfefe - 0xa1a1) && 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (uint8_t)(value-0xa1)<=(0xfe - 0xa1))) { 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_SET_FILTER_HZ: 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(UCNV_EXT_FROM_U_GET_LENGTH(value)==2 && 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (uint16_t)((value=UCNV_EXT_FROM_U_GET_DATA(value))-0xa1a1)<=(0xfdfe - 0xa1a1) && 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (uint8_t)(value-0xa1)<=(0xfe - 0xa1))) { 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UCNV_SET_FILTER_NONE, 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or UCNV_SET_FILTER_DBCS_ONLY which is handled via minLength 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sa->add(sa->set, c); 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while((++c&0xf)!=0); 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c+=16; /* empty stage 3 block */ 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c+=1024; /* empty stage 2 block */ 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */ 1138