Coverage Report

Created: 2025-07-11 06:23

/src/icu/source/common/unicode/bytestream.h
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
// Copyright (C) 2009-2012, International Business Machines
4
// Corporation and others. All Rights Reserved.
5
//
6
// Copyright 2007 Google Inc. All Rights Reserved.
7
// Author: sanjay@google.com (Sanjay Ghemawat)
8
//
9
// Abstract interface that consumes a sequence of bytes (ByteSink).
10
//
11
// Used so that we can write a single piece of code that can operate
12
// on a variety of output string types.
13
//
14
// Various implementations of this interface are provided:
15
//   ByteSink:
16
//      CheckedArrayByteSink    Write to a flat array, with bounds checking
17
//      StringByteSink          Write to an STL string
18
19
// This code is a contribution of Google code, and the style used here is
20
// a compromise between the original Google code and the ICU coding guidelines.
21
// For example, data types are ICU-ified (size_t,int->int32_t),
22
// and API comments doxygen-ified, but function names and behavior are
23
// as in the original, if possible.
24
// Assertion-style error handling, not available in ICU, was changed to
25
// parameter "pinning" similar to UnicodeString.
26
//
27
// In addition, this is only a partial port of the original Google code,
28
// limited to what was needed so far. The (nearly) complete original code
29
// is in the ICU svn repository at icuhtml/trunk/design/strings/contrib
30
// (see ICU ticket 6765, r25517).
31
32
#ifndef __BYTESTREAM_H__
33
#define __BYTESTREAM_H__
34
35
/**
36
 * \file
37
 * \brief C++ API: Interface for writing bytes, and implementation classes.
38
 */
39
40
#include "unicode/utypes.h"
41
#include "unicode/uobject.h"
42
#include "unicode/std_string.h"
43
44
U_NAMESPACE_BEGIN
45
46
/**
47
 * A ByteSink can be filled with bytes.
48
 * @stable ICU 4.2
49
 */
50
class U_COMMON_API ByteSink : public UMemory {
51
public:
52
  /**
53
   * Default constructor.
54
   * @stable ICU 4.2
55
   */
56
0
  ByteSink() { }
57
  /**
58
   * Virtual destructor.
59
   * @stable ICU 4.2
60
   */
61
  virtual ~ByteSink();
62
63
  /**
64
   * Append "bytes[0,n-1]" to this.
65
   * @param bytes the pointer to the bytes
66
   * @param n the number of bytes; must be non-negative
67
   * @stable ICU 4.2
68
   */
69
  virtual void Append(const char* bytes, int32_t n) = 0;
70
71
  /**
72
   * Returns a writable buffer for appending and writes the buffer's capacity to
73
   * *result_capacity. Guarantees *result_capacity>=min_capacity.
74
   * May return a pointer to the caller-owned scratch buffer which must have
75
   * scratch_capacity>=min_capacity.
76
   * The returned buffer is only valid until the next operation
77
   * on this ByteSink.
78
   *
79
   * After writing at most *result_capacity bytes, call Append() with the
80
   * pointer returned from this function and the number of bytes written.
81
   * Many Append() implementations will avoid copying bytes if this function
82
   * returned an internal buffer.
83
   *
84
   * Partial usage example:
85
   *  int32_t capacity;
86
   *  char* buffer = sink->GetAppendBuffer(..., &capacity);
87
   *  ... Write n bytes into buffer, with n <= capacity.
88
   *  sink->Append(buffer, n);
89
   * In many implementations, that call to Append will avoid copying bytes.
90
   *
91
   * If the ByteSink allocates or reallocates an internal buffer, it should use
92
   * the desired_capacity_hint if appropriate.
93
   * If a caller cannot provide a reasonable guess at the desired capacity,
94
   * it should pass desired_capacity_hint=0.
95
   *
96
   * If a non-scratch buffer is returned, the caller may only pass
97
   * a prefix to it to Append().
98
   * That is, it is not correct to pass an interior pointer to Append().
99
   *
100
   * The default implementation always returns the scratch buffer.
101
   *
102
   * @param min_capacity required minimum capacity of the returned buffer;
103
   *                     must be non-negative
104
   * @param desired_capacity_hint desired capacity of the returned buffer;
105
   *                              must be non-negative
106
   * @param scratch default caller-owned buffer
107
   * @param scratch_capacity capacity of the scratch buffer
108
   * @param result_capacity pointer to an integer which will be set to the
109
   *                        capacity of the returned buffer
110
   * @return a buffer with *result_capacity>=min_capacity
111
   * @stable ICU 4.2
112
   */
113
  virtual char* GetAppendBuffer(int32_t min_capacity,
114
                                int32_t desired_capacity_hint,
115
                                char* scratch, int32_t scratch_capacity,
116
                                int32_t* result_capacity);
117
118
  /**
119
   * Flush internal buffers.
120
   * Some byte sinks use internal buffers or provide buffering
121
   * and require calling Flush() at the end of the stream.
122
   * The ByteSink should be ready for further Append() calls after Flush().
123
   * The default implementation of Flush() does nothing.
124
   * @stable ICU 4.2
125
   */
126
  virtual void Flush();
127
128
private:
129
  ByteSink(const ByteSink &); // copy constructor not implemented
130
  ByteSink &operator=(const ByteSink &); // assignment operator not implemented
131
};
132
133
// -------------------------------------------------------------
134
// Some standard implementations
135
136
/** 
137
 * Implementation of ByteSink that writes to a flat byte array,
138
 * with bounds-checking:
139
 * This sink will not write more than capacity bytes to outbuf.
140
 * If more than capacity bytes are Append()ed, then excess bytes are ignored,
141
 * and Overflowed() will return true.
142
 * Overflow does not cause a runtime error.
143
 * @stable ICU 4.2
144
 */
