1// Copyright (C) 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4*******************************************************************************
5*   Copyright (C) 2011-2012, International Business Machines
6*   Corporation and others.  All Rights Reserved.
7*******************************************************************************
8*   file name:  appendable.h
9*   encoding:   US-ASCII
10*   tab size:   8 (not used)
11*   indentation:4
12*
13*   created on: 2010dec07
14*   created by: Markus W. Scherer
15*/
16
17#ifndef __APPENDABLE_H__
18#define __APPENDABLE_H__
19
20/**
21 * \file
22 * \brief C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (UChars).
23 */
24
25#include "unicode/utypes.h"
26#include "unicode/uobject.h"
27
28U_NAMESPACE_BEGIN
29
30class UnicodeString;
31
32/**
33 * Base class for objects to which Unicode characters and strings can be appended.
34 * Combines elements of Java Appendable and ICU4C ByteSink.
35 *
36 * This class can be used in APIs where it does not matter whether the actual destination is
37 * a UnicodeString, a UChar[] array, a UnicodeSet, or any other object
38 * that receives and processes characters and/or strings.
39 *
40 * Implementation classes must implement at least appendCodeUnit(UChar).
41 * The base class provides default implementations for the other methods.
42 *
43 * The methods do not take UErrorCode parameters.
44 * If an error occurs (e.g., out-of-memory),
45 * in addition to returning FALSE from failing operations,
46 * the implementation must prevent unexpected behavior (e.g., crashes)
47 * from further calls and should make the error condition available separately
48 * (e.g., store a UErrorCode, make/keep a UnicodeString bogus).
49 * @stable ICU 4.8
50 */
51class U_COMMON_API Appendable : public UObject {
52public:
53    /**
54     * Destructor.
55     * @stable ICU 4.8
56     */
57    ~Appendable();
58
59    /**
60     * Appends a 16-bit code unit.
61     * @param c code unit
62     * @return TRUE if the operation succeeded
63     * @stable ICU 4.8
64     */
65    virtual UBool appendCodeUnit(UChar c) = 0;
66
67    /**
68     * Appends a code point.
69     * The default implementation calls appendCodeUnit(UChar) once or twice.
70     * @param c code point 0..0x10ffff
71     * @return TRUE if the operation succeeded
72     * @stable ICU 4.8
73     */
74    virtual UBool appendCodePoint(UChar32 c);
75
76    /**
77     * Appends a string.
78     * The default implementation calls appendCodeUnit(UChar) for each code unit.
79     * @param s string, must not be NULL if length!=0
80     * @param length string length, or -1 if NUL-terminated
81     * @return TRUE if the operation succeeded
82     * @stable ICU 4.8
83     */
84    virtual UBool appendString(const UChar *s, int32_t length);
85
86    /**
87     * Tells the object that the caller is going to append roughly
88     * appendCapacity UChars. A subclass might use this to pre-allocate
89     * a larger buffer if necessary.
90     * The default implementation does nothing. (It always returns TRUE.)
91     * @param appendCapacity estimated number of UChars that will be appended
92     * @return TRUE if the operation succeeded
93     * @stable ICU 4.8
94     */
95    virtual UBool reserveAppendCapacity(int32_t appendCapacity);
96
97    /**
98     * Returns a writable buffer for appending and writes the buffer's capacity to
99     * *resultCapacity. Guarantees *resultCapacity>=minCapacity.
100     * May return a pointer to the caller-owned scratch buffer which must have
101     * scratchCapacity>=minCapacity.
102     * The returned buffer is only valid until the next operation
103     * on this Appendable.
104     *
105     * After writing at most *resultCapacity UChars, call appendString() with the
106     * pointer returned from this function and the number of UChars written.
107     * Many appendString() implementations will avoid copying UChars if this function
108     * returned an internal buffer.
109     *
110     * Partial usage example:
111     * \code
112     *  int32_t capacity;
113     *  UChar* buffer = app.getAppendBuffer(..., &capacity);
114     *  ... Write n UChars into buffer, with n <= capacity.
115     *  app.appendString(buffer, n);
116     * \endcode
117     * In many implementations, that call to append will avoid copying UChars.
118     *
119     * If the Appendable allocates or reallocates an internal buffer, it should use
120     * the desiredCapacityHint if appropriate.
121     * If a caller cannot provide a reasonable guess at the desired capacity,
122     * it should pass desiredCapacityHint=0.
123     *
124     * If a non-scratch buffer is returned, the caller may only pass
125     * a prefix to it to appendString().
126     * That is, it is not correct to pass an interior pointer to appendString().
127     *
128     * The default implementation always returns the scratch buffer.
129     *
130     * @param minCapacity required minimum capacity of the returned buffer;
131     *                    must be non-negative
132     * @param desiredCapacityHint desired capacity of the returned buffer;
133     *                            must be non-negative
134     * @param scratch default caller-owned buffer
135     * @param scratchCapacity capacity of the scratch buffer
136     * @param resultCapacity pointer to an integer which will be set to the
137     *                       capacity of the returned buffer
138     * @return a buffer with *resultCapacity>=minCapacity
139     * @stable ICU 4.8
140     */
141    virtual UChar *getAppendBuffer(int32_t minCapacity,
142                                   int32_t desiredCapacityHint,
143                                   UChar *scratch, int32_t scratchCapacity,
144                                   int32_t *resultCapacity);
145};
146
147/**
148 * An Appendable implementation which writes to a UnicodeString.
149 *
150 * This class is not intended for public subclassing.
151 * @stable ICU 4.8
152 */
153class U_COMMON_API UnicodeStringAppendable : public Appendable {
154public:
155    /**
156     * Aliases the UnicodeString (keeps its reference) for writing.
157     * @param s The UnicodeString to which this Appendable will write.
158     * @stable ICU 4.8
159     */
160    explicit UnicodeStringAppendable(UnicodeString &s) : str(s) {}
161
162    /**
163     * Destructor.
164     * @stable ICU 4.8
165     */
166    ~UnicodeStringAppendable();
167
168    /**
169     * Appends a 16-bit code unit to the string.
170     * @param c code unit
171     * @return TRUE if the operation succeeded
172     * @stable ICU 4.8
173     */
174    virtual UBool appendCodeUnit(UChar c);
175
176    /**
177     * Appends a code point to the string.
178     * @param c code point 0..0x10ffff
179     * @return TRUE if the operation succeeded
180     * @stable ICU 4.8
181     */
182    virtual UBool appendCodePoint(UChar32 c);
183
184    /**
185     * Appends a string to the UnicodeString.
186     * @param s string, must not be NULL if length!=0
187     * @param length string length, or -1 if NUL-terminated
188     * @return TRUE if the operation succeeded
189     * @stable ICU 4.8
190     */
191    virtual UBool appendString(const UChar *s, int32_t length);
192
193    /**
194     * Tells the UnicodeString that the caller is going to append roughly
195     * appendCapacity UChars.
196     * @param appendCapacity estimated number of UChars that will be appended
197     * @return TRUE if the operation succeeded
198     * @stable ICU 4.8
199     */
200    virtual UBool reserveAppendCapacity(int32_t appendCapacity);
201
202    /**
203     * Returns a writable buffer for appending and writes the buffer's capacity to
204     * *resultCapacity. Guarantees *resultCapacity>=minCapacity.
205     * May return a pointer to the caller-owned scratch buffer which must have
206     * scratchCapacity>=minCapacity.
207     * The returned buffer is only valid until the next write operation
208     * on the UnicodeString.
209     *
210     * For details see Appendable::getAppendBuffer().
211     *
212     * @param minCapacity required minimum capacity of the returned buffer;
213     *                    must be non-negative
214     * @param desiredCapacityHint desired capacity of the returned buffer;
215     *                            must be non-negative
216     * @param scratch default caller-owned buffer
217     * @param scratchCapacity capacity of the scratch buffer
218     * @param resultCapacity pointer to an integer which will be set to the
219     *                       capacity of the returned buffer
220     * @return a buffer with *resultCapacity>=minCapacity
221     * @stable ICU 4.8
222     */
223    virtual UChar *getAppendBuffer(int32_t minCapacity,
224                                   int32_t desiredCapacityHint,
225                                   UChar *scratch, int32_t scratchCapacity,
226                                   int32_t *resultCapacity);
227
228private:
229    UnicodeString &str;
230};
231
232U_NAMESPACE_END
233
234#endif  // __APPENDABLE_H__
235