10 /// Internal String struct
12 // GNU malloc: storage overhead is 8 bytes anyway.
13 const int INITIALMAX =8; // how to do this in ANSI C++ ?
15 friend class String_handle;
16 int maxlen; // maxlen is arraysize-1
26 string = new char[maxlen + 1];
31 /// init from src. Conservative allocation.
32 StringData(StringData const &src) {
34 maxlen = length = src.length;
35 string = new char[maxlen+1]; // should calc GNU 8byte overhead.
36 strcpy(string, src.string);
40 assert(references == 0);
50 string = new char[maxlen + 1];
56 /** POST: maxlen >= j.
57 IN: j, maximum stringlength.
65 char *p = new char[maxlen + 1];
69 // length = strlen(string);
72 /** POST: maxlen >= j.
73 IN: j, maximum stringlength.
74 contents are kept if it grows.
76 /// check if writeable.
79 assert (references == 1);
85 assert(strlen(string) == size_t(length));
86 assert(maxlen >= length);
88 assert(references >= 1);
93 length = strlen (string);
96 /// reduce memory usage.
97 void tighten() { // should be dec'd const
99 char *p = new char[maxlen + 1];
106 void set(const char *s) {
117 void operator += (const char *s) {
124 strcpy(string + old, s);
128 operator const char *() const { return string; }
131 char *array_for_modify() {
137 assert(j >= 0 && j <= length);
142 /** not really safe. Can alter length without StringData knowing it.
144 char &operator [](int j) {
145 assert(j >= 0 && j <= length);
149 char operator [](int j) const {
150 assert(j >= 0 && j <= length);
156 the data itself. Handles simple tasks (resizing, resetting)
159 /****************************************************************/
160 /// ref. counting for strings
161 class String_handle {
164 /// decrease ref count. Named kind of like a Tanenbaum semafore
165 void down() { if (!(--data->references)) delete data; data = 0; }
167 /// increase ref count
168 void up(StringData *d) { data=d; data->references ++; }
170 /** make sure data has only one reference.
171 POST: data->references == 1
174 if (data->references !=1){
175 StringData *newdata = new StringData(*data);
189 String_handle(String_handle const & src) {
193 /// retrieve the actual array.
194 operator const char *() const { return *data; }
195 char *array_for_modify() {
197 return data->array_for_modify();
200 void operator =(String_handle const &src) {
207 void operator += (const char *s) {
213 char operator[](int j) const { return (*data)[j]; }
216 // don't use this for loops. Use array_for_modify()
217 char &operator[](int j) {
218 copy(); // hmm. Not efficient
219 return data->array_for_modify()[j];
222 void operator = (char const *p) {
227 void trunc(int j) { copy(); data->trunc(j); }
228 int len() const { return data->length; }
231 handles ref. counting, and provides a very thin
232 interface using char *
237 #if (NDEBUG == BLONDE)
244 #endif // STRINGUTIL_HH