ICU 65.1  65.1
ucptrie.h
Go to the documentation of this file.
1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 // ucptrie.h (modified from utrie2.h)
5 // created: 2017dec29 Markus W. Scherer
6 
7 #ifndef __UCPTRIE_H__
8 #define __UCPTRIE_H__
9 
10 #include "unicode/utypes.h"
11 
12 #include "unicode/localpointer.h"
13 #include "unicode/ucpmap.h"
14 #include "unicode/utf8.h"
15 
17 
27 #ifndef U_IN_DOXYGEN
28 
29 typedef union UCPTrieData {
31  const void *ptr0;
33  const uint16_t *ptr16;
35  const uint32_t *ptr32;
37  const uint8_t *ptr8;
38 } UCPTrieData;
39 #endif
40 
58 struct UCPTrie {
59 #ifndef U_IN_DOXYGEN
60 
61  const uint16_t *index;
63  UCPTrieData data;
64 
66  int32_t indexLength;
68  int32_t dataLength;
70  UChar32 highStart;
72  uint16_t shifted12HighStart;
73 
75  int8_t type; // UCPTrieType
77  int8_t valueWidth; // UCPTrieValueWidth
78 
80  uint32_t reserved32;
82  uint16_t reserved16;
83 
89  uint16_t index3NullOffset;
95  int32_t dataNullOffset;
97  uint32_t nullValue;
98 
99 #ifdef UCPTRIE_DEBUG
100 
101  const char *name;
102 #endif
103 #endif
104 };
105 #ifndef U_IN_DOXYGEN
106 typedef struct UCPTrie UCPTrie;
107 #endif
108 
135 };
136 #ifndef U_IN_DOXYGEN
137 typedef enum UCPTrieType UCPTrieType;
138 #endif
139 
172 };
173 #ifndef U_IN_DOXYGEN
175 #endif
176 
203 U_CAPI UCPTrie * U_EXPORT2
205  const void *data, int32_t length, int32_t *pActualLength,
206  UErrorCode *pErrorCode);
207 
214 U_CAPI void U_EXPORT2
215 ucptrie_close(UCPTrie *trie);
216 
226 U_CAPI UCPTrieType U_EXPORT2
227 ucptrie_getType(const UCPTrie *trie);
228 
238 U_CAPI UCPTrieValueWidth U_EXPORT2
239 ucptrie_getValueWidth(const UCPTrie *trie);
240 
255 U_CAPI uint32_t U_EXPORT2
256 ucptrie_get(const UCPTrie *trie, UChar32 c);
257 
294 U_CAPI UChar32 U_EXPORT2
295 ucptrie_getRange(const UCPTrie *trie, UChar32 start,
296  UCPMapRangeOption option, uint32_t surrogateValue,
297  UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
298 
314 U_CAPI int32_t U_EXPORT2
315 ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode);
316 
325 #define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i])
326 
335 #define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i])
336 
345 #define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i])
346 
357 #define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c))
358 
369 #define UCPTRIE_SMALL_GET(trie, dataAccess, c) \
370  dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c))
371 
385 #define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
386  (c) = *(src)++; \
387  int32_t __index; \
388  if (!U16_IS_SURROGATE(c)) { \
389  __index = _UCPTRIE_FAST_INDEX(trie, c); \
390  } else { \
391  uint16_t __c2; \
392  if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \
393  ++(src); \
394  (c) = U16_GET_SUPPLEMENTARY((c), __c2); \
395  __index = _UCPTRIE_SMALL_INDEX(trie, c); \
396  } else { \
397  __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
398  } \
399  } \
400  (result) = dataAccess(trie, __index); \
401 } UPRV_BLOCK_MACRO_END
402 
416 #define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
417  (c) = *--(src); \
418  int32_t __index; \
419  if (!U16_IS_SURROGATE(c)) { \
420  __index = _UCPTRIE_FAST_INDEX(trie, c); \
421  } else { \
422  uint16_t __c2; \
423  if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \
424  --(src); \
425  (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \
426  __index = _UCPTRIE_SMALL_INDEX(trie, c); \
427  } else { \
428  __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
429  } \
430  } \
431  (result) = dataAccess(trie, __index); \
432 } UPRV_BLOCK_MACRO_END
433 
450 #define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
451  int32_t __lead = (uint8_t)*(src)++; \
452  if (!U8_IS_SINGLE(__lead)) { \
453  uint8_t __t1, __t2, __t3; \
454  if ((src) != (limit) && \
455  (__lead >= 0xe0 ? \
456  __lead < 0xf0 ? /* U+0800..U+FFFF except surrogates */ \
457  U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \
458  ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \
459  (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \
460  : /* U+10000..U+10FFFF */ \
461  (__lead -= 0xf0) <= 4 && \
462  U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \
463  (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \
464  (__t2 = *(src) - 0x80) <= 0x3f && \
465  ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \
466  (__lead = __lead >= (trie)->shifted12HighStart ? \
467  (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
468  ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \
469  : /* U+0080..U+07FF */ \
470  __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \
471  (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \
472  ++(src); \
473  } else { \
474  __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; /* ill-formed*/ \
475  } \
476  } \
477  (result) = dataAccess(trie, __lead); \
478 } UPRV_BLOCK_MACRO_END
479 
496 #define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
497  int32_t __index = (uint8_t)*--(src); \
498  if (!U8_IS_SINGLE(__index)) { \
499  __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \
500  (const uint8_t *)(src)); \
501  (src) -= __index & 7; \
502  __index >>= 3; \
503  } \
504  (result) = dataAccess(trie, __index); \
505 } UPRV_BLOCK_MACRO_END
506 
516 #define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c)
517 
529 #define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c))
530 
541 #define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c))
542 
543 /* Internal definitions ----------------------------------------------------- */
544 
545 #ifndef U_IN_DOXYGEN
546 
552 enum {
554  UCPTRIE_FAST_SHIFT = 6,
555 
557  UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT,
558 
560  UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1,
561 
563  UCPTRIE_SMALL_MAX = 0xfff,
564 
570  UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1,
576  UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2
577 };
578 
579 /* Internal functions and macros -------------------------------------------- */
580 // Do not conditionalize with #ifndef U_HIDE_INTERNAL_API, needed for public API
581 
583 U_INTERNAL int32_t U_EXPORT2
584 ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c);
585 
587 U_INTERNAL int32_t U_EXPORT2
588 ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3);
589 
595 U_INTERNAL int32_t U_EXPORT2
596 ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
597  const uint8_t *start, const uint8_t *src);
598 
600 #define _UCPTRIE_FAST_INDEX(trie, c) \
601  ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK))
602 
604 #define _UCPTRIE_SMALL_INDEX(trie, c) \
605  ((c) >= (trie)->highStart ? \
606  (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
607  ucptrie_internalSmallIndex(trie, c))
608 
614 #define _UCPTRIE_CP_INDEX(trie, fastMax, c) \
615  ((uint32_t)(c) <= (uint32_t)(fastMax) ? \
616  _UCPTRIE_FAST_INDEX(trie, c) : \
617  (uint32_t)(c) <= 0x10ffff ? \
618  _UCPTRIE_SMALL_INDEX(trie, c) : \
619  (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET)
620 
622 
623 #endif // U_IN_DOXYGEN
624 
625 #if U_SHOW_CPLUSPLUS_API
626 
627 U_NAMESPACE_BEGIN
628 
639 
640 U_NAMESPACE_END
641 
642 #endif // U_SHOW_CPLUSPLUS_API
643 
644 #endif
UCPMapRangeOption
Selectors for how ucpmap_getRange() etc.
Definition: ucpmap.h:42
U_CAPI UCPTrieType ucptrie_getType(const UCPTrie *trie)
Returns the trie type.
U_CAPI UCPTrie * ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth, const void *data, int32_t length, int32_t *pActualLength, UErrorCode *pErrorCode)
Opens a trie from its binary form, stored in 32-bit-aligned memory.
#define U_CAPI
This is used to declare a function as a public ICU C API.
Definition: umachine.h:109
UCPTrieValueWidth
Selectors for the number of bits in a UCPTrie data value.
Definition: ucptrie.h:148
Immutable Unicode code point trie structure.
Definition: ucptrie.h:58
This file defines an abstract map from Unicode code points to integer values.
#define U_INTERNAL
This is used to declare a function as an internal ICU C API.
Definition: umachine.h:119
The trie stores 8 bits per data value.
Definition: ucptrie.h:171
C API: 8-bit Unicode handling macros.
#define U_CDECL_BEGIN
This is used to begin a declaration of a library private ICU C API.
Definition: umachine.h:84
"Smart pointer" class, closes a UCPTrie via ucptrie_close().
U_CAPI uint32_t ucptrie_get(const UCPTrie *trie, UChar32 c)
Returns the value for a code point as stored in the trie, with range checking.
Fast/simple/larger BMP data structure.
Definition: ucptrie.h:129
#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction)
"Smart pointer" definition macro, deletes objects via the closeFunction.
Definition: localpointer.h:562
C++ API: "Smart pointers" for use with and in ICU4C C++ code.
U_CAPI int32_t ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode)
Writes a memory-mappable form of the trie into 32-bit aligned memory.
uint32_t UCPMapValueFilter(const void *context, uint32_t value)
Callback function type: Modifies a map value.
Definition: ucpmap.h:114
The trie stores 32 bits per data value.
Definition: ucptrie.h:165
int32_t UChar32
Define UChar32 as a type for single Unicode code points.
Definition: umachine.h:425
The trie stores 16 bits per data value.
Definition: ucptrie.h:160
U_CAPI UCPTrieValueWidth ucptrie_getValueWidth(const UCPTrie *trie)
Returns the number of bits in a trie data value.
For ucptrie_openFromBinary() to accept any data value width.
Definition: ucptrie.h:154
U_CAPI void ucptrie_close(UCPTrie *trie)
Closes a trie and releases associated memory.
#define U_CDECL_END
This is used to end a declaration of a library private ICU C API.
Definition: umachine.h:85
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:415
For ucptrie_openFromBinary() to accept any type.
Definition: ucptrie.h:124
Basic definitions for ICU, for both C and C++ APIs.
U_CAPI UChar32 ucptrie_getRange(const UCPTrie *trie, UChar32 start, UCPMapRangeOption option, uint32_t surrogateValue, UCPMapValueFilter *filter, const void *context, uint32_t *pValue)
Returns the last code point such that all those from start to there have the same value...
UCPTrieType
Selectors for the type of a UCPTrie.
Definition: ucptrie.h:118
Small/slower BMP data structure.
Definition: ucptrie.h:134