ucharstrieiterator.cpp revision b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2
1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 2010-2011, International Business Machines 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Corporation and others. All Rights Reserved. 5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* file name: ucharstrieiterator.h 7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* encoding: US-ASCII 8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* tab size: 8 (not used) 9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* indentation:4 10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* 11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* created on: 2010nov15 12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* created by: Markus W. Scherer 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*/ 14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/ucharstrie.h" 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/unistr.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uvectr32.h" 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::Iterator(const UChar *trieUChars, int32_t maxStringLength, 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode &errorCode) 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho : uchars_(trieUChars), 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_(uchars_), initialPos_(uchars_), 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho remainingMatchLength_(-1), initialRemainingMatchLength_(-1), 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho skipValue_(FALSE), 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho maxLength_(maxStringLength), value_(0), stack_(NULL) { 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(U_FAILURE(errorCode)) { 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // stack_ is a pointer so that it's easy to turn ucharstrie.h into 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // a public API header for which we would want it to depend only on 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // other public headers. 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Unlike UCharsTrie itself, its Iterator performs memory allocations anyway 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // via the UnicodeString and UVector32 implementations, so this additional 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // cost is minimal. 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_=new UVector32(errorCode); 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(stack_==NULL) { 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errorCode=U_MEMORY_ALLOCATION_ERROR; 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::Iterator(const UCharsTrie &trie, int32_t maxStringLength, 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode &errorCode) 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho : uchars_(trie.uchars_), pos_(trie.pos_), initialPos_(trie.pos_), 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho remainingMatchLength_(trie.remainingMatchLength_), 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho initialRemainingMatchLength_(trie.remainingMatchLength_), 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho skipValue_(FALSE), 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho maxLength_(maxStringLength), value_(0), stack_(NULL) { 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(U_FAILURE(errorCode)) { 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_=new UVector32(errorCode); 55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(U_FAILURE(errorCode)) { 56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(stack_==NULL) { 59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errorCode=U_MEMORY_ALLOCATION_ERROR; 60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length=remainingMatchLength_; // Actual remaining match length minus 1. 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(length>=0) { 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Pending linear-match node, append remaining UChars to str_. 65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++length; 66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(maxLength_>0 && length>maxLength_) { 67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho length=maxLength_; // This will leave remainingMatchLength>=0 as a signal. 68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.append(pos_, length); 70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_+=length; 71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho remainingMatchLength_-=length; 72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::~Iterator() { 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete stack_; 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator & 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::reset() { 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_=initialPos_; 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho remainingMatchLength_=initialRemainingMatchLength_; 83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho skipValue_=FALSE; 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length=remainingMatchLength_+1; // Remaining match length. 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(maxLength_>0 && length>maxLength_) { 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho length=maxLength_; 87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.truncate(length); 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_+=length; 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho remainingMatchLength_-=length; 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->setSize(0); 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return *this; 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::hasNext() const { return pos_!=NULL || !stack_->isEmpty(); } 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::next(UErrorCode &errorCode) { 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(U_FAILURE(errorCode)) { 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *pos=pos_; 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(pos==NULL) { 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(stack_->isEmpty()) { 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Pop the state off the stack and continue with the next outbound edge of 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // the branch node. 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t stackSize=stack_->size(); 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length=stack_->elementAti(stackSize-1); 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=uchars_+stack_->elementAti(stackSize-2); 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->setSize(stackSize-2); 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.truncate(length&0xffff); 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho length=(int32_t)((uint32_t)length>>16); 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(length>1) { 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=branchNext(pos, length, errorCode); 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(pos==NULL) { 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; // Reached a final value. 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.append(*pos++); 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(remainingMatchLength_>=0) { 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We only get here if we started in a pending linear-match node 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // with more than maxLength remaining units. 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return truncateAndStop(); 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(;;) { 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t node=*pos++; 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(node>=kMinValueLead) { 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(skipValue_) { 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=skipNodeValue(pos, node); 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node&=kNodeTypeMask; 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho skipValue_=FALSE; 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Deliver value for the string so far. 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isFinal=(UBool)(node>>15); 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(isFinal) { 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho value_=readValue(pos, node&0x7fff); 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho value_=readNodeValue(pos, node); 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(isFinal || (maxLength_>0 && str_.length()==maxLength_)) { 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_=NULL; 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We cannot skip the value right here because it shares its 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // lead unit with a match node which we have to evaluate 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // next time. 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Instead, keep pos_ on the node lead unit itself. 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_=pos-1; 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho skipValue_=TRUE; 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(maxLength_>0 && str_.length()==maxLength_) { 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return truncateAndStop(); 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(node<kMinLinearMatch) { 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(node==0) { 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node=*pos++; 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=branchNext(pos, node+1, errorCode); 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(pos==NULL) { 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; // Reached a final value. 168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Linear-match node, append length units to str_. 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length=node-kMinLinearMatch+1; 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(maxLength_>0 && str_.length()+length>maxLength_) { 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.append(pos, maxLength_-str_.length()); 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return truncateAndStop(); 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.append(pos, length); 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos+=length; 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Branch node, needs to take the first outbound edge and push state for the rest. 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar * 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUCharsTrie::Iterator::branchNext(const UChar *pos, int32_t length, UErrorCode &errorCode) { 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while(length>kMaxBranchLinearSubNodeLength) { 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++pos; // ignore the comparison unit 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Push state for the greater-or-equal edge. 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->addElement((int32_t)(skipDelta(pos)-uchars_), errorCode); 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->addElement(((length-(length>>1))<<16)|str_.length(), errorCode); 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Follow the less-than edge. 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho length>>=1; 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=jumpByDelta(pos); 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // List of key-value pairs where values are either final values or jump deltas. 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Read the first (key, value) pair. 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar trieUnit=*pos++; 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t node=*pos++; 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isFinal=(UBool)(node>>15); 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t value=readValue(pos, node&=0x7fff); 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos=skipValue(pos, node); 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->addElement((int32_t)(pos-uchars_), errorCode); 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stack_->addElement(((length-1)<<16)|str_.length(), errorCode); 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str_.append(trieUnit); 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(isFinal) { 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos_=NULL; 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho value_=value; 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return pos+value; 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 214