1 //
2 //	aegis - project change supervisor
3 //	Copyright (C) 2004-2006, 2008 Peter Miller
4 //
5 //	This program is free software; you can redistribute it and/or modify
6 //	it under the terms of the GNU General Public License as published by
7 //	the Free Software Foundation; either version 3 of the License, or
8 //	(at your option) any later version.
9 //
10 //	This program is distributed in the hope that it will be useful,
11 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //	GNU General Public License for more details.
14 //
15 //	You should have received a copy of the GNU General Public License
16 //	along with this program. If not, see
17 //	<http://www.gnu.org/licenses/>.
18 //
19 
20 #ifndef COMMON_NSTRING_ACCUMULATOR_H
21 #define COMMON_NSTRING_ACCUMULATOR_H
22 
23 #include <common/nstring.h>
24 
25 /** \addtogroup String_Accumulator
26   * \brief String Accumulation functions
27   * \ingroup String
28   * @{
29   */
30 
31 /**
32   * The nstring_accumulator class is used to accumulate strings into a buffer.
33   */
34 class nstring_accumulator
35 {
36 public:
37     /**
38       * The destructor.  Thou shalt not derive from this class because
39       * it isn't virtual.
40       */
41     ~nstring_accumulator();
42 
43     /**
44       * The default constructor.
45       */
46     nstring_accumulator();
47 
48     /**
49       * The copy constructor.
50       */
51     nstring_accumulator(const nstring_accumulator &);
52 
53     /**
54       * The assignment operator.
55       */
56     nstring_accumulator &operator=(const nstring_accumulator &);
57 
58     /**
59       * The mkstr method is used to take the current contents of the
60       * accumulated buffer and turn it into a string.
61       */
62     nstring mkstr() const;
63 
64     /**
65       * The push_back method is used to append another character to the
66       * end of the accumulator.
67       *
68       * \param c
69       *     The character to be appended to the buffer.
70       */
71     void
push_back(char c)72     push_back(char c)
73     {
74 	//
75         // The nstring_accumulator::push_back(char) method shows up
76         // in the profiles as occupying 10% of the time it takes to
77         // parse the database files.  By making it an inline, things go
78         // measurably faster.
79 	//
80 	if (length < maximum)
81 	    buffer[length++] = c;
82 	else
83 	    overflow(c);
84     }
85 
86     /**
87       * The push_back method is used to append an array of characters to
88       * the end of the accumulator.
89       *
90       * \param data
91       *     The data to be appended to the buffer.
92       * \param len
93       *     The number of bytes of data.
94       */
95     void push_back(const char *data, size_t len);
96 
97     /**
98       * The push_back method is used to append a NUL terminated string
99       * to the end of the accumulator.
100       *
101       * \param data
102       *     The string to be appended to the buffer.
103       */
104     void push_back(const char *data);
105 
106     /**
107       * The push_back method is used to append another string
108       * accumulator to the end of this accumulator.
109       *
110       * \param data
111       *     The string to be appended to the buffer.
112       */
113     void push_back(const nstring_accumulator &data);
114 
115     /**
116       * The push_back method is used to append another string
117       * accumulator to the end of this accumulator.
118       *
119       * \param data
120       *     The string to be appended to the buffer.
121       */
122     void push_back(const nstring &data);
123 
124     /**
125       * The clear method is used to reset the length of the accumulated
126       * string to zero.
127       */
clear()128     void clear() { length = 0; }
129 
130     /**
131       * The size method is used to obtain the current size of the buffer
132       * in characters.
133       */
size()134     size_t size() const { return length; }
135 
136     /**
137       * The empty method is used to determine if the buffer is empty
138       * (has a size of zero).
139       */
empty()140     bool empty() const { return (length == 0); }
141 
142     /**
143       * The pop_back method is used to remove the last character from
144       * the buffer.
145       */
pop_back()146     void pop_back() { if (length) --length; }
147 
148     /**
149       * The back method is used to obtain the last character in the
150       * buffer, or NUL if the buffer is empty.
151       */
back()152     char back() { return (length ? buffer[length - 1] : 0); }
153 
154     /**
155       * The get_data method is used to obtain a pointer to the base of
156       * the array of characters being accumulated.
157       *
158       * \note
159       *     The pointer is only garanteed to be valid until the next
160       *     push_back method call.
161       * \note
162       *     Please use this methdo as little as possible.
163       */
get_data()164     const char *get_data() const { return (buffer ? buffer : ""); }
165 
166     /**
167       * The array index operator is used to obtain thr nth character in
168       * the buffer.
169       *
170       * \note
171       *     No array bounds checking is performed.  If you really stuff
172       *     up, it will segfault.  Caveat emptor.
173       */
174     char operator[](size_t n) { return buffer[n]; }
175 
176 private:
177     /**
178       * The overflow method is used to append another character to the
179       * end of the accumulator.  It is called by the putch method when
180       * it get too too hard (and a new buffer is needed).
181       *
182       * \param c
183       *     The character to be appended to the buffer.
184       */
185     void overflow(char c);
186 
187     /**
188       * The length instance variable is used to remember how many
189       * characters in the buffer are significant.
190       */
191     size_t length;
192 
193     /**
194       * The length instance variable is used to remember the allocated
195       * size of the buffer.
196       */
197     size_t maximum;
198 
199     /**
200       * The length instance variable is used to remember the base of an
201       * array of characters in the heap.
202       */
203     char *buffer;
204 };
205 
206 
207 /** @} */
208 #endif // COMMON_NSTRING_ACCUMULATOR_H
209