Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
string_builder.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_core/string_builder.h
10 //! @brief String builder.
11 
12 #ifndef ROC_CORE_STRING_BUILDER_H_
13 #define ROC_CORE_STRING_BUILDER_H_
14 
15 #include "roc_core/macro_helpers.h"
16 #include "roc_core/noncopyable.h"
17 #include "roc_core/optional.h"
18 #include "roc_core/stddefs.h"
19 #include "roc_core/string_buffer.h"
20 
21 namespace roc {
22 namespace core {
23 
24 //! String builder.
25 //!
26 //! Allows to incrementally build a string. Doesn't own the string itself, but
27 //! instead holds a reference to external fixed-size or dynamic buffer.
28 //
29 //! Supports "dry run" mode when no actual writing happens. This can be used
30 //! to calculate the required buffer size before writing.
31 //!
32 //! When used with fixed-sized buffer, all methods are signal-safe and hence
33 //! can be used from a signal handler.
34 class StringBuilder : public NonCopyable<> {
35 public:
36  //! Construct string builder on top of fixed-size buffer.
37  //!
38  //! The builder will write output string into the given buffer.
39  //! If the output buffer is too small, the output string is truncated
40  //! and error flag is set. If the output buffer has at least one byte,
41  //! it will be always zero-terminated, even if truncation occurred.
42  //!
43  //! @p buf may be NULL. In this case, nothing will be written, but
44  //! needed_size() will be still calculated.
45  //!
46  //! If @p buf is non-NULL, @p bufsz should be non-zero so that buffer
47  //! could hold at least zero terminator. Otherwise, error flag is raised
48  //! immediately in constructor.
49  //!
50  //! If @p buf is NULL, @p bufsz may be both zero and non-zero. Use
51  //! non-zero to get an error when buffer size is exceeded (like if it was
52  //! a real buffer); use zero to disable buffer size checking (there is
53  //! no buffer anyway).
54  StringBuilder(char* buf, size_t bufsz);
55 
56  //! Construct string builder on top of dynamic buffer.
57  //!
58  //! The builder will write output string into the given buffer. The buffer
59  //! will be resized accordingly to the output string size plus terminating
60  //! zero byte. The buffer will be always zero-terminated.
62 
63  //! Get number of bytes required to store the output string.
64  //! Includes terminating zero byte.
65  //!
66  //! @remarks
67  //! If there is non-NULL output buffer, and no error occurred, this size
68  //! is equal to actual_size(). Otherwise it may be larger.
69  size_t needed_size() const;
70 
71  //! Get number of bytes actually written to the output string.
72  //! Includes terminating zero byte.
73  size_t actual_size() const;
74 
75  //! Check for errors.
76  //! @remarks
77  //! Error flag is raised if any of the methods fail, and is cleared
78  //! if an assign* method succeeds.
79  bool is_ok() const;
80 
81  //! Overwrite result with given string.
82  //! If there is not enough space, truncates the string and returns false.
83  bool assign_str(const char* str);
84 
85  //! Overwrite result with given range.
86  //! If there is not enough space, truncates the string and returns false.
87  bool assign_str(const char* str_begin, const char* str_end);
88 
89  //! Append to result given string.
90  //! If there is not enough space, truncates the string and returns false.
91  bool append_str(const char* str);
92 
93  //! Append to result given range.
94  //! If there is not enough space, truncates the string and returns false.
95  bool append_str(const char* str_begin, const char* str_end);
96 
97  //! Append to result given character.
98  //! If there is not enough space, truncates the string and returns false.
99  bool append_char(char ch);
100 
101  //! Format and append to result given number.
102  //! If there is not enough space, truncates the string and returns false.
103  bool append_uint(uint64_t number, unsigned int base);
104 
105 private:
106  class IBufferWriter {
107  public:
108  virtual ~IBufferWriter();
109 
110  virtual bool is_noop() = 0;
111  virtual bool reset() = 0;
112  virtual bool grow_by(size_t n_chars) = 0;
113  virtual ssize_t extend_by(size_t n_chars) = 0;
114  virtual char* write_ptr() = 0;
115  };
116 
117  class StaticBufferWriter : public IBufferWriter {
118  public:
119  StaticBufferWriter(char* buf, size_t buf_size);
120 
121  virtual bool is_noop();
122  virtual bool reset();
123  virtual bool grow_by(size_t n_chars);
124  virtual ssize_t extend_by(size_t n_chars);
125  virtual char* write_ptr();
126 
127  private:
128  char* const buf_;
129  const size_t buf_max_size_;
130  size_t buf_cur_size_;
131  char* buf_wr_ptr_;
132  };
133 
134  class DynamicBufferWriter : public IBufferWriter {
135  public:
136  DynamicBufferWriter(StringBuffer& buf);
137 
138  virtual bool is_noop();
139  virtual bool reset();
140  virtual bool grow_by(size_t n_chars);
141  virtual ssize_t extend_by(size_t n_chars);
142  virtual char* write_ptr();
143 
144  private:
145  StringBuffer& buf_;
146  char* buf_wr_ptr_;
147  };
148 
149  void initialize_();
150  void reset_();
151  bool append_(const char* str, size_t str_size, bool grow);
152 
153  Optional<IBufferWriter,
154  ROC_MAX(sizeof(StaticBufferWriter), sizeof(DynamicBufferWriter))>
155  writer_;
156 
157  size_t n_processed_;
158  size_t n_written_;
159 
160  bool truncation_error_;
161  bool write_error_;
162 };
163 
164 } // namespace core
165 } // namespace roc
166 
167 #endif // ROC_CORE_STRING_BUILDER_H_
Base class for non-copyable objects.
Definition: noncopyable.h:23
size_t needed_size() const
Get number of bytes required to store the output string. Includes terminating zero byte.
bool assign_str(const char *str)
Overwrite result with given string. If there is not enough space, truncates the string and returns fa...
bool append_str(const char *str)
Append to result given string. If there is not enough space, truncates the string and returns false.
StringBuilder(StringBuffer &buf)
Construct string builder on top of dynamic buffer.
bool append_uint(uint64_t number, unsigned int base)
Format and append to result given number. If there is not enough space, truncates the string and retu...
bool assign_str(const char *str_begin, const char *str_end)
Overwrite result with given range. If there is not enough space, truncates the string and returns fal...
bool is_ok() const
Check for errors.
StringBuilder(char *buf, size_t bufsz)
Construct string builder on top of fixed-size buffer.
size_t actual_size() const
Get number of bytes actually written to the output string. Includes terminating zero byte.
bool append_str(const char *str_begin, const char *str_end)
Append to result given range. If there is not enough space, truncates the string and returns false.
bool append_char(char ch)
Append to result given character. If there is not enough space, truncates the string and returns fals...
Helper macros.
#define ROC_MAX(a, b)
Select minum value.
Definition: macro_helpers.h:21
Root namespace.
Non-copyable object.
Optionally constructed object.
Commonly used types and functions.
String buffer.