• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
UnicodeStringAppender(UnicodeString & dest)44     UnicodeStringAppender(UnicodeString &dest) : fDest(&dest), fIdx(0) { }
45 
append(UChar x)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 
append(UChar32 x)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      */
flush()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      */
~UnicodeStringAppender()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