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 22U_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 */ 39class UnicodeStringAppender : public UMemory { 40public: 41 42 /** 43 * dest is the UnicodeString being appended to. It must always 44 * exist while this instance exists. 45 */ 46 UnicodeStringAppender(UnicodeString &dest) : fDest(&dest), fIdx(0) { } 47 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 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 */ 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 */ 77 ~UnicodeStringAppender() { 78 flush(); 79 } 80private: 81 UnicodeString *fDest; 82 int32_t fIdx; 83 UChar fBuffer[32]; 84 UnicodeStringAppender(const UnicodeStringAppender &other); 85 UnicodeStringAppender &operator=(const UnicodeStringAppender &other); 86}; 87 88U_NAMESPACE_END 89 90#endif 91