1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ****************************************************************************** 5 * Copyright (C) 2015, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ****************************************************************************** 8 * 9 * File unistrappender.h 10 ****************************************************************************** 11 */ 12 13 #ifndef __UNISTRAPPENDER_H__ 14 #define __UNISTRAPPENDER_H__ 15 16 #include "unicode/unistr.h" 17 #include "unicode/uobject.h" 18 #include "unicode/utf16.h" 19 #include "unicode/utypes.h" 20 #include "cmemory.h" 21 22 U_NAMESPACE_BEGIN 23 24 /** 25 * An optimization for the slowness of calling UnicodeString::append() 26 * one character at a time in a loop. It stores appends in a buffer while 27 * never actually calling append on the unicode string unless the buffer 28 * fills up or is flushed. 29 * 30 * proper usage: 31 * { 32 * UnicodeStringAppender appender(astring); 33 * for (int32_t i = 0; i < 100; ++i) { 34 * appender.append((UChar) i); 35 * } 36 * // appender flushed automatically when it goes out of scope. 37 * } 38 */ 39 class UnicodeStringAppender : public UMemory { 40 public: 41 42 /** 43 * dest is the UnicodeString being appended to. It must always 44 * exist while this instance exists. 45 */ UnicodeStringAppender(UnicodeString & dest)46 UnicodeStringAppender(UnicodeString &dest) : fDest(&dest), fIdx(0) { } 47 append(UChar x)48 inline void append(UChar x) { 49 if (fIdx == UPRV_LENGTHOF(fBuffer)) { 50 fDest->append(fBuffer, 0, fIdx); 51 fIdx = 0; 52 } 53 fBuffer[fIdx++] = x; 54 } 55 append(UChar32 x)56 inline void append(UChar32 x) { 57 if (fIdx >= UPRV_LENGTHOF(fBuffer) - 1) { 58 fDest->append(fBuffer, 0, fIdx); 59 fIdx = 0; 60 } 61 U16_APPEND_UNSAFE(fBuffer, fIdx, x); 62 } 63 64 /** 65 * Ensures that all appended characters have been written out to dest. 66 */ flush()67 inline void flush() { 68 if (fIdx) { 69 fDest->append(fBuffer, 0, fIdx); 70 } 71 fIdx = 0; 72 } 73 74 /** 75 * flush the buffer when we go out of scope. 76 */ ~UnicodeStringAppender()77 ~UnicodeStringAppender() { 78 flush(); 79 } 80 private: 81 UnicodeString *fDest; 82 int32_t fIdx; 83 UChar fBuffer[32]; 84 UnicodeStringAppender(const UnicodeStringAppender &other); 85 UnicodeStringAppender &operator=(const UnicodeStringAppender &other); 86 }; 87 88 U_NAMESPACE_END 89 90 #endif 91