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