Home | History | Annotate | Download | only in i18n
      1 //  2017 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 
      4 #include "unicode/utypes.h"
      5 
      6 #if !UCONFIG_NO_FORMATTING
      7 #ifndef __NUMBER_STRINGBUILDER_H__
      8 #define __NUMBER_STRINGBUILDER_H__
      9 
     10 
     11 #include <cstdint>
     12 #include "unicode/numfmt.h"
     13 #include "unicode/ustring.h"
     14 #include "cstring.h"
     15 #include "uassert.h"
     16 #include "number_types.h"
     17 #include "fphdlimp.h"
     18 
     19 U_NAMESPACE_BEGIN namespace number {
     20 namespace impl {
     21 
     22 class U_I18N_API NumberStringBuilder : public UMemory {
     23   private:
     24     static const int32_t DEFAULT_CAPACITY = 40;
     25 
     26     template<typename T>
     27     union ValueOrHeapArray {
     28         T value[DEFAULT_CAPACITY];
     29         struct {
     30             T *ptr;
     31             int32_t capacity;
     32         } heap;
     33     };
     34 
     35   public:
     36     NumberStringBuilder();
     37 
     38     ~NumberStringBuilder();
     39 
     40     NumberStringBuilder(const NumberStringBuilder &other);
     41 
     42     NumberStringBuilder &operator=(const NumberStringBuilder &other);
     43 
     44     int32_t length() const;
     45 
     46     int32_t codePointCount() const;
     47 
     48     inline char16_t charAt(int32_t index) const {
     49         U_ASSERT(index >= 0);
     50         U_ASSERT(index < fLength);
     51         return getCharPtr()[fZero + index];
     52     }
     53 
     54     inline Field fieldAt(int32_t index) const {
     55         U_ASSERT(index >= 0);
     56         U_ASSERT(index < fLength);
     57         return getFieldPtr()[fZero + index];
     58     }
     59 
     60     UChar32 getFirstCodePoint() const;
     61 
     62     UChar32 getLastCodePoint() const;
     63 
     64     UChar32 codePointAt(int32_t index) const;
     65 
     66     UChar32 codePointBefore(int32_t index) const;
     67 
     68     NumberStringBuilder &clear();
     69 
     70     int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status);
     71 
     72     int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status);
     73 
     74     int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status);
     75 
     76     int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status);
     77 
     78     int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field,
     79                    UErrorCode &status);
     80 
     81     int32_t splice(int32_t startThis, int32_t endThis,  const UnicodeString &unistr,
     82                    int32_t startOther, int32_t endOther, Field field, UErrorCode& status);
     83 
     84     int32_t append(const NumberStringBuilder &other, UErrorCode &status);
     85 
     86     int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status);
     87 
     88     /**
     89      * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed.
     90      * */
     91     UnicodeString toUnicodeString() const;
     92 
     93     /**
     94      * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and
     95      * unchanged. Slightly faster than toUnicodeString().
     96      */
     97     const UnicodeString toTempUnicodeString() const;
     98 
     99     UnicodeString toDebugString() const;
    100 
    101     const char16_t *chars() const;
    102 
    103     bool contentEquals(const NumberStringBuilder &other) const;
    104 
    105     bool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const;
    106 
    107     void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
    108 
    109     bool containsField(Field field) const;
    110 
    111   private:
    112     bool fUsingHeap = false;
    113     ValueOrHeapArray<char16_t> fChars;
    114     ValueOrHeapArray<Field> fFields;
    115     int32_t fZero = DEFAULT_CAPACITY / 2;
    116     int32_t fLength = 0;
    117 
    118     inline char16_t *getCharPtr() {
    119         return fUsingHeap ? fChars.heap.ptr : fChars.value;
    120     }
    121 
    122     inline const char16_t *getCharPtr() const {
    123         return fUsingHeap ? fChars.heap.ptr : fChars.value;
    124     }
    125 
    126     inline Field *getFieldPtr() {
    127         return fUsingHeap ? fFields.heap.ptr : fFields.value;
    128     }
    129 
    130     inline const Field *getFieldPtr() const {
    131         return fUsingHeap ? fFields.heap.ptr : fFields.value;
    132     }
    133 
    134     inline int32_t getCapacity() const {
    135         return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY;
    136     }
    137 
    138     int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status);
    139 
    140     int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status);
    141 
    142     int32_t remove(int32_t index, int32_t count);
    143 };
    144 
    145 } // namespace impl
    146 } // namespace number
    147 U_NAMESPACE_END
    148 
    149 
    150 #endif //__NUMBER_STRINGBUILDER_H__
    151 
    152 #endif /* #if !UCONFIG_NO_FORMATTING */
    153