1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others. 2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html 3*0e209d39SAndroid Build Coastguard Worker /* 4*0e209d39SAndroid Build Coastguard Worker ******************************************************************************* 5*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 2010-2012, International Business Machines 6*0e209d39SAndroid Build Coastguard Worker * Corporation and others. All Rights Reserved. 7*0e209d39SAndroid Build Coastguard Worker ******************************************************************************* 8*0e209d39SAndroid Build Coastguard Worker * file name: bytestrie.h 9*0e209d39SAndroid Build Coastguard Worker * encoding: UTF-8 10*0e209d39SAndroid Build Coastguard Worker * tab size: 8 (not used) 11*0e209d39SAndroid Build Coastguard Worker * indentation:4 12*0e209d39SAndroid Build Coastguard Worker * 13*0e209d39SAndroid Build Coastguard Worker * created on: 2010sep25 14*0e209d39SAndroid Build Coastguard Worker * created by: Markus W. Scherer 15*0e209d39SAndroid Build Coastguard Worker */ 16*0e209d39SAndroid Build Coastguard Worker 17*0e209d39SAndroid Build Coastguard Worker #ifndef __BYTESTRIE_H__ 18*0e209d39SAndroid Build Coastguard Worker #define __BYTESTRIE_H__ 19*0e209d39SAndroid Build Coastguard Worker 20*0e209d39SAndroid Build Coastguard Worker /** 21*0e209d39SAndroid Build Coastguard Worker * \file 22*0e209d39SAndroid Build Coastguard Worker * \brief C++ API: Trie for mapping byte sequences to integer values. 23*0e209d39SAndroid Build Coastguard Worker */ 24*0e209d39SAndroid Build Coastguard Worker 25*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h" 26*0e209d39SAndroid Build Coastguard Worker 27*0e209d39SAndroid Build Coastguard Worker #if U_SHOW_CPLUSPLUS_API 28*0e209d39SAndroid Build Coastguard Worker 29*0e209d39SAndroid Build Coastguard Worker #include "unicode/stringpiece.h" 30*0e209d39SAndroid Build Coastguard Worker #include "unicode/uobject.h" 31*0e209d39SAndroid Build Coastguard Worker #include "unicode/ustringtrie.h" 32*0e209d39SAndroid Build Coastguard Worker 33*0e209d39SAndroid Build Coastguard Worker class BytesTrieTest; 34*0e209d39SAndroid Build Coastguard Worker 35*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN 36*0e209d39SAndroid Build Coastguard Worker 37*0e209d39SAndroid Build Coastguard Worker class ByteSink; 38*0e209d39SAndroid Build Coastguard Worker class BytesTrieBuilder; 39*0e209d39SAndroid Build Coastguard Worker class CharString; 40*0e209d39SAndroid Build Coastguard Worker class UVector32; 41*0e209d39SAndroid Build Coastguard Worker 42*0e209d39SAndroid Build Coastguard Worker /** 43*0e209d39SAndroid Build Coastguard Worker * Light-weight, non-const reader class for a BytesTrie. 44*0e209d39SAndroid Build Coastguard Worker * Traverses a byte-serialized data structure with minimal state, 45*0e209d39SAndroid Build Coastguard Worker * for mapping byte sequences to non-negative integer values. 46*0e209d39SAndroid Build Coastguard Worker * 47*0e209d39SAndroid Build Coastguard Worker * This class owns the serialized trie data only if it was constructed by 48*0e209d39SAndroid Build Coastguard Worker * the builder's build() method. 49*0e209d39SAndroid Build Coastguard Worker * The public constructor and the copy constructor only alias the data (only copy the pointer). 50*0e209d39SAndroid Build Coastguard Worker * There is no assignment operator. 51*0e209d39SAndroid Build Coastguard Worker * 52*0e209d39SAndroid Build Coastguard Worker * This class is not intended for public subclassing. 53*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 54*0e209d39SAndroid Build Coastguard Worker */ 55*0e209d39SAndroid Build Coastguard Worker class U_COMMON_API BytesTrie : public UMemory { 56*0e209d39SAndroid Build Coastguard Worker public: 57*0e209d39SAndroid Build Coastguard Worker /** 58*0e209d39SAndroid Build Coastguard Worker * Constructs a BytesTrie reader instance. 59*0e209d39SAndroid Build Coastguard Worker * 60*0e209d39SAndroid Build Coastguard Worker * The trieBytes must contain a copy of a byte sequence from the BytesTrieBuilder, 61*0e209d39SAndroid Build Coastguard Worker * starting with the first byte of that sequence. 62*0e209d39SAndroid Build Coastguard Worker * The BytesTrie object will not read more bytes than 63*0e209d39SAndroid Build Coastguard Worker * the BytesTrieBuilder generated in the corresponding build() call. 64*0e209d39SAndroid Build Coastguard Worker * 65*0e209d39SAndroid Build Coastguard Worker * The array is not copied/cloned and must not be modified while 66*0e209d39SAndroid Build Coastguard Worker * the BytesTrie object is in use. 67*0e209d39SAndroid Build Coastguard Worker * 68*0e209d39SAndroid Build Coastguard Worker * @param trieBytes The byte array that contains the serialized trie. 69*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 70*0e209d39SAndroid Build Coastguard Worker */ BytesTrie(const void * trieBytes)71*0e209d39SAndroid Build Coastguard Worker BytesTrie(const void *trieBytes) 72*0e209d39SAndroid Build Coastguard Worker : ownedArray_(nullptr), bytes_(static_cast<const uint8_t *>(trieBytes)), 73*0e209d39SAndroid Build Coastguard Worker pos_(bytes_), remainingMatchLength_(-1) {} 74*0e209d39SAndroid Build Coastguard Worker 75*0e209d39SAndroid Build Coastguard Worker /** 76*0e209d39SAndroid Build Coastguard Worker * Destructor. 77*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 78*0e209d39SAndroid Build Coastguard Worker */ 79*0e209d39SAndroid Build Coastguard Worker ~BytesTrie(); 80*0e209d39SAndroid Build Coastguard Worker 81*0e209d39SAndroid Build Coastguard Worker /** 82*0e209d39SAndroid Build Coastguard Worker * Copy constructor, copies the other trie reader object and its state, 83*0e209d39SAndroid Build Coastguard Worker * but not the byte array which will be shared. (Shallow copy.) 84*0e209d39SAndroid Build Coastguard Worker * @param other Another BytesTrie object. 85*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 86*0e209d39SAndroid Build Coastguard Worker */ BytesTrie(const BytesTrie & other)87*0e209d39SAndroid Build Coastguard Worker BytesTrie(const BytesTrie &other) 88*0e209d39SAndroid Build Coastguard Worker : ownedArray_(nullptr), bytes_(other.bytes_), 89*0e209d39SAndroid Build Coastguard Worker pos_(other.pos_), remainingMatchLength_(other.remainingMatchLength_) {} 90*0e209d39SAndroid Build Coastguard Worker 91*0e209d39SAndroid Build Coastguard Worker /** 92*0e209d39SAndroid Build Coastguard Worker * Resets this trie to its initial state. 93*0e209d39SAndroid Build Coastguard Worker * @return *this 94*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 95*0e209d39SAndroid Build Coastguard Worker */ reset()96*0e209d39SAndroid Build Coastguard Worker BytesTrie &reset() { 97*0e209d39SAndroid Build Coastguard Worker pos_=bytes_; 98*0e209d39SAndroid Build Coastguard Worker remainingMatchLength_=-1; 99*0e209d39SAndroid Build Coastguard Worker return *this; 100*0e209d39SAndroid Build Coastguard Worker } 101*0e209d39SAndroid Build Coastguard Worker 102*0e209d39SAndroid Build Coastguard Worker /** 103*0e209d39SAndroid Build Coastguard Worker * Returns the state of this trie as a 64-bit integer. 104*0e209d39SAndroid Build Coastguard Worker * The state value is never 0. 105*0e209d39SAndroid Build Coastguard Worker * 106*0e209d39SAndroid Build Coastguard Worker * @return opaque state value 107*0e209d39SAndroid Build Coastguard Worker * @see resetToState64 108*0e209d39SAndroid Build Coastguard Worker * @stable ICU 65 109*0e209d39SAndroid Build Coastguard Worker */ getState64()110*0e209d39SAndroid Build Coastguard Worker uint64_t getState64() const { 111*0e209d39SAndroid Build Coastguard Worker return (static_cast<uint64_t>(remainingMatchLength_ + 2) << kState64RemainingShift) | 112*0e209d39SAndroid Build Coastguard Worker (uint64_t)(pos_ - bytes_); 113*0e209d39SAndroid Build Coastguard Worker } 114*0e209d39SAndroid Build Coastguard Worker 115*0e209d39SAndroid Build Coastguard Worker /** 116*0e209d39SAndroid Build Coastguard Worker * Resets this trie to the saved state. 117*0e209d39SAndroid Build Coastguard Worker * Unlike resetToState(State), the 64-bit state value 118*0e209d39SAndroid Build Coastguard Worker * must be from getState64() from the same trie object or 119*0e209d39SAndroid Build Coastguard Worker * from one initialized the exact same way. 120*0e209d39SAndroid Build Coastguard Worker * Because of no validation, this method is faster. 121*0e209d39SAndroid Build Coastguard Worker * 122*0e209d39SAndroid Build Coastguard Worker * @param state The opaque trie state value from getState64(). 123*0e209d39SAndroid Build Coastguard Worker * @return *this 124*0e209d39SAndroid Build Coastguard Worker * @see getState64 125*0e209d39SAndroid Build Coastguard Worker * @see resetToState 126*0e209d39SAndroid Build Coastguard Worker * @see reset 127*0e209d39SAndroid Build Coastguard Worker * @stable ICU 65 128*0e209d39SAndroid Build Coastguard Worker */ resetToState64(uint64_t state)129*0e209d39SAndroid Build Coastguard Worker BytesTrie &resetToState64(uint64_t state) { 130*0e209d39SAndroid Build Coastguard Worker remainingMatchLength_ = static_cast<int32_t>(state >> kState64RemainingShift) - 2; 131*0e209d39SAndroid Build Coastguard Worker pos_ = bytes_ + (state & kState64PosMask); 132*0e209d39SAndroid Build Coastguard Worker return *this; 133*0e209d39SAndroid Build Coastguard Worker } 134*0e209d39SAndroid Build Coastguard Worker 135*0e209d39SAndroid Build Coastguard Worker /** 136*0e209d39SAndroid Build Coastguard Worker * BytesTrie state object, for saving a trie's current state 137*0e209d39SAndroid Build Coastguard Worker * and resetting the trie back to this state later. 138*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 139*0e209d39SAndroid Build Coastguard Worker */ 140*0e209d39SAndroid Build Coastguard Worker class State : public UMemory { 141*0e209d39SAndroid Build Coastguard Worker public: 142*0e209d39SAndroid Build Coastguard Worker /** 143*0e209d39SAndroid Build Coastguard Worker * Constructs an empty State. 144*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 145*0e209d39SAndroid Build Coastguard Worker */ State()146*0e209d39SAndroid Build Coastguard Worker State() { bytes=nullptr; } 147*0e209d39SAndroid Build Coastguard Worker private: 148*0e209d39SAndroid Build Coastguard Worker friend class BytesTrie; 149*0e209d39SAndroid Build Coastguard Worker 150*0e209d39SAndroid Build Coastguard Worker const uint8_t *bytes; 151*0e209d39SAndroid Build Coastguard Worker const uint8_t *pos; 152*0e209d39SAndroid Build Coastguard Worker int32_t remainingMatchLength; 153*0e209d39SAndroid Build Coastguard Worker }; 154*0e209d39SAndroid Build Coastguard Worker 155*0e209d39SAndroid Build Coastguard Worker /** 156*0e209d39SAndroid Build Coastguard Worker * Saves the state of this trie. 157*0e209d39SAndroid Build Coastguard Worker * @param state The State object to hold the trie's state. 158*0e209d39SAndroid Build Coastguard Worker * @return *this 159*0e209d39SAndroid Build Coastguard Worker * @see resetToState 160*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 161*0e209d39SAndroid Build Coastguard Worker */ saveState(State & state)162*0e209d39SAndroid Build Coastguard Worker const BytesTrie &saveState(State &state) const { 163*0e209d39SAndroid Build Coastguard Worker state.bytes=bytes_; 164*0e209d39SAndroid Build Coastguard Worker state.pos=pos_; 165*0e209d39SAndroid Build Coastguard Worker state.remainingMatchLength=remainingMatchLength_; 166*0e209d39SAndroid Build Coastguard Worker return *this; 167*0e209d39SAndroid Build Coastguard Worker } 168*0e209d39SAndroid Build Coastguard Worker 169*0e209d39SAndroid Build Coastguard Worker /** 170*0e209d39SAndroid Build Coastguard Worker * Resets this trie to the saved state. 171*0e209d39SAndroid Build Coastguard Worker * If the state object contains no state, or the state of a different trie, 172*0e209d39SAndroid Build Coastguard Worker * then this trie remains unchanged. 173*0e209d39SAndroid Build Coastguard Worker * @param state The State object which holds a saved trie state. 174*0e209d39SAndroid Build Coastguard Worker * @return *this 175*0e209d39SAndroid Build Coastguard Worker * @see saveState 176*0e209d39SAndroid Build Coastguard Worker * @see reset 177*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 178*0e209d39SAndroid Build Coastguard Worker */ resetToState(const State & state)179*0e209d39SAndroid Build Coastguard Worker BytesTrie &resetToState(const State &state) { 180*0e209d39SAndroid Build Coastguard Worker if(bytes_==state.bytes && bytes_!=nullptr) { 181*0e209d39SAndroid Build Coastguard Worker pos_=state.pos; 182*0e209d39SAndroid Build Coastguard Worker remainingMatchLength_=state.remainingMatchLength; 183*0e209d39SAndroid Build Coastguard Worker } 184*0e209d39SAndroid Build Coastguard Worker return *this; 185*0e209d39SAndroid Build Coastguard Worker } 186*0e209d39SAndroid Build Coastguard Worker 187*0e209d39SAndroid Build Coastguard Worker /** 188*0e209d39SAndroid Build Coastguard Worker * Determines whether the byte sequence so far matches, whether it has a value, 189*0e209d39SAndroid Build Coastguard Worker * and whether another input byte can continue a matching byte sequence. 190*0e209d39SAndroid Build Coastguard Worker * @return The match/value Result. 191*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 192*0e209d39SAndroid Build Coastguard Worker */ 193*0e209d39SAndroid Build Coastguard Worker UStringTrieResult current() const; 194*0e209d39SAndroid Build Coastguard Worker 195*0e209d39SAndroid Build Coastguard Worker /** 196*0e209d39SAndroid Build Coastguard Worker * Traverses the trie from the initial state for this input byte. 197*0e209d39SAndroid Build Coastguard Worker * Equivalent to reset().next(inByte). 198*0e209d39SAndroid Build Coastguard Worker * @param inByte Input byte value. Values -0x100..-1 are treated like 0..0xff. 199*0e209d39SAndroid Build Coastguard Worker * Values below -0x100 and above 0xff will never match. 200*0e209d39SAndroid Build Coastguard Worker * @return The match/value Result. 201*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 202*0e209d39SAndroid Build Coastguard Worker */ first(int32_t inByte)203*0e209d39SAndroid Build Coastguard Worker inline UStringTrieResult first(int32_t inByte) { 204*0e209d39SAndroid Build Coastguard Worker remainingMatchLength_=-1; 205*0e209d39SAndroid Build Coastguard Worker if(inByte<0) { 206*0e209d39SAndroid Build Coastguard Worker inByte+=0x100; 207*0e209d39SAndroid Build Coastguard Worker } 208*0e209d39SAndroid Build Coastguard Worker return nextImpl(bytes_, inByte); 209*0e209d39SAndroid Build Coastguard Worker } 210*0e209d39SAndroid Build Coastguard Worker 211*0e209d39SAndroid Build Coastguard Worker /** 212*0e209d39SAndroid Build Coastguard Worker * Traverses the trie from the current state for this input byte. 213*0e209d39SAndroid Build Coastguard Worker * @param inByte Input byte value. Values -0x100..-1 are treated like 0..0xff. 214*0e209d39SAndroid Build Coastguard Worker * Values below -0x100 and above 0xff will never match. 215*0e209d39SAndroid Build Coastguard Worker * @return The match/value Result. 216*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 217*0e209d39SAndroid Build Coastguard Worker */ 218*0e209d39SAndroid Build Coastguard Worker UStringTrieResult next(int32_t inByte); 219*0e209d39SAndroid Build Coastguard Worker 220*0e209d39SAndroid Build Coastguard Worker /** 221*0e209d39SAndroid Build Coastguard Worker * Traverses the trie from the current state for this byte sequence. 222*0e209d39SAndroid Build Coastguard Worker * Equivalent to 223*0e209d39SAndroid Build Coastguard Worker * \code 224*0e209d39SAndroid Build Coastguard Worker * Result result=current(); 225*0e209d39SAndroid Build Coastguard Worker * for(each c in s) 226*0e209d39SAndroid Build Coastguard Worker * if(!USTRINGTRIE_HAS_NEXT(result)) return USTRINGTRIE_NO_MATCH; 227*0e209d39SAndroid Build Coastguard Worker * result=next(c); 228*0e209d39SAndroid Build Coastguard Worker * return result; 229*0e209d39SAndroid Build Coastguard Worker * \endcode 230*0e209d39SAndroid Build Coastguard Worker * @param s A string or byte sequence. Can be nullptr if length is 0. 231*0e209d39SAndroid Build Coastguard Worker * @param length The length of the byte sequence. Can be -1 if NUL-terminated. 232*0e209d39SAndroid Build Coastguard Worker * @return The match/value Result. 233*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 234*0e209d39SAndroid Build Coastguard Worker */ 235*0e209d39SAndroid Build Coastguard Worker UStringTrieResult next(const char *s, int32_t length); 236*0e209d39SAndroid Build Coastguard Worker 237*0e209d39SAndroid Build Coastguard Worker /** 238*0e209d39SAndroid Build Coastguard Worker * Returns a matching byte sequence's value if called immediately after 239*0e209d39SAndroid Build Coastguard Worker * current()/first()/next() returned USTRINGTRIE_INTERMEDIATE_VALUE or USTRINGTRIE_FINAL_VALUE. 240*0e209d39SAndroid Build Coastguard Worker * getValue() can be called multiple times. 241*0e209d39SAndroid Build Coastguard Worker * 242*0e209d39SAndroid Build Coastguard Worker * Do not call getValue() after USTRINGTRIE_NO_MATCH or USTRINGTRIE_NO_VALUE! 243*0e209d39SAndroid Build Coastguard Worker * @return The value for the byte sequence so far. 244*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 245*0e209d39SAndroid Build Coastguard Worker */ getValue()246*0e209d39SAndroid Build Coastguard Worker inline int32_t getValue() const { 247*0e209d39SAndroid Build Coastguard Worker const uint8_t *pos=pos_; 248*0e209d39SAndroid Build Coastguard Worker int32_t leadByte=*pos++; 249*0e209d39SAndroid Build Coastguard Worker // U_ASSERT(leadByte>=kMinValueLead); 250*0e209d39SAndroid Build Coastguard Worker return readValue(pos, leadByte>>1); 251*0e209d39SAndroid Build Coastguard Worker } 252*0e209d39SAndroid Build Coastguard Worker 253*0e209d39SAndroid Build Coastguard Worker /** 254*0e209d39SAndroid Build Coastguard Worker * Determines whether all byte sequences reachable from the current state 255*0e209d39SAndroid Build Coastguard Worker * map to the same value. 256*0e209d39SAndroid Build Coastguard Worker * @param uniqueValue Receives the unique value, if this function returns true. 257*0e209d39SAndroid Build Coastguard Worker * (output-only) 258*0e209d39SAndroid Build Coastguard Worker * @return true if all byte sequences reachable from the current state 259*0e209d39SAndroid Build Coastguard Worker * map to the same value. 260*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 261*0e209d39SAndroid Build Coastguard Worker */ hasUniqueValue(int32_t & uniqueValue)262*0e209d39SAndroid Build Coastguard Worker inline UBool hasUniqueValue(int32_t &uniqueValue) const { 263*0e209d39SAndroid Build Coastguard Worker const uint8_t *pos=pos_; 264*0e209d39SAndroid Build Coastguard Worker // Skip the rest of a pending linear-match node. 265*0e209d39SAndroid Build Coastguard Worker return pos!=nullptr && findUniqueValue(pos+remainingMatchLength_+1, false, uniqueValue); 266*0e209d39SAndroid Build Coastguard Worker } 267*0e209d39SAndroid Build Coastguard Worker 268*0e209d39SAndroid Build Coastguard Worker /** 269*0e209d39SAndroid Build Coastguard Worker * Finds each byte which continues the byte sequence from the current state. 270*0e209d39SAndroid Build Coastguard Worker * That is, each byte b for which it would be next(b)!=USTRINGTRIE_NO_MATCH now. 271*0e209d39SAndroid Build Coastguard Worker * @param out Each next byte is appended to this object. 272*0e209d39SAndroid Build Coastguard Worker * (Only uses the out.Append(s, length) method.) 273*0e209d39SAndroid Build Coastguard Worker * @return the number of bytes which continue the byte sequence from here 274*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 275*0e209d39SAndroid Build Coastguard Worker */ 276*0e209d39SAndroid Build Coastguard Worker int32_t getNextBytes(ByteSink &out) const; 277*0e209d39SAndroid Build Coastguard Worker 278*0e209d39SAndroid Build Coastguard Worker /** 279*0e209d39SAndroid Build Coastguard Worker * Iterator for all of the (byte sequence, value) pairs in a BytesTrie. 280*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 281*0e209d39SAndroid Build Coastguard Worker */ 282*0e209d39SAndroid Build Coastguard Worker class U_COMMON_API Iterator : public UMemory { 283*0e209d39SAndroid Build Coastguard Worker public: 284*0e209d39SAndroid Build Coastguard Worker /** 285*0e209d39SAndroid Build Coastguard Worker * Iterates from the root of a byte-serialized BytesTrie. 286*0e209d39SAndroid Build Coastguard Worker * @param trieBytes The trie bytes. 287*0e209d39SAndroid Build Coastguard Worker * @param maxStringLength If 0, the iterator returns full strings/byte sequences. 288*0e209d39SAndroid Build Coastguard Worker * Otherwise, the iterator returns strings with this maximum length. 289*0e209d39SAndroid Build Coastguard Worker * @param errorCode Standard ICU error code. Its input value must 290*0e209d39SAndroid Build Coastguard Worker * pass the U_SUCCESS() test, or else the function returns 291*0e209d39SAndroid Build Coastguard Worker * immediately. Check for U_FAILURE() on output or use with 292*0e209d39SAndroid Build Coastguard Worker * function chaining. (See User Guide for details.) 293*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 294*0e209d39SAndroid Build Coastguard Worker */ 295*0e209d39SAndroid Build Coastguard Worker Iterator(const void *trieBytes, int32_t maxStringLength, UErrorCode &errorCode); 296*0e209d39SAndroid Build Coastguard Worker 297*0e209d39SAndroid Build Coastguard Worker /** 298*0e209d39SAndroid Build Coastguard Worker * Iterates from the current state of the specified BytesTrie. 299*0e209d39SAndroid Build Coastguard Worker * @param trie The trie whose state will be copied for iteration. 300*0e209d39SAndroid Build Coastguard Worker * @param maxStringLength If 0, the iterator returns full strings/byte sequences. 301*0e209d39SAndroid Build Coastguard Worker * Otherwise, the iterator returns strings with this maximum length. 302*0e209d39SAndroid Build Coastguard Worker * @param errorCode Standard ICU error code. Its input value must 303*0e209d39SAndroid Build Coastguard Worker * pass the U_SUCCESS() test, or else the function returns 304*0e209d39SAndroid Build Coastguard Worker * immediately. Check for U_FAILURE() on output or use with 305*0e209d39SAndroid Build Coastguard Worker * function chaining. (See User Guide for details.) 306*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 307*0e209d39SAndroid Build Coastguard Worker */ 308*0e209d39SAndroid Build Coastguard Worker Iterator(const BytesTrie &trie, int32_t maxStringLength, UErrorCode &errorCode); 309*0e209d39SAndroid Build Coastguard Worker 310*0e209d39SAndroid Build Coastguard Worker /** 311*0e209d39SAndroid Build Coastguard Worker * Destructor. 312*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 313*0e209d39SAndroid Build Coastguard Worker */ 314*0e209d39SAndroid Build Coastguard Worker ~Iterator(); 315*0e209d39SAndroid Build Coastguard Worker 316*0e209d39SAndroid Build Coastguard Worker /** 317*0e209d39SAndroid Build Coastguard Worker * Resets this iterator to its initial state. 318*0e209d39SAndroid Build Coastguard Worker * @return *this 319*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 320*0e209d39SAndroid Build Coastguard Worker */ 321*0e209d39SAndroid Build Coastguard Worker Iterator &reset(); 322*0e209d39SAndroid Build Coastguard Worker 323*0e209d39SAndroid Build Coastguard Worker /** 324*0e209d39SAndroid Build Coastguard Worker * @return true if there are more elements. 325*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 326*0e209d39SAndroid Build Coastguard Worker */ 327*0e209d39SAndroid Build Coastguard Worker UBool hasNext() const; 328*0e209d39SAndroid Build Coastguard Worker 329*0e209d39SAndroid Build Coastguard Worker /** 330*0e209d39SAndroid Build Coastguard Worker * Finds the next (byte sequence, value) pair if there is one. 331*0e209d39SAndroid Build Coastguard Worker * 332*0e209d39SAndroid Build Coastguard Worker * If the byte sequence is truncated to the maximum length and does not 333*0e209d39SAndroid Build Coastguard Worker * have a real value, then the value is set to -1. 334*0e209d39SAndroid Build Coastguard Worker * In this case, this "not a real value" is indistinguishable from 335*0e209d39SAndroid Build Coastguard Worker * a real value of -1. 336*0e209d39SAndroid Build Coastguard Worker * @param errorCode Standard ICU error code. Its input value must 337*0e209d39SAndroid Build Coastguard Worker * pass the U_SUCCESS() test, or else the function returns 338*0e209d39SAndroid Build Coastguard Worker * immediately. Check for U_FAILURE() on output or use with 339*0e209d39SAndroid Build Coastguard Worker * function chaining. (See User Guide for details.) 340*0e209d39SAndroid Build Coastguard Worker * @return true if there is another element. 341*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 342*0e209d39SAndroid Build Coastguard Worker */ 343*0e209d39SAndroid Build Coastguard Worker UBool next(UErrorCode &errorCode); 344*0e209d39SAndroid Build Coastguard Worker 345*0e209d39SAndroid Build Coastguard Worker /** 346*0e209d39SAndroid Build Coastguard Worker * @return The NUL-terminated byte sequence for the last successful next(). 347*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 348*0e209d39SAndroid Build Coastguard Worker */ 349*0e209d39SAndroid Build Coastguard Worker StringPiece getString() const; 350*0e209d39SAndroid Build Coastguard Worker /** 351*0e209d39SAndroid Build Coastguard Worker * @return The value for the last successful next(). 352*0e209d39SAndroid Build Coastguard Worker * @stable ICU 4.8 353*0e209d39SAndroid Build Coastguard Worker */ getValue()354*0e209d39SAndroid Build Coastguard Worker int32_t getValue() const { return value_; } 355*0e209d39SAndroid Build Coastguard Worker 356*0e209d39SAndroid Build Coastguard Worker private: 357*0e209d39SAndroid Build Coastguard Worker UBool truncateAndStop(); 358*0e209d39SAndroid Build Coastguard Worker 359*0e209d39SAndroid Build Coastguard Worker const uint8_t *branchNext(const uint8_t *pos, int32_t length, UErrorCode &errorCode); 360*0e209d39SAndroid Build Coastguard Worker 361*0e209d39SAndroid Build Coastguard Worker const uint8_t *bytes_; 362*0e209d39SAndroid Build Coastguard Worker const uint8_t *pos_; 363*0e209d39SAndroid Build Coastguard Worker const uint8_t *initialPos_; 364*0e209d39SAndroid Build Coastguard Worker int32_t remainingMatchLength_; 365*0e209d39SAndroid Build Coastguard Worker int32_t initialRemainingMatchLength_; 366*0e209d39SAndroid Build Coastguard Worker 367*0e209d39SAndroid Build Coastguard Worker CharString *str_; 368*0e209d39SAndroid Build Coastguard Worker int32_t maxLength_; 369*0e209d39SAndroid Build Coastguard Worker int32_t value_; 370*0e209d39SAndroid Build Coastguard Worker 371*0e209d39SAndroid Build Coastguard Worker // The stack stores pairs of integers for backtracking to another 372*0e209d39SAndroid Build Coastguard Worker // outbound edge of a branch node. 373*0e209d39SAndroid Build Coastguard Worker // The first integer is an offset from bytes_. 374*0e209d39SAndroid Build Coastguard Worker // The second integer has the str_->length() from before the node in bits 15..0, 375*0e209d39SAndroid Build Coastguard Worker // and the remaining branch length in bits 24..16. (Bits 31..25 are unused.) 376*0e209d39SAndroid Build Coastguard Worker // (We could store the remaining branch length minus 1 in bits 23..16 and not use bits 31..24, 377*0e209d39SAndroid Build Coastguard Worker // but the code looks more confusing that way.) 378*0e209d39SAndroid Build Coastguard Worker UVector32 *stack_; 379*0e209d39SAndroid Build Coastguard Worker }; 380*0e209d39SAndroid Build Coastguard Worker 381*0e209d39SAndroid Build Coastguard Worker private: 382*0e209d39SAndroid Build Coastguard Worker friend class BytesTrieBuilder; 383*0e209d39SAndroid Build Coastguard Worker friend class ::BytesTrieTest; 384*0e209d39SAndroid Build Coastguard Worker 385*0e209d39SAndroid Build Coastguard Worker /** 386*0e209d39SAndroid Build Coastguard Worker * Constructs a BytesTrie reader instance. 387*0e209d39SAndroid Build Coastguard Worker * Unlike the public constructor which just aliases an array, 388*0e209d39SAndroid Build Coastguard Worker * this constructor adopts the builder's array. 389*0e209d39SAndroid Build Coastguard Worker * This constructor is only called by the builder. 390*0e209d39SAndroid Build Coastguard Worker */ BytesTrie(void * adoptBytes,const void * trieBytes)391*0e209d39SAndroid Build Coastguard Worker BytesTrie(void *adoptBytes, const void *trieBytes) 392*0e209d39SAndroid Build Coastguard Worker : ownedArray_(static_cast<uint8_t *>(adoptBytes)), 393*0e209d39SAndroid Build Coastguard Worker bytes_(static_cast<const uint8_t *>(trieBytes)), 394*0e209d39SAndroid Build Coastguard Worker pos_(bytes_), remainingMatchLength_(-1) {} 395*0e209d39SAndroid Build Coastguard Worker 396*0e209d39SAndroid Build Coastguard Worker // No assignment operator. 397*0e209d39SAndroid Build Coastguard Worker BytesTrie &operator=(const BytesTrie &other) = delete; 398*0e209d39SAndroid Build Coastguard Worker stop()399*0e209d39SAndroid Build Coastguard Worker inline void stop() { 400*0e209d39SAndroid Build Coastguard Worker pos_=nullptr; 401*0e209d39SAndroid Build Coastguard Worker } 402*0e209d39SAndroid Build Coastguard Worker 403*0e209d39SAndroid Build Coastguard Worker // Reads a compact 32-bit integer. 404*0e209d39SAndroid Build Coastguard Worker // pos is already after the leadByte, and the lead byte is already shifted right by 1. 405*0e209d39SAndroid Build Coastguard Worker static int32_t readValue(const uint8_t *pos, int32_t leadByte); skipValue(const uint8_t * pos,int32_t leadByte)406*0e209d39SAndroid Build Coastguard Worker static inline const uint8_t *skipValue(const uint8_t *pos, int32_t leadByte) { 407*0e209d39SAndroid Build Coastguard Worker // U_ASSERT(leadByte>=kMinValueLead); 408*0e209d39SAndroid Build Coastguard Worker if(leadByte>=(kMinTwoByteValueLead<<1)) { 409*0e209d39SAndroid Build Coastguard Worker if(leadByte<(kMinThreeByteValueLead<<1)) { 410*0e209d39SAndroid Build Coastguard Worker ++pos; 411*0e209d39SAndroid Build Coastguard Worker } else if(leadByte<(kFourByteValueLead<<1)) { 412*0e209d39SAndroid Build Coastguard Worker pos+=2; 413*0e209d39SAndroid Build Coastguard Worker } else { 414*0e209d39SAndroid Build Coastguard Worker pos+=3+((leadByte>>1)&1); 415*0e209d39SAndroid Build Coastguard Worker } 416*0e209d39SAndroid Build Coastguard Worker } 417*0e209d39SAndroid Build Coastguard Worker return pos; 418*0e209d39SAndroid Build Coastguard Worker } skipValue(const uint8_t * pos)419*0e209d39SAndroid Build Coastguard Worker static inline const uint8_t *skipValue(const uint8_t *pos) { 420*0e209d39SAndroid Build Coastguard Worker int32_t leadByte=*pos++; 421*0e209d39SAndroid Build Coastguard Worker return skipValue(pos, leadByte); 422*0e209d39SAndroid Build Coastguard Worker } 423*0e209d39SAndroid Build Coastguard Worker 424*0e209d39SAndroid Build Coastguard Worker // Reads a jump delta and jumps. 425*0e209d39SAndroid Build Coastguard Worker static const uint8_t *jumpByDelta(const uint8_t *pos); 426*0e209d39SAndroid Build Coastguard Worker skipDelta(const uint8_t * pos)427*0e209d39SAndroid Build Coastguard Worker static inline const uint8_t *skipDelta(const uint8_t *pos) { 428*0e209d39SAndroid Build Coastguard Worker int32_t delta=*pos++; 429*0e209d39SAndroid Build Coastguard Worker if(delta>=kMinTwoByteDeltaLead) { 430*0e209d39SAndroid Build Coastguard Worker if(delta<kMinThreeByteDeltaLead) { 431*0e209d39SAndroid Build Coastguard Worker ++pos; 432*0e209d39SAndroid Build Coastguard Worker } else if(delta<kFourByteDeltaLead) { 433*0e209d39SAndroid Build Coastguard Worker pos+=2; 434*0e209d39SAndroid Build Coastguard Worker } else { 435*0e209d39SAndroid Build Coastguard Worker pos+=3+(delta&1); 436*0e209d39SAndroid Build Coastguard Worker } 437*0e209d39SAndroid Build Coastguard Worker } 438*0e209d39SAndroid Build Coastguard Worker return pos; 439*0e209d39SAndroid Build Coastguard Worker } 440*0e209d39SAndroid Build Coastguard Worker valueResult(int32_t node)441*0e209d39SAndroid Build Coastguard Worker static inline UStringTrieResult valueResult(int32_t node) { 442*0e209d39SAndroid Build Coastguard Worker return (UStringTrieResult)(USTRINGTRIE_INTERMEDIATE_VALUE-(node&kValueIsFinal)); 443*0e209d39SAndroid Build Coastguard Worker } 444*0e209d39SAndroid Build Coastguard Worker 445*0e209d39SAndroid Build Coastguard Worker // Handles a branch node for both next(byte) and next(string). 446*0e209d39SAndroid Build Coastguard Worker UStringTrieResult branchNext(const uint8_t *pos, int32_t length, int32_t inByte); 447*0e209d39SAndroid Build Coastguard Worker 448*0e209d39SAndroid Build Coastguard Worker // Requires remainingLength_<0. 449*0e209d39SAndroid Build Coastguard Worker UStringTrieResult nextImpl(const uint8_t *pos, int32_t inByte); 450*0e209d39SAndroid Build Coastguard Worker 451*0e209d39SAndroid Build Coastguard Worker // Helper functions for hasUniqueValue(). 452*0e209d39SAndroid Build Coastguard Worker // Recursively finds a unique value (or whether there is not a unique one) 453*0e209d39SAndroid Build Coastguard Worker // from a branch. 454*0e209d39SAndroid Build Coastguard Worker static const uint8_t *findUniqueValueFromBranch(const uint8_t *pos, int32_t length, 455*0e209d39SAndroid Build Coastguard Worker UBool haveUniqueValue, int32_t &uniqueValue); 456*0e209d39SAndroid Build Coastguard Worker // Recursively finds a unique value (or whether there is not a unique one) 457*0e209d39SAndroid Build Coastguard Worker // starting from a position on a node lead byte. 458*0e209d39SAndroid Build Coastguard Worker static UBool findUniqueValue(const uint8_t *pos, UBool haveUniqueValue, int32_t &uniqueValue); 459*0e209d39SAndroid Build Coastguard Worker 460*0e209d39SAndroid Build Coastguard Worker // Helper functions for getNextBytes(). 461*0e209d39SAndroid Build Coastguard Worker // getNextBytes() when pos is on a branch node. 462*0e209d39SAndroid Build Coastguard Worker static void getNextBranchBytes(const uint8_t *pos, int32_t length, ByteSink &out); 463*0e209d39SAndroid Build Coastguard Worker static void append(ByteSink &out, int c); 464*0e209d39SAndroid Build Coastguard Worker 465*0e209d39SAndroid Build Coastguard Worker // BytesTrie data structure 466*0e209d39SAndroid Build Coastguard Worker // 467*0e209d39SAndroid Build Coastguard Worker // The trie consists of a series of byte-serialized nodes for incremental 468*0e209d39SAndroid Build Coastguard Worker // string/byte sequence matching. The root node is at the beginning of the trie data. 469*0e209d39SAndroid Build Coastguard Worker // 470*0e209d39SAndroid Build Coastguard Worker // Types of nodes are distinguished by their node lead byte ranges. 471*0e209d39SAndroid Build Coastguard Worker // After each node, except a final-value node, another node follows to 472*0e209d39SAndroid Build Coastguard Worker // encode match values or continue matching further bytes. 473*0e209d39SAndroid Build Coastguard Worker // 474*0e209d39SAndroid Build Coastguard Worker // Node types: 475*0e209d39SAndroid Build Coastguard Worker // - Value node: Stores a 32-bit integer in a compact, variable-length format. 476*0e209d39SAndroid Build Coastguard Worker // The value is for the string/byte sequence so far. 477*0e209d39SAndroid Build Coastguard Worker // One node bit indicates whether the value is final or whether 478*0e209d39SAndroid Build Coastguard Worker // matching continues with the next node. 479*0e209d39SAndroid Build Coastguard Worker // - Linear-match node: Matches a number of bytes. 480*0e209d39SAndroid Build Coastguard Worker // - Branch node: Branches to other nodes according to the current input byte. 481*0e209d39SAndroid Build Coastguard Worker // The node byte is the length of the branch (number of bytes to select from) 482*0e209d39SAndroid Build Coastguard Worker // minus 1. It is followed by a sub-node: 483*0e209d39SAndroid Build Coastguard Worker // - If the length is at most kMaxBranchLinearSubNodeLength, then 484*0e209d39SAndroid Build Coastguard Worker // there are length-1 (key, value) pairs and then one more comparison byte. 485*0e209d39SAndroid Build Coastguard Worker // If one of the key bytes matches, then the value is either a final value for 486*0e209d39SAndroid Build Coastguard Worker // the string/byte sequence so far, or a "jump" delta to the next node. 487*0e209d39SAndroid Build Coastguard Worker // If the last byte matches, then matching continues with the next node. 488*0e209d39SAndroid Build Coastguard Worker // (Values have the same encoding as value nodes.) 489*0e209d39SAndroid Build Coastguard Worker // - If the length is greater than kMaxBranchLinearSubNodeLength, then 490*0e209d39SAndroid Build Coastguard Worker // there is one byte and one "jump" delta. 491*0e209d39SAndroid Build Coastguard Worker // If the input byte is less than the sub-node byte, then "jump" by delta to 492*0e209d39SAndroid Build Coastguard Worker // the next sub-node which will have a length of length/2. 493*0e209d39SAndroid Build Coastguard Worker // (The delta has its own compact encoding.) 494*0e209d39SAndroid Build Coastguard Worker // Otherwise, skip the "jump" delta to the next sub-node 495*0e209d39SAndroid Build Coastguard Worker // which will have a length of length-length/2. 496*0e209d39SAndroid Build Coastguard Worker 497*0e209d39SAndroid Build Coastguard Worker // Node lead byte values. 498*0e209d39SAndroid Build Coastguard Worker 499*0e209d39SAndroid Build Coastguard Worker // 00..0f: Branch node. If node!=0 then the length is node+1, otherwise 500*0e209d39SAndroid Build Coastguard Worker // the length is one more than the next byte. 501*0e209d39SAndroid Build Coastguard Worker 502*0e209d39SAndroid Build Coastguard Worker // For a branch sub-node with at most this many entries, we drop down 503*0e209d39SAndroid Build Coastguard Worker // to a linear search. 504*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxBranchLinearSubNodeLength=5; 505*0e209d39SAndroid Build Coastguard Worker 506*0e209d39SAndroid Build Coastguard Worker // 10..1f: Linear-match node, match 1..16 bytes and continue reading the next node. 507*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinLinearMatch=0x10; 508*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxLinearMatchLength=0x10; 509*0e209d39SAndroid Build Coastguard Worker 510*0e209d39SAndroid Build Coastguard Worker // 20..ff: Variable-length value node. 511*0e209d39SAndroid Build Coastguard Worker // If odd, the value is final. (Otherwise, intermediate value or jump delta.) 512*0e209d39SAndroid Build Coastguard Worker // Then shift-right by 1 bit. 513*0e209d39SAndroid Build Coastguard Worker // The remaining lead byte value indicates the number of following bytes (0..4) 514*0e209d39SAndroid Build Coastguard Worker // and contains the value's top bits. 515*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinValueLead=kMinLinearMatch+kMaxLinearMatchLength; // 0x20 516*0e209d39SAndroid Build Coastguard Worker // It is a final value if bit 0 is set. 517*0e209d39SAndroid Build Coastguard Worker static const int32_t kValueIsFinal=1; 518*0e209d39SAndroid Build Coastguard Worker 519*0e209d39SAndroid Build Coastguard Worker // Compact value: After testing bit 0, shift right by 1 and then use the following thresholds. 520*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinOneByteValueLead=kMinValueLead/2; // 0x10 521*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxOneByteValue=0x40; // At least 6 bits in the first byte. 522*0e209d39SAndroid Build Coastguard Worker 523*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinTwoByteValueLead=kMinOneByteValueLead+kMaxOneByteValue+1; // 0x51 524*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxTwoByteValue=0x1aff; 525*0e209d39SAndroid Build Coastguard Worker 526*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinThreeByteValueLead=kMinTwoByteValueLead+(kMaxTwoByteValue>>8)+1; // 0x6c 527*0e209d39SAndroid Build Coastguard Worker static const int32_t kFourByteValueLead=0x7e; 528*0e209d39SAndroid Build Coastguard Worker 529*0e209d39SAndroid Build Coastguard Worker // A little more than Unicode code points. (0x11ffff) 530*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxThreeByteValue=((kFourByteValueLead-kMinThreeByteValueLead)<<16)-1; 531*0e209d39SAndroid Build Coastguard Worker 532*0e209d39SAndroid Build Coastguard Worker static const int32_t kFiveByteValueLead=0x7f; 533*0e209d39SAndroid Build Coastguard Worker 534*0e209d39SAndroid Build Coastguard Worker // Compact delta integers. 535*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxOneByteDelta=0xbf; 536*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinTwoByteDeltaLead=kMaxOneByteDelta+1; // 0xc0 537*0e209d39SAndroid Build Coastguard Worker static const int32_t kMinThreeByteDeltaLead=0xf0; 538*0e209d39SAndroid Build Coastguard Worker static const int32_t kFourByteDeltaLead=0xfe; 539*0e209d39SAndroid Build Coastguard Worker static const int32_t kFiveByteDeltaLead=0xff; 540*0e209d39SAndroid Build Coastguard Worker 541*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxTwoByteDelta=((kMinThreeByteDeltaLead-kMinTwoByteDeltaLead)<<8)-1; // 0x2fff 542*0e209d39SAndroid Build Coastguard Worker static const int32_t kMaxThreeByteDelta=((kFourByteDeltaLead-kMinThreeByteDeltaLead)<<16)-1; // 0xdffff 543*0e209d39SAndroid Build Coastguard Worker 544*0e209d39SAndroid Build Coastguard Worker // For getState64(): 545*0e209d39SAndroid Build Coastguard Worker // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2 546*0e209d39SAndroid Build Coastguard Worker // so we need at least 5 bits for that. 547*0e209d39SAndroid Build Coastguard Worker // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength. 548*0e209d39SAndroid Build Coastguard Worker static constexpr int32_t kState64RemainingShift = 59; 549*0e209d39SAndroid Build Coastguard Worker static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1; 550*0e209d39SAndroid Build Coastguard Worker 551*0e209d39SAndroid Build Coastguard Worker uint8_t *ownedArray_; 552*0e209d39SAndroid Build Coastguard Worker 553*0e209d39SAndroid Build Coastguard Worker // Fixed value referencing the BytesTrie bytes. 554*0e209d39SAndroid Build Coastguard Worker const uint8_t *bytes_; 555*0e209d39SAndroid Build Coastguard Worker 556*0e209d39SAndroid Build Coastguard Worker // Iterator variables. 557*0e209d39SAndroid Build Coastguard Worker 558*0e209d39SAndroid Build Coastguard Worker // Pointer to next trie byte to read. nullptr if no more matches. 559*0e209d39SAndroid Build Coastguard Worker const uint8_t *pos_; 560*0e209d39SAndroid Build Coastguard Worker // Remaining length of a linear-match node, minus 1. Negative if not in such a node. 561*0e209d39SAndroid Build Coastguard Worker int32_t remainingMatchLength_; 562*0e209d39SAndroid Build Coastguard Worker }; 563*0e209d39SAndroid Build Coastguard Worker 564*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END 565*0e209d39SAndroid Build Coastguard Worker 566*0e209d39SAndroid Build Coastguard Worker #endif /* U_SHOW_CPLUSPLUS_API */ 567*0e209d39SAndroid Build Coastguard Worker 568*0e209d39SAndroid Build Coastguard Worker #endif // __BYTESTRIE_H__ 569