Home | History | Annotate | Download | only in common
      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      */
     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     }
     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