145
class U_COMMON_API CheckedArrayByteSink : public ByteSink {
146
public:
147
  /**
148
   * Constructs a ByteSink that will write to outbuf[0..capacity-1].
149
   * @param outbuf buffer to write to
150
   * @param capacity size of the buffer
151
   * @stable ICU 4.2
152
   */
153
  CheckedArrayByteSink(char* outbuf, int32_t capacity);
154
  /**
155
   * Destructor.
156
   * @stable ICU 4.2
157
   */
158
  virtual ~CheckedArrayByteSink();
159
  /**
160
   * Returns the sink to its original state, without modifying the buffer.
161
   * Useful for reusing both the buffer and the sink for multiple streams.
162
   * Resets the state to NumberOfBytesWritten()=NumberOfBytesAppended()=0
163
   * and Overflowed()=FALSE.
164
   * @return *this
165
   * @stable ICU 4.6
166
   */
167
  virtual CheckedArrayByteSink& Reset();
168
  /**
169
   * Append "bytes[0,n-1]" to this.
170
   * @param bytes the pointer to the bytes
171
   * @param n the number of bytes; must be non-negative
172
   * @stable ICU 4.2
173
   */
174
  virtual void Append(const char* bytes, int32_t n);
175
  /**
176
   * Returns a writable buffer for appending and writes the buffer's capacity to
177
   * *result_capacity. For details see the base class documentation.
178
   * @param min_capacity required minimum capacity of the returned buffer;
179
   *                     must be non-negative
180
   * @param desired_capacity_hint desired capacity of the returned buffer;
181
   *                              must be non-negative
182
   * @param scratch default caller-owned buffer
183
   * @param scratch_capacity capacity of the scratch buffer
184
   * @param result_capacity pointer to an integer which will be set to the
185
   *                        capacity of the returned buffer
186
   * @return a buffer with *result_capacity>=min_capacity
187
   * @stable ICU 4.2
188
   */
189
  virtual char* GetAppendBuffer(int32_t min_capacity,
190
                                int32_t desired_capacity_hint,
191
                                char* scratch, int32_t scratch_capacity,
192
                                int32_t* result_capacity);
193
  /**
194
   * Returns the number of bytes actually written to the sink.
195
   * @return number of bytes written to the buffer
196
   * @stable ICU 4.2
197
   */
198
0
  int32_t NumberOfBytesWritten() const { return size_; }
199
  /**
200
   * Returns true if any bytes were discarded, i.e., if there was an
201
   * attempt to write more than 'capacity' bytes.
202
   * @return TRUE if more than 'capacity' bytes were Append()ed
203
   * @stable ICU 4.2
204
   */
205
0
  UBool Overflowed() const { return overflowed_; }
206
  /**
207
   * Returns the number of bytes appended to the sink.
208
   * If Overflowed() then NumberOfBytesAppended()>NumberOfBytesWritten()
209
   * else they return the same number.
210
   * @return number of bytes written to the buffer
211
   * @stable ICU 4.6
212
   */
213
0
  int32_t NumberOfBytesAppended() const { return appended_; }
214
private:
215
  char* outbuf_;
216
  const int32_t capacity_;
217
  int32_t size_;
218
  int32_t appended_;
219
  UBool overflowed_;
220
  CheckedArrayByteSink(); ///< default constructor not implemented 
221
  CheckedArrayByteSink(const CheckedArrayByteSink &); ///< copy constructor not implemented
222
  CheckedArrayByteSink &operator=(const CheckedArrayByteSink &); ///< assignment operator not implemented
223
};
224
225
/** 
226
 * Implementation of ByteSink that writes to a "string".
227
 * The StringClass is usually instantiated with a std::string.
228
 * @stable ICU 4.2
229
 */
230
template<typename StringClass>
231
class StringByteSink : public ByteSink {
232
 public:
233
  /**
234
   * Constructs a ByteSink that will append bytes to the dest string.
235
   * @param dest pointer to string object to append to
236
   * @stable ICU 4.2
237
   */
238
  StringByteSink(StringClass* dest) : dest_(dest) { }
239
  /**
240
   * Append "bytes[0,n-1]" to this.
241
   * @param data the pointer to the bytes
242
   * @param n the number of bytes; must be non-negative
243
   * @stable ICU 4.2
244
   */
245
  virtual void Append(const char* data, int32_t n) { dest_->append(data, n); }
246
 private:
247
  StringClass* dest_;
248
  StringByteSink(); ///< default constructor not implemented 
249
  StringByteSink(const StringByteSink &); ///< copy constructor not implemented
250
  StringByteSink &operator=(const StringByteSink &); ///< assignment operator not implemented
251
};
252
253
U_NAMESPACE_END
254
255
#endif  // __BYTESTREAM_H__