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