00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __UT_WorkBuffer_h__
00035 #define __UT_WorkBuffer_h__
00036
00037 #include "UT_API.h"
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include <iostream.h>
00042 #include "UT_Assert.h"
00043 #include "UT_Defines.h"
00044 #include "UT_String.h"
00045
00046
00047
00048
00049
00050 #define UT_INITIAL_BUFFER_SIZE 2000
00051
00052 class UT_WorkArgs;
00053 class UT_IStream;
00054
00055 class UT_API UT_WorkBuffer
00056 {
00057 public:
00058 UT_WorkBuffer();
00059 ~UT_WorkBuffer();
00060
00061
00062
00063
00064 const char *buffer() const { return myBuffer; }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 char *lock(int offset = 0, size_t reserve_bytes=0);
00085 void release(int recomputeLength=0);
00086 int getAllocatedSize() const { return myAllocatedSize; }
00087
00088 void reserve(size_t bytes=0);
00089
00090
00091
00092
00093
00094 char operator()(int idx) const
00095 {
00096
00097
00098 UT_ASSERT_P(idx >= 0 && idx <= myLength);
00099 return myBuffer[idx];
00100 }
00101
00102
00103 int isNullTerminated() const;
00104
00105 private:
00106
00107
00108 void growBufferIfNeeded()
00109 {
00110
00111
00112
00113
00114 while (myLength+1 > myAllocatedSize)
00115 reserve(myAllocatedSize * 2);
00116 }
00117
00118 public:
00119
00120 void strcpy(const char *src)
00121 {
00122 clear();
00123 append(src);
00124 }
00125 void strcpy(const UT_WorkBuffer &src)
00126 {
00127 clear();
00128 append(src);
00129 }
00130
00131 void strncpy(const char *src, int maxlen)
00132 {
00133 clear();
00134
00135 myLength = maxlen+1;
00136 growBufferIfNeeded();
00137 myLength = 0;
00138 ::strncpy(myBuffer, src, maxlen);
00139
00140 myBuffer[maxlen] = 0;
00141 myLength = (int)::strlen(myBuffer);
00142 }
00143
00144
00145 int strlen() const
00146 {
00147 UT_ASSERT_P(isNullTerminated());
00148 return (int)::strlen(myBuffer);
00149 }
00150
00151 int length() const
00152 {
00153 return myLength;
00154 }
00155
00156 void strcat(const char *src)
00157 {
00158 append(src);
00159 }
00160
00161
00162
00163 void protectedStrcat(const char *str, bool forcequote=false);
00164
00165 void strncat(const char *src, int len)
00166 {
00167 UT_ASSERT_P(isNullTerminated());
00168
00169 myLength += len+1;
00170 growBufferIfNeeded();
00171 myLength -= len+1;
00172 ::strncat(myBuffer, src, len);
00173 myLength = (int)::strlen(myBuffer);
00174 }
00175
00176
00177
00178
00179 void strcatFirstWord(const char *src);
00180
00181 int strcmp(const char *src) const
00182 {
00183 UT_ASSERT_P(isNullTerminated());
00184 return ::strcmp(myBuffer, src);
00185 }
00186
00187 int strncmp(const char *src, int n) const
00188 {
00189 UT_ASSERT_P(isNullTerminated());
00190 return ::strncmp(myBuffer, src, n);
00191 }
00192
00193 char *strdup() const
00194 {
00195 UT_ASSERT(isNullTerminated());
00196 return ::strdup(myBuffer);
00197 }
00198
00199
00200 void clear()
00201 {
00202 if (myLockCount) { UT_ASSERT(0); return; }
00203 myLength = 0;
00204 myBuffer[0] = '\0';
00205 }
00206
00207
00208
00209
00210 void write(int offset, char c)
00211 {
00212 UT_ASSERT(offset >= 0);
00213 if (offset < 0) return;
00214 if (offset >= myLength)
00215 {
00216 if (myLockCount) { UT_ASSERT(0); return; }
00217 myLength = offset+1;
00218 growBufferIfNeeded();
00219 myBuffer[myLength] = '\0';
00220 }
00221 myBuffer[offset] = c;
00222 if (c == '\0')
00223 myLength = offset;
00224 }
00225
00226
00227
00228 void write(int offset, const char *src)
00229 {
00230 while (*src)
00231 {
00232 write(offset, *src);
00233 src++;
00234 offset++;
00235 }
00236 }
00237
00238
00239
00240 bool getline(istream &is);
00241 bool getline(FILE *fp);
00242
00243
00244
00245
00246
00247
00248
00249 bool cmdGetLine(istream &is, UT_WorkArgs &args, int &line_num,
00250 const char *comment_chars = "#",
00251 const char *separators = " \t\n\r");
00252 bool cmdGetLine(UT_IStream &is, UT_WorkArgs &args, int &line_num,
00253 const char *comment_chars = "#",
00254 const char *separators = " \t\n\r");
00255 bool cmdGetLine(FILE *fp, UT_WorkArgs &args, int &line_num,
00256 const char *comment_chars = "#",
00257 const char *separators = " \t\n\r");
00258
00259 int sprintf(const char *fmt, ...)
00260 SYS_PRINTF_CHECK_ATTRIBUTE(2, 3);
00261 int appendSprintf(const char *fmt, ...)
00262 SYS_PRINTF_CHECK_ATTRIBUTE(2, 3);
00263
00264 int vsprintf(const char *fmt, va_list ap);
00265
00266
00267 void append(char character)
00268 {
00269 if (myLockCount) { UT_ASSERT(0); return; }
00270 UT_ASSERT_P(isNullTerminated());
00271 myLength++;
00272 growBufferIfNeeded();
00273 myBuffer[myLength - 1] = character;
00274 myBuffer[myLength] = '\0';
00275 }
00276
00277 void append(const char *data, int size)
00278 {
00279 if (myLockCount) { UT_ASSERT(0); return; }
00280 UT_ASSERT_P(data);
00281 UT_ASSERT_P(isNullTerminated());
00282 myLength += size;
00283 growBufferIfNeeded();
00284 ::memcpy(myBuffer + myLength - size, data, size);
00285 myBuffer[myLength] = '\0';
00286 }
00287
00288 void append(const char *str)
00289 {
00290 if( UTisstring(str) )
00291 append(str, (int)::strlen(str));
00292 }
00293
00294 void append(const UT_String &str)
00295 {
00296 if (str.isstring())
00297 append((const char *)str);
00298 }
00299
00300 void append(const UT_WorkBuffer &wb)
00301 {
00302 append( wb.buffer(), wb.length() );
00303 }
00304
00305 void prepend(char character)
00306 {
00307 if (myLockCount) { UT_ASSERT(0); return; }
00308 UT_ASSERT_P(isNullTerminated());
00309 myLength++;
00310 growBufferIfNeeded();
00311 ::memmove(myBuffer+1, myBuffer, myLength+1);
00312 myBuffer[0] = character;
00313 }
00314 void prepend(const char *data, int size)
00315 {
00316 if (myLockCount) { UT_ASSERT(0); return; }
00317 UT_ASSERT_P(data);
00318 UT_ASSERT_P(isNullTerminated());
00319 myLength += size;
00320 growBufferIfNeeded();
00321 ::memmove(myBuffer+size, myBuffer, myLength+1);
00322 ::memcpy(myBuffer, data, size);
00323 }
00324 void prepend(const char *str)
00325 {
00326 UT_ASSERT_P(str);
00327 prepend(str, (int)::strlen(str));
00328 }
00329
00330 void prepend(const UT_String &str)
00331 {
00332 if (str.isstring())
00333 prepend((const char *)str);
00334 }
00335
00336 void rewind() { backup(myLength); }
00337
00338 void backup(int by_length)
00339 {
00340 if (myLockCount) { UT_ASSERT(0); return; }
00341 UT_ASSERT_P(isNullTerminated());
00342 UT_ASSERT_P(by_length >= 0);
00343 myLength -= by_length;
00344 UT_ASSERT(myLength >= 0);
00345 myBuffer[myLength] = '\0';
00346 }
00347
00348
00349
00350 void backupTo(char c)
00351 {
00352 if (myLockCount) { UT_ASSERT(0); return; }
00353 UT_ASSERT_P(isNullTerminated());
00354 while( myLength > 0 && myBuffer[myLength-1] != c )
00355 myLength--;
00356 myBuffer[myLength] = '\0';
00357 }
00358
00359 void advance(int by_length)
00360 {
00361 if (myLockCount) { UT_ASSERT(0); return; }
00362 UT_ASSERT_P(isNullTerminated());
00363 UT_ASSERT_P(by_length >= 0);
00364 myLength -= by_length;
00365 UT_ASSERT(myLength >= 0);
00366 for (int i=0; i<myLength; i++)
00367 myBuffer[i] = myBuffer[by_length+i];
00368 myBuffer[myLength] = '\0';
00369 }
00370
00371 const char *findChar(char c, int occurance_number = 1) const
00372 {
00373
00374 if (myLockCount) { UT_ASSERT(0); return NULL; }
00375 UT_ASSERT_P(isNullTerminated());
00376 int i;
00377 for(i=0; i<myLength; i++)
00378 if(c == myBuffer[i])
00379 {
00380 occurance_number--;
00381 if(occurance_number <= 0)
00382 return myBuffer+i;
00383 }
00384 return NULL;
00385 }
00386
00387
00388
00389
00390 bool getNextToken(const char *(&string),
00391 const UT_String separators = " \t\n");
00392
00393
00394 void copyIntoString(UT_String &str);
00395
00396
00397
00398 void copyIntoString(char *str, int max_length);
00399
00400
00401
00402
00403
00404 bool stripComments(char comment_char = '#');
00405
00406
00407 void removeTrailingSpaceLines();
00408
00409 private:
00410 friend UT_API ostream &operator<<(ostream &os,
00411 const UT_WorkBuffer &buffer);
00412
00413 private:
00414
00415 char *myBuffer;
00416 int myAllocatedSize;
00417 int myLength;
00418
00419 int myLockCount;
00420
00421 char myStackBuffer[UT_INITIAL_BUFFER_SIZE];
00422 };
00423
00424 #endif