|
ICU 73.2
73.2
|
00001 // © 2017 and later: Unicode, Inc. and others. 00002 // License & terms of use: http://www.unicode.org/copyright.html 00003 00004 // ucptrie.h (modified from utrie2.h) 00005 // created: 2017dec29 Markus W. Scherer 00006 00007 #ifndef __UCPTRIE_H__ 00008 #define __UCPTRIE_H__ 00009 00010 #include "unicode/utypes.h" 00011 #include "unicode/ucpmap.h" 00012 #include "unicode/utf8.h" 00013 00014 #if U_SHOW_CPLUSPLUS_API 00015 #include "unicode/localpointer.h" 00016 #endif // U_SHOW_CPLUSPLUS_API 00017 00018 U_CDECL_BEGIN 00019 00028 #ifndef U_IN_DOXYGEN 00029 00030 typedef union UCPTrieData { 00032 const void *ptr0; 00034 const uint16_t *ptr16; 00036 const uint32_t *ptr32; 00038 const uint8_t *ptr8; 00039 } UCPTrieData; 00040 #endif 00041 00059 struct UCPTrie { 00060 #ifndef U_IN_DOXYGEN 00061 00062 const uint16_t *index; 00064 UCPTrieData data; 00065 00067 int32_t indexLength; 00069 int32_t dataLength; 00071 UChar32 highStart; 00073 uint16_t shifted12HighStart; 00074 00076 int8_t type; // UCPTrieType 00078 int8_t valueWidth; // UCPTrieValueWidth 00079 00081 uint32_t reserved32; 00083 uint16_t reserved16; 00084 00090 uint16_t index3NullOffset; 00096 int32_t dataNullOffset; 00098 uint32_t nullValue; 00099 00100 #ifdef UCPTRIE_DEBUG 00101 00102 const char *name; 00103 #endif 00104 #endif 00105 }; 00106 #ifndef U_IN_DOXYGEN 00107 typedef struct UCPTrie UCPTrie; 00108 #endif 00109 00119 enum UCPTrieType { 00125 UCPTRIE_TYPE_ANY = -1, 00130 UCPTRIE_TYPE_FAST, 00135 UCPTRIE_TYPE_SMALL 00136 }; 00137 #ifndef U_IN_DOXYGEN 00138 typedef enum UCPTrieType UCPTrieType; 00139 #endif 00140 00149 enum UCPTrieValueWidth { 00155 UCPTRIE_VALUE_BITS_ANY = -1, 00161 UCPTRIE_VALUE_BITS_16, 00166 UCPTRIE_VALUE_BITS_32, 00172 UCPTRIE_VALUE_BITS_8 00173 }; 00174 #ifndef U_IN_DOXYGEN 00175 typedef enum UCPTrieValueWidth UCPTrieValueWidth; 00176 #endif 00177 00204 U_CAPI UCPTrie * U_EXPORT2 00205 ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth, 00206 const void *data, int32_t length, int32_t *pActualLength, 00207 UErrorCode *pErrorCode); 00208 00215 U_CAPI void U_EXPORT2 00216 ucptrie_close(UCPTrie *trie); 00217 00227 U_CAPI UCPTrieType U_EXPORT2 00228 ucptrie_getType(const UCPTrie *trie); 00229 00239 U_CAPI UCPTrieValueWidth U_EXPORT2 00240 ucptrie_getValueWidth(const UCPTrie *trie); 00241 00256 U_CAPI uint32_t U_EXPORT2 00257 ucptrie_get(const UCPTrie *trie, UChar32 c); 00258 00295 U_CAPI UChar32 U_EXPORT2 00296 ucptrie_getRange(const UCPTrie *trie, UChar32 start, 00297 UCPMapRangeOption option, uint32_t surrogateValue, 00298 UCPMapValueFilter *filter, const void *context, uint32_t *pValue); 00299 00315 U_CAPI int32_t U_EXPORT2 00316 ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode); 00317 00326 #define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i]) 00327 00336 #define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i]) 00337 00346 #define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i]) 00347 00358 #define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c)) 00359 00370 #define UCPTRIE_SMALL_GET(trie, dataAccess, c) \ 00371 dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c)) 00372 00386 #define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \ 00387 (c) = *(src)++; \ 00388 int32_t __index; \ 00389 if (!U16_IS_SURROGATE(c)) { \ 00390 __index = _UCPTRIE_FAST_INDEX(trie, c); \ 00391 } else { \ 00392 uint16_t __c2; \ 00393 if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \ 00394 ++(src); \ 00395 (c) = U16_GET_SUPPLEMENTARY((c), __c2); \ 00396 __index = _UCPTRIE_SMALL_INDEX(trie, c); \ 00397 } else { \ 00398 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \ 00399 } \ 00400 } \ 00401 (result) = dataAccess(trie, __index); \ 00402 } UPRV_BLOCK_MACRO_END 00403 00417 #define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \ 00418 (c) = *--(src); \ 00419 int32_t __index; \ 00420 if (!U16_IS_SURROGATE(c)) { \ 00421 __index = _UCPTRIE_FAST_INDEX(trie, c); \ 00422 } else { \ 00423 uint16_t __c2; \ 00424 if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \ 00425 --(src); \ 00426 (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \ 00427 __index = _UCPTRIE_SMALL_INDEX(trie, c); \ 00428 } else { \ 00429 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \ 00430 } \ 00431 } \ 00432 (result) = dataAccess(trie, __index); \ 00433 } UPRV_BLOCK_MACRO_END 00434 00451 #define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \ 00452 int32_t __lead = (uint8_t)*(src)++; \ 00453 if (!U8_IS_SINGLE(__lead)) { \ 00454 uint8_t __t1, __t2, __t3; \ 00455 if ((src) != (limit) && \ 00456 (__lead >= 0xe0 ? \ 00457 __lead < 0xf0 ? /* U+0800..U+FFFF except surrogates */ \ 00458 U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \ 00459 ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \ 00460 (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \ 00461 : /* U+10000..U+10FFFF */ \ 00462 (__lead -= 0xf0) <= 4 && \ 00463 U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \ 00464 (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \ 00465 (__t2 = *(src) - 0x80) <= 0x3f && \ 00466 ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \ 00467 (__lead = __lead >= (trie)->shifted12HighStart ? \ 00468 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \ 00469 ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \ 00470 : /* U+0080..U+07FF */ \ 00471 __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \ 00472 (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \ 00473 ++(src); \ 00474 } else { \ 00475 __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; /* ill-formed*/ \ 00476 } \ 00477 } \ 00478 (result) = dataAccess(trie, __lead); \ 00479 } UPRV_BLOCK_MACRO_END 00480 00497 #define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \ 00498 int32_t __index = (uint8_t)*--(src); \ 00499 if (!U8_IS_SINGLE(__index)) { \ 00500 __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \ 00501 (const uint8_t *)(src)); \ 00502 (src) -= __index & 7; \ 00503 __index >>= 3; \ 00504 } \ 00505 (result) = dataAccess(trie, __index); \ 00506 } UPRV_BLOCK_MACRO_END 00507 00517 #define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c) 00518 00530 #define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c)) 00531 00542 #define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c)) 00543 00544 /* Internal definitions ----------------------------------------------------- */ 00545 00546 #ifndef U_IN_DOXYGEN 00547 00553 enum { 00555 UCPTRIE_FAST_SHIFT = 6, 00556 00558 UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT, 00559 00561 UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1, 00562 00564 UCPTRIE_SMALL_MAX = 0xfff, 00565 00571 UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1, 00577 UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2 00578 }; 00579 00580 /* Internal functions and macros -------------------------------------------- */ 00581 // Do not conditionalize with #ifndef U_HIDE_INTERNAL_API, needed for public API 00582 00584 U_CAPI int32_t U_EXPORT2 00585 ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c); 00586 00588 U_CAPI int32_t U_EXPORT2 00589 ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3); 00590 00596 U_CAPI int32_t U_EXPORT2 00597 ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c, 00598 const uint8_t *start, const uint8_t *src); 00599 00601 #define _UCPTRIE_FAST_INDEX(trie, c) \ 00602 ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK)) 00603 00605 #define _UCPTRIE_SMALL_INDEX(trie, c) \ 00606 ((c) >= (trie)->highStart ? \ 00607 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \ 00608 ucptrie_internalSmallIndex(trie, c)) 00609 00615 #define _UCPTRIE_CP_INDEX(trie, fastMax, c) \ 00616 ((uint32_t)(c) <= (uint32_t)(fastMax) ? \ 00617 _UCPTRIE_FAST_INDEX(trie, c) : \ 00618 (uint32_t)(c) <= 0x10ffff ? \ 00619 _UCPTRIE_SMALL_INDEX(trie, c) : \ 00620 (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET) 00621 00622 U_CDECL_END 00623 00624 #endif // U_IN_DOXYGEN 00625 00626 #if U_SHOW_CPLUSPLUS_API 00627 00628 U_NAMESPACE_BEGIN 00629 00639 U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close); 00640 00641 U_NAMESPACE_END 00642 00643 #endif // U_SHOW_CPLUSPLUS_API 00644 00645 #endif
1.7.6.1