7 // switching into "blonde" mode
8 // i trust stringclass nowadays.
12 /// Internal String struct
14 // GNU malloc: storage overhead is 8 bytes anyway.
15 const int INITIALMAX = 8;
17 friend class String_handle;
18 int maxlen; // maxlen is arraysize-1
28 string = new char[maxlen + 1];
33 /// init from src. Conservative allocation.
34 StringData(StringData const &src) {
36 maxlen = length = src.length;
37 string = new char[maxlen+1]; // should calc GNU 8byte overhead.
38 strcpy(string, src.string);
42 assert(references == 0);
52 string = new char[maxlen + 1];
58 /** POST: maxlen >= j.
59 IN: j, maximum stringlength.
67 char *p = new char[maxlen + 1];
71 // length = strlen(string);
74 /** POST: maxlen >= j.
75 IN: j, maximum stringlength.
76 contents are kept if it grows.
78 /// check if writeable.
81 assert (references == 1);
87 assert(strlen(string) == size_t(length));
88 assert(maxlen >= length);
90 assert(references >= 1);
95 length = strlen (string);
98 /// reduce memory usage.
99 void tighten() { // should be dec'd const
101 char *p = new char[maxlen + 1];
108 void set(const char *s) {
119 void operator += (const char *s) {
126 strcpy(string + old, s);
130 operator const char *() const { return string; }
133 char *array_for_modify() {
139 assert(j >= 0 && j <= length);
144 /** not really safe. Can alter length without StringData knowing it.
146 char &operator [](int j) {
147 assert(j >= 0 && j <= length);
151 char operator [](int j) const {
152 assert(j >= 0 && j <= length);
158 the data itself. Handles simple tasks (resizing, resetting)
160 /****************************************************************/
161 /// ref. counting for strings
162 class String_handle {
165 /// decrease ref count. Named kind of like a Tanenbaum semafore
166 void down() { if (!(--data->references)) delete data; data = 0; }
168 /// increase ref count
169 void up(StringData *d) { data=d; data->references ++; }
171 /** make sure data has only one reference.
172 POST: data->references == 1
175 if (data->references !=1){
176 StringData *newdata = new StringData(*data);
190 String_handle(String_handle const & src) {
194 /// retrieve the actual array.
195 operator const char *() const { return *data; }
196 char *array_for_modify() {
198 return data->array_for_modify();
201 void operator =(String_handle const &src) {
208 void operator += (const char *s) {
214 char operator[](int j) const { return (*data)[j]; }
217 // don't use this for loops. Use array_for_modify()
218 char &operator[](int j) {
219 copy(); // hmm. Not efficient
220 return data->array_for_modify()[j];
223 void operator = (char const *p) {
228 void trunc(int j) { copy(); data->trunc(j); }
229 int len() const { return data->length; }
232 handles ref. counting, and provides a very thin
233 interface using char *
238 #if (NDEBUG == BLONDE)
245 #endif // STRINGUTIL_HH