]> git.donarmstrong.com Git - lilypond.git/blob - flower/stringutil.cc
bca803a23e6367ad83b103aad9717f1113f6cab6
[lilypond.git] / flower / stringutil.cc
1 // stringutil.cc
2 #ifndef __STRING_UTIL_CC
3 #define __STRING_UTIL_CC
4
5 // include only when 
6 // *  reading stringutil.hh, or 
7 // *  string util stuff not inlined
8 #if !defined STRING_UTILS_INLINED
9
10 #include <assert.h>
11 #include <memory.h>
12 #include "stringutil.hh"
13
14
15 // namespace StringData { namespaces are broken in this version of g++ 
16 // gcc version 2.7.2.1
17
18
19 StringData::StringData() 
20 {
21     references=0;
22     maxlen = INITIALMAX;
23     data_by_p_ = new Byte[maxlen + 1];
24     data_by_p_[0] = 0;
25     length_i_ = 0;
26 }
27
28 StringData::StringData(StringData const &src) 
29 {
30     references=0;       
31     maxlen = length_i_ = src.length_i_;         
32     data_by_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead.         
33     memmove( data_by_p_, src.data_by_p_, length_i_ + 1 );       
34 }
35
36
37 StringData::~StringData() 
38 {
39     assert(references == 0);
40     delete[] data_by_p_;
41 }
42
43 void 
44 StringData::setmax(int j) 
45 {       
46     OKW();
47     if (j > maxlen) {
48         delete data_by_p_;
49         maxlen = j;
50         data_by_p_ = new Byte[maxlen + 1];
51     
52         data_by_p_[0] = 0;
53         length_i_ = 0;
54     }
55 }
56
57
58 void 
59 StringData::remax(int j) 
60 {
61     OKW();
62     if (j > maxlen) {
63         maxlen = j;
64         Byte *p = new Byte[maxlen + 1];     
65         memmove( p, data_by_p_, length_i_ + 1 );            
66         delete[] data_by_p_;
67         data_by_p_ = p;
68     //    length_i_ = strlength_i(data_by_p_);
69     }
70 }
71
72
73 void 
74 StringData::OKW() 
75 {
76     assert (references == 1);
77 }
78
79 void 
80 StringData::OK() 
81 {
82 // can-t do this with binary data
83 //      assert(strlen(data_by_p_) == size_t(length_i_));
84     assert(maxlen >= length_i_);
85     assert(bool(data_by_p_));
86     assert(references >= 1);
87 }
88
89 //    // needed?
90 // well, we can't -> depreciated
91 //    void update() {
92 //      length_i_  = strlen (data_by_p_);
93 //    }
94
95
96 void 
97 StringData::tighten() 
98 { // should be dec'd const
99     maxlen = length_i_;
100     Byte *p = new Byte[maxlen + 1];         
101     memmove( p, data_by_p_, length_i_ + 1 );        
102     delete[] data_by_p_;
103     data_by_p_ = p;             
104 }
105
106 // assignment.
107 void 
108 StringData::set( Byte const* by_c_l, int length_i ) 
109 {
110     OKW();
111
112     assert( by_c_l && by_c_l != data_by_p_);
113
114     length_i_ = length_i;
115     remax( length_i_ );
116     memmove( data_by_p_, by_c_l, length_i_ );
117     data_by_p_[ length_i_ ] = 0;
118 }
119
120
121 void 
122 StringData::set( char const* ch_c_l ) 
123 {
124     set( (Byte const*)ch_c_l, strlen( ch_c_l ) );
125 }
126
127
128 /// concatenation.
129 void 
130 StringData::append( Byte const* by_c_l, int length_i ) 
131 {
132     OK();
133     OKW();
134     int old_i = length_i_;
135     
136     length_i_ += length_i;
137     remax( length_i_ );
138     memmove( data_by_p_ + old_i, by_c_l, length_i );    
139     data_by_p_[ length_i_ ] = 0;
140 }
141
142
143 void 
144 StringData::operator += ( char const* ch_c_l ) 
145 {
146     append( (Byte const*)ch_c_l, strlen( ch_c_l ) );
147 }
148
149 char const*
150 StringData::ch_c_l() const
151 {
152     return (char const*)data_by_p_; 
153 }
154
155 char* 
156 StringData::ch_l() 
157
158     return (char*)data_by_p_; 
159 }
160
161 Byte const*
162 StringData::by_c_l() const 
163
164     return data_by_p_; 
165 }
166
167 // idem, non const
168 Byte* 
169 StringData::by_l() 
170 {
171     OKW();
172     return data_by_p_;
173 }
174
175 void 
176 StringData::trunc(int j) 
177 {
178     OKW(); 
179     assert(j >= 0 && j <= length_i_);
180     data_by_p_[j] = 0;
181     length_i_ = j;
182 }
183
184 Byte&
185 StringData::operator [](int j) 
186 {
187     assert(j >= 0 && j <= length_i_);
188     return data_by_p_[j] ; 
189 }
190
191 Byte 
192 StringData::operator [](int j) const 
193 {
194     assert(j >= 0 && j <= length_i_);
195     return data_by_p_[j]; 
196 }
197
198
199 // } namespace broken
200
201
202
203
204 // namespace String_handle {
205
206
207 void 
208 String_handle::down() 
209
210     if (!(--data->references)) delete data; data = 0; 
211 }
212
213 /// increase ref count
214 void 
215 String_handle::up(StringData *d) 
216
217     data=d; data->references ++; 
218 }
219
220 void 
221 String_handle::copy() 
222 {
223     if (data->references !=1){
224         StringData *newdata = new StringData(*data);
225         down();
226         up(newdata);
227     }
228 }
229
230 String_handle::String_handle() 
231 {
232     up(new StringData);
233 }
234 String_handle::~String_handle() 
235 {       
236     down();
237 }    
238 String_handle::String_handle(String_handle const & src) 
239 {       
240     up(src.data);
241 }
242
243 Byte* 
244 String_handle::by_l() 
245 {
246     copy();
247     return data->by_l();
248 }
249
250 char* 
251 String_handle::ch_l() 
252 {
253     copy();
254     return (char*)data->by_l();
255 }
256
257 Byte 
258 const* String_handle::by_c_l() const 
259 {
260     return data->by_c_l();
261 }
262
263 char const* 
264 String_handle::ch_c_l() const 
265 {
266     return (char const*)data->by_c_l();
267 }
268
269 void 
270 String_handle::operator =(String_handle const &src) 
271 {
272     if (this == &src)
273         return;
274     down();
275     up(src.data);
276 }
277
278 void 
279 String_handle::operator += (char const *s) 
280 {       
281     copy();
282     *data += s;
283 }    
284
285
286 Byte 
287 String_handle::operator[](int j) const 
288
289     return (*data)[j]; 
290 }
291
292 // !NOT SAFE!
293 // don't use this for loops. Use by_c_l()
294 Byte &
295 String_handle::operator[](int j) 
296 {
297     copy();     // hmm. Not efficient
298     return data->by_l()[j];
299 }
300
301 void 
302 String_handle::append( Byte const* by_c_l, int length_i ) 
303 {
304     copy();
305     data->append( by_c_l, length_i );
306 }
307                            
308 void 
309 String_handle::set( Byte const* by_c_l, int length_i ) 
310 {
311     copy();
312     data->set( by_c_l, length_i );
313 }
314                            
315 void 
316 String_handle::operator = (char const *p) 
317 {
318     copy();
319     data->set( p );
320 }
321                            
322 void 
323 String_handle::trunc(int j) 
324 {
325     copy(); data->trunc(j); 
326 }
327
328 int 
329 String_handle::length_i() const 
330
331     return data->length_i_; 
332 }
333
334
335 // } namespaces broken
336
337
338 #endif // not STRING_UTILS_INLINED //
339
340 #endif // __STRING_UTIL_CC //