00001
00002
00003
00004
00005
00006
00007 #ifndef __UCPTRIE_H__
00008 #define __UCPTRIE_H__
00009
00010 #include "unicode/utypes.h"
00011
00012 #ifndef U_HIDE_DRAFT_API
00013
00014 #include "unicode/localpointer.h"
00015 #include "unicode/ucpmap.h"
00016 #include "unicode/utf8.h"
00017
00018 U_CDECL_BEGIN
00019
00029 #ifndef U_IN_DOXYGEN
00030
00031 typedef union UCPTrieData {
00033 const void *ptr0;
00035 const uint16_t *ptr16;
00037 const uint32_t *ptr32;
00039 const uint8_t *ptr8;
00040 } UCPTrieData;
00041 #endif
00042
00060 struct UCPTrie {
00061 #ifndef U_IN_DOXYGEN
00062
00063 const uint16_t *index;
00065 UCPTrieData data;
00066
00068 int32_t indexLength;
00070 int32_t dataLength;
00072 UChar32 highStart;
00074 uint16_t shifted12HighStart;
00075
00077 int8_t type;
00079 int8_t valueWidth;
00080
00082 uint32_t reserved32;
00084 uint16_t reserved16;
00085
00091 uint16_t index3NullOffset;
00097 int32_t dataNullOffset;
00099 uint32_t nullValue;
00100
00101 #ifdef UCPTRIE_DEBUG
00102
00103 const char *name;
00104 #endif
00105 #endif
00106 };
00107 #ifndef U_IN_DOXYGEN
00108 typedef struct UCPTrie UCPTrie;
00109 #endif
00110
00120 enum UCPTrieType {
00126 UCPTRIE_TYPE_ANY = -1,
00131 UCPTRIE_TYPE_FAST,
00136 UCPTRIE_TYPE_SMALL
00137 };
00138 #ifndef U_IN_DOXYGEN
00139 typedef enum UCPTrieType UCPTrieType;
00140 #endif
00141
00150 enum UCPTrieValueWidth {
00156 UCPTRIE_VALUE_BITS_ANY = -1,
00162 UCPTRIE_VALUE_BITS_16,
00167 UCPTRIE_VALUE_BITS_32,
00173 UCPTRIE_VALUE_BITS_8
00174 };
00175 #ifndef U_IN_DOXYGEN
00176 typedef enum UCPTrieValueWidth UCPTrieValueWidth;
00177 #endif
00178
00205 U_CAPI UCPTrie * U_EXPORT2
00206 ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
00207 const void *data, int32_t length, int32_t *pActualLength,
00208 UErrorCode *pErrorCode);
00209
00216 U_CAPI void U_EXPORT2
00217 ucptrie_close(UCPTrie *trie);
00218
00219 #if U_SHOW_CPLUSPLUS_API
00220
00221 U_NAMESPACE_BEGIN
00222
00232 U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close);
00233
00234 U_NAMESPACE_END
00235
00236 #endif
00237
00247 U_CAPI UCPTrieType U_EXPORT2
00248 ucptrie_getType(const UCPTrie *trie);
00249
00259 U_CAPI UCPTrieValueWidth U_EXPORT2
00260 ucptrie_getValueWidth(const UCPTrie *trie);
00261
00276 U_CAPI uint32_t U_EXPORT2
00277 ucptrie_get(const UCPTrie *trie, UChar32 c);
00278
00315 U_CAPI UChar32 U_EXPORT2
00316 ucptrie_getRange(const UCPTrie *trie, UChar32 start,
00317 UCPMapRangeOption option, uint32_t surrogateValue,
00318 UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
00319
00335 U_CAPI int32_t U_EXPORT2
00336 ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode);
00337
00346 #define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i])
00347
00356 #define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i])
00357
00366 #define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i])
00367
00378 #define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c))
00379
00390 #define UCPTRIE_SMALL_GET(trie, dataAccess, c) \
00391 dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c))
00392
00406 #define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) { \
00407 (c) = *(src)++; \
00408 int32_t __index; \
00409 if (!U16_IS_SURROGATE(c)) { \
00410 __index = _UCPTRIE_FAST_INDEX(trie, c); \
00411 } else { \
00412 uint16_t __c2; \
00413 if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \
00414 ++(src); \
00415 (c) = U16_GET_SUPPLEMENTARY((c), __c2); \
00416 __index = _UCPTRIE_SMALL_INDEX(trie, c); \
00417 } else { \
00418 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00419 } \
00420 } \
00421 (result) = dataAccess(trie, __index); \
00422 }
00423
00437 #define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) { \
00438 (c) = *--(src); \
00439 int32_t __index; \
00440 if (!U16_IS_SURROGATE(c)) { \
00441 __index = _UCPTRIE_FAST_INDEX(trie, c); \
00442 } else { \
00443 uint16_t __c2; \
00444 if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \
00445 --(src); \
00446 (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \
00447 __index = _UCPTRIE_SMALL_INDEX(trie, c); \
00448 } else { \
00449 __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00450 } \
00451 } \
00452 (result) = dataAccess(trie, __index); \
00453 }
00454
00471 #define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) { \
00472 int32_t __lead = (uint8_t)*(src)++; \
00473 if (!U8_IS_SINGLE(__lead)) { \
00474 uint8_t __t1, __t2, __t3; \
00475 if ((src) != (limit) && \
00476 (__lead >= 0xe0 ? \
00477 __lead < 0xf0 ? \
00478 U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \
00479 ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \
00480 (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \
00481 : \
00482 (__lead -= 0xf0) <= 4 && \
00483 U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \
00484 (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \
00485 (__t2 = *(src) - 0x80) <= 0x3f && \
00486 ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \
00487 (__lead = __lead >= (trie)->shifted12HighStart ? \
00488 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
00489 ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \
00490 : \
00491 __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \
00492 (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \
00493 ++(src); \
00494 } else { \
00495 __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
00496 } \
00497 } \
00498 (result) = dataAccess(trie, __lead); \
00499 }
00500
00517 #define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) { \
00518 int32_t __index = (uint8_t)*--(src); \
00519 if (!U8_IS_SINGLE(__index)) { \
00520 __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \
00521 (const uint8_t *)(src)); \
00522 (src) -= __index & 7; \
00523 __index >>= 3; \
00524 } \
00525 (result) = dataAccess(trie, __index); \
00526 }
00527
00537 #define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c)
00538
00550 #define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c))
00551
00562 #define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c))
00563
00564
00565
00566 #ifndef U_IN_DOXYGEN
00567
00573 enum {
00575 UCPTRIE_FAST_SHIFT = 6,
00576
00578 UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT,
00579
00581 UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1,
00582
00584 UCPTRIE_SMALL_MAX = 0xfff,
00585
00591 UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1,
00597 UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2
00598 };
00599
00600
00601
00602
00604 U_INTERNAL int32_t U_EXPORT2
00605 ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c);
00606
00608 U_INTERNAL int32_t U_EXPORT2
00609 ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3);
00610
00616 U_INTERNAL int32_t U_EXPORT2
00617 ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
00618 const uint8_t *start, const uint8_t *src);
00619
00621 #define _UCPTRIE_FAST_INDEX(trie, c) \
00622 ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK))
00623
00625 #define _UCPTRIE_SMALL_INDEX(trie, c) \
00626 ((c) >= (trie)->highStart ? \
00627 (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
00628 ucptrie_internalSmallIndex(trie, c))
00629
00635 #define _UCPTRIE_CP_INDEX(trie, fastMax, c) \
00636 ((uint32_t)(c) <= (uint32_t)(fastMax) ? \
00637 _UCPTRIE_FAST_INDEX(trie, c) : \
00638 (uint32_t)(c) <= 0x10ffff ? \
00639 _UCPTRIE_SMALL_INDEX(trie, c) : \
00640 (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET)
00641
00642 U_CDECL_END
00643
00644 #endif // U_IN_DOXYGEN
00645 #endif // U_HIDE_DRAFT_API
00646 #endif