00001
00002
00003
00004
00005
00006
00007 #ifndef __UCPTRIE_H__
00008 #define __UCPTRIE_H__
00009
00010 #include "unicode/utypes.h"
00011
00012 #include "unicode/localpointer.h"
00013 #include "unicode/ucpmap.h"
00014 #include "unicode/utf8.h"
00015
00016 U_CDECL_BEGIN
00017
00027 #ifndef U_IN_DOXYGEN
00028
00029 typedef union UCPTrieData {
00031 const void *ptr0;
00033 const uint16_t *ptr16;
00035 const uint32_t *ptr32;
00037 const uint8_t *ptr8;
00038 } UCPTrieData;
00039 #endif
00040
00058 struct UCPTrie {
00059 #ifndef U_IN_DOXYGEN
00060
00061 const uint16_t *index;
00063 UCPTrieData data;
00064
00066 int32_t indexLength;
00068 int32_t dataLength;
00070 UChar32 highStart;
00072 uint16_t shifted12HighStart;
00073
00075 int8_t type;
00077 int8_t valueWidth;
00078
00080 uint32_t reserved32;
00082 uint16_t reserved16;
00083
00089 uint16_t index3NullOffset;
00095 int32_t dataNullOffset;
00097 uint32_t nullValue;
00098
00099 #ifdef UCPTRIE_DEBUG
00100
00101 const char *name;
00102 #endif
00103 #endif
00104 };
00105 #ifndef U_IN_DOXYGEN
00106 typedef struct UCPTrie UCPTrie;
00107 #endif
00108
00118 enum UCPTrieType {
00124 UCPTRIE_TYPE_ANY = -1,
00129 UCPTRIE_TYPE_FAST,
00134 UCPTRIE_TYPE_SMALL
00135 };
00136 #ifndef U_IN_DOXYGEN
00137 typedef enum UCPTrieType UCPTrieType;
00138 #endif
00139
00148 enum UCPTrieValueWidth {
00154 UCPTRIE_VALUE_BITS_ANY = -1,
00160 UCPTRIE_VALUE_BITS_16,
00165 UCPTRIE_VALUE_BITS_32,
00171 UCPTRIE_VALUE_BITS_8
00172 };
00173 #ifndef U_IN_DOXYGEN
00174 typedef enum UCPTrieValueWidth UCPTrieValueWidth;
00175 #endif
00176
00203 U_CAPI UCPTrie * U_EXPORT2
00204 ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
00205 const void *data, int32_t length, int32_t *pActualLength,
00206 UErrorCode *pErrorCode);
00207
00214 U_CAPI void U_EXPORT2
00215 ucptrie_close(UCPTrie *trie);
00216
00226 U_CAPI UCPTrieType U_EXPORT2
00227 ucptrie_getType(const UCPTrie *trie);
00228
00238 U_CAPI UCPTrieValueWidth U_EXPORT2
00239 ucptrie_getValueWidth(const UCPTrie *trie);
00240
00255 U_CAPI uint32_t U_EXPORT2
00256 ucptrie_get(const UCPTrie *trie, UChar32 c);
00257
00294 U_CAPI UChar32 U_EXPORT2
00295 ucptrie_getRange(const UCPTrie *trie, UChar32 start,
00296 UCPMapRangeOption option, uint32_t surrogateValue,
00297 UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
00298
00314 U_CAPI int32_t U_EXPORT2
00315 ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode);
00316
00325 #define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i])
00326
00335 #define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i])
00336
00345 #define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i])
00346
00357 #define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c))
00358
00369 #define UCPTRIE_SMALL_GET(trie, dataAccess, c) \
00370 dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c))
00371
00385 #define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
00386 (c) = *(src)++; \
00387 int32_t __index; \
00388 if (!U16_IS_SURROGATE(c)) { \
00389 __index = _UCPTRIE_FAST_INDEX(trie, c); \
00390 } else { \
00391 uint16_t __c2; \
00392 if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \
00393 ++(src); \
00394 (c) = U16_GET_SUPPLEMENTARY((c), __c2); \
00395 __index = _UCPTRIE_SMALL_INDEX(trie, c); \
00396 } else { \
00397 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00398 } \
00399 } \
00400 (result) = dataAccess(trie, __index); \
00401 } UPRV_BLOCK_MACRO_END
00402
00416 #define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
00417 (c) = *--(src); \
00418 int32_t __index; \
00419 if (!U16_IS_SURROGATE(c)) { \
00420 __index = _UCPTRIE_FAST_INDEX(trie, c); \
00421 } else { \
00422 uint16_t __c2; \
00423 if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \
00424 --(src); \
00425 (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \
00426 __index = _UCPTRIE_SMALL_INDEX(trie, c); \
00427 } else { \
00428 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00429 } \
00430 } \
00431 (result) = dataAccess(trie, __index); \
00432 } UPRV_BLOCK_MACRO_END
00433
00450 #define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
00451 int32_t __lead = (uint8_t)*(src)++; \
00452 if (!U8_IS_SINGLE(__lead)) { \
00453 uint8_t __t1, __t2, __t3; \
00454 if ((src) != (limit) && \
00455 (__lead >= 0xe0 ? \
00456 __lead < 0xf0 ? \
00457 U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \
00458 ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \
00459 (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \
00460 : \
00461 (__lead -= 0xf0) <= 4 && \
00462 U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \
00463 (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \
00464 (__t2 = *(src) - 0x80) <= 0x3f && \
00465 ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \
00466 (__lead = __lead >= (trie)->shifted12HighStart ? \
00467 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
00468 ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \
00469 : \
00470 __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \
00471 (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \
00472 ++(src); \
00473 } else { \
00474 __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00475 } \
00476 } \
00477 (result) = dataAccess(trie, __lead); \
00478 } UPRV_BLOCK_MACRO_END
00479
00496 #define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
00497 int32_t __index = (uint8_t)*--(src); \
00498 if (!U8_IS_SINGLE(__index)) { \
00499 __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \
00500 (const uint8_t *)(src)); \
00501 (src) -= __index & 7; \
00502 __index >>= 3; \
00503 } \
00504 (result) = dataAccess(trie, __index); \
00505 } UPRV_BLOCK_MACRO_END
00506
00516 #define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c)
00517
00529 #define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c))
00530
00541 #define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c))
00542
00543
00544
00545 #ifndef U_IN_DOXYGEN
00546
00552 enum {
00554 UCPTRIE_FAST_SHIFT = 6,
00555
00557 UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT,
00558
00560 UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1,
00561
00563 UCPTRIE_SMALL_MAX = 0xfff,
00564
00570 UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1,
00576 UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2
00577 };
00578
00579
00580
00581
00583 U_INTERNAL int32_t U_EXPORT2
00584 ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c);
00585
00587 U_INTERNAL int32_t U_EXPORT2
00588 ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3);
00589
00595 U_INTERNAL int32_t U_EXPORT2
00596 ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
00597 const uint8_t *start, const uint8_t *src);
00598
00600 #define _UCPTRIE_FAST_INDEX(trie, c) \
00601 ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK))
00602
00604 #define _UCPTRIE_SMALL_INDEX(trie, c) \
00605 ((c) >= (trie)->highStart ? \
00606 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
00607 ucptrie_internalSmallIndex(trie, c))
00608
00614 #define _UCPTRIE_CP_INDEX(trie, fastMax, c) \
00615 ((uint32_t)(c) <= (uint32_t)(fastMax) ? \
00616 _UCPTRIE_FAST_INDEX(trie, c) : \
00617 (uint32_t)(c) <= 0x10ffff ? \
00618 _UCPTRIE_SMALL_INDEX(trie, c) : \
00619 (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET)
00620
00621 U_CDECL_END
00622
00623 #endif // U_IN_DOXYGEN
00624
00625 #if U_SHOW_CPLUSPLUS_API
00626
00627 U_NAMESPACE_BEGIN
00628
00638 U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close);
00639
00640 U_NAMESPACE_END
00641
00642 #endif // U_SHOW_CPLUSPLUS_API
00643
00644 #endif