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 void releaseSetLength(int new_length);
00087 int getAllocatedSize() const { return myAllocatedSize; }
00088
00089 void reserve(size_t bytes=0);
00090
00091
00092
00093
00094
00095 char operator()(int idx) const
00096 {
00097
00098
00099 UT_ASSERT_P(idx >= 0 && idx <= myLength);
00100 return myBuffer[idx];
00101 }
00102
00103
00104 int isNullTerminated() const;
00105
00106 private:
00107
00108
00109 void growBufferIfNeeded()
00110 {
00111
00112
00113
00114
00115 while (myLength+1 > myAllocatedSize)
00116 reserve(myAllocatedSize * 2);
00117 }
00118
00119 public:
00120
00121 void strcpy(const char *src)
00122 {
00123 clear();
00124 append(src);
00125 }
00126 void strcpy(const UT_WorkBuffer &src)
00127 {
00128 clear();
00129 append(src);
00130 }
00131
00132 void strncpy(const char *src, int maxlen)
00133 {
00134 clear();
00135
00136 myLength = maxlen+1;
00137 growBufferIfNeeded();
00138 myLength = 0;
00139 ::strncpy(myBuffer, src, maxlen);
00140
00141 myBuffer[maxlen] = 0;
00142 myLength = (int)::strlen(myBuffer);
00143 }
00144
00145
00146 int strlen() const
00147 {
00148 UT_ASSERT_P(isNullTerminated());
00149 return (int)::strlen(myBuffer);
00150 }
00151
00152 int length() const
00153 {
00154 return myLength;
00155 }
00156
00157 void strcat(const char *src)
00158 {
00159 append(src);
00160 }
00161
00162
00163
00164
00165 void protectedStrcat(const char *str, bool force_quote=false);
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 void fullyProtectedStrcat(const char *str, bool force_quote=false);
00176 void fullyProtectedBinaryStrcat(
00177 const char *str, int size, bool force_quote=false);
00178
00179 void strncat(const char *src, int len)
00180 {
00181 UT_ASSERT_P(isNullTerminated());
00182
00183 myLength += len+1;
00184 growBufferIfNeeded();
00185 myLength -= len+1;
00186 ::strncat(myBuffer, src, len);
00187 myLength = (int)::strlen(myBuffer);
00188 }
00189
00190
00191
00192
00193 void strcatFirstWord(const char *src);
00194
00195 int strcmp(const char *src) const
00196 {
00197 UT_ASSERT_P(isNullTerminated());
00198 return ::strcmp(myBuffer, src);
00199 }
00200
00201 int strncmp(const char *src, int n) const
00202 {
00203 UT_ASSERT_P(isNullTerminated());
00204 return ::strncmp(myBuffer, src, n);
00205 }
00206
00207 char *strdup() const
00208 {
00209 UT_ASSERT(isNullTerminated());
00210 return ::strdup(myBuffer);
00211 }
00212
00213
00214 void clear()
00215 {
00216 if (myLockCount) { UT_ASSERT(0); return; }
00217 myLength = 0;
00218 myBuffer[0] = '\0';
00219 }
00220
00221
00222
00223
00224 void write(int offset, char c)
00225 {
00226 UT_ASSERT(offset >= 0);
00227 if (offset < 0) return;
00228 if (offset >= myLength)
00229 {
00230 if (myLockCount) { UT_ASSERT(0); return; }
00231 myLength = offset+1;
00232 growBufferIfNeeded();
00233 myBuffer[myLength] = '\0';
00234 }
00235 myBuffer[offset] = c;
00236 if (c == '\0')
00237 myLength = offset;
00238 }
00239
00240
00241
00242 void write(int offset, const char *src)
00243 {
00244 while (*src)
00245 {
00246 write(offset, *src);
00247 src++;
00248 offset++;
00249 }
00250 }
00251
00252
00253
00254 bool getline(istream &is);
00255 bool getline(FILE *fp);
00256
00257
00258
00259
00260
00261
00262
00263 bool cmdGetLine(istream &is, UT_WorkArgs &args, int &line_num,
00264 const char *comment_chars = "#",
00265 const char *separators = " \t\n\r");
00266 bool cmdGetLine(UT_IStream &is, UT_WorkArgs &args, int &line_num,
00267 const char *comment_chars = "#",
00268 const char *separators = " \t\n\r");
00269 bool cmdGetLine(FILE *fp, UT_WorkArgs &args, int &line_num,
00270 const char *comment_chars = "#",
00271 const char *separators = " \t\n\r");
00272
00273 int sprintf(const char *fmt, ...)
00274 SYS_PRINTF_CHECK_ATTRIBUTE(2, 3);
00275 int appendSprintf(const char *fmt, ...)
00276 SYS_PRINTF_CHECK_ATTRIBUTE(2, 3);
00277
00278 int vsprintf(const char *fmt, va_list ap);
00279
00280
00281 void append(char character)
00282 {
00283 if (myLockCount) { UT_ASSERT(0); return; }
00284 UT_ASSERT_P(isNullTerminated());
00285 myLength++;
00286 growBufferIfNeeded();
00287 myBuffer[myLength - 1] = character;
00288 myBuffer[myLength] = '\0';
00289 }
00290
00291 void append(const char *data, int size)
00292 {
00293 if (myLockCount) { UT_ASSERT(0); return; }
00294 UT_ASSERT_P(data);
00295 UT_ASSERT_P(isNullTerminated());
00296 myLength += size;
00297 growBufferIfNeeded();
00298 ::memcpy(myBuffer + myLength - size, data, size);
00299 myBuffer[myLength] = '\0';
00300 }
00301
00302 void append(const char *str)
00303 {
00304 if( UTisstring(str) )
00305 append(str, (int)::strlen(str));
00306 }
00307
00308 void append(const UT_String &str)
00309 {
00310 if (str.isstring())
00311 append((const char *)str);
00312 }
00313
00314 void append(const UT_WorkBuffer &wb)
00315 {
00316 append( wb.buffer(), wb.length() );
00317 }
00318
00319 void prepend(char character)
00320 {
00321 if (myLockCount) { UT_ASSERT(0); return; }
00322 UT_ASSERT_P(isNullTerminated());
00323 myLength++;
00324 growBufferIfNeeded();
00325 ::memmove(myBuffer+1, myBuffer, myLength+1);
00326 myBuffer[0] = character;
00327 }
00328 void prepend(const char *data, int size)
00329 {
00330 if (myLockCount) { UT_ASSERT(0); return; }
00331 UT_ASSERT_P(data);
00332 UT_ASSERT_P(isNullTerminated());
00333 myLength += size;
00334 growBufferIfNeeded();
00335 ::memmove(myBuffer+size, myBuffer, myLength+1);
00336 ::memcpy(myBuffer, data, size);
00337 }
00338 void prepend(const char *str)
00339 {
00340 UT_ASSERT_P(str);
00341 prepend(str, (int)::strlen(str));
00342 }
00343
00344 void prepend(const UT_String &str)
00345 {
00346 if (str.isstring())
00347 prepend((const char *)str);
00348 }
00349
00350 void rewind() { backup(myLength); }
00351
00352 void backup(int by_length)
00353 {
00354 if (myLockCount) { UT_ASSERT(0); return; }
00355 UT_ASSERT_P(isNullTerminated());
00356 UT_ASSERT_P(by_length >= 0);
00357 myLength -= by_length;
00358 UT_ASSERT(myLength >= 0);
00359 myBuffer[myLength] = '\0';
00360 }
00361
00362
00363
00364 void backupTo(char c)
00365 {
00366 if (myLockCount) { UT_ASSERT(0); return; }
00367 UT_ASSERT_P(isNullTerminated());
00368 while( myLength > 0 && myBuffer[myLength-1] != c )
00369 myLength--;
00370 myBuffer[myLength] = '\0';
00371 }
00372
00373 void advance(int by_length)
00374 {
00375 if (myLockCount) { UT_ASSERT(0); return; }
00376 UT_ASSERT_P(isNullTerminated());
00377 UT_ASSERT_P(by_length >= 0);
00378 myLength -= by_length;
00379 UT_ASSERT(myLength >= 0);
00380 for (int i=0; i<myLength; i++)
00381 myBuffer[i] = myBuffer[by_length+i];
00382 myBuffer[myLength] = '\0';
00383 }
00384
00385 const char *findChar(char c, int occurance_number = 1) const
00386 {
00387
00388 if (myLockCount) { UT_ASSERT(0); return NULL; }
00389 UT_ASSERT_P(isNullTerminated());
00390 int i;
00391 for(i=0; i<myLength; i++)
00392 if(c == myBuffer[i])
00393 {
00394 occurance_number--;
00395 if(occurance_number <= 0)
00396 return myBuffer+i;
00397 }
00398 return NULL;
00399 }
00400
00401
00402
00403
00404 bool getNextToken(const char *(&string),
00405 const UT_String separators = " \t\n");
00406
00407
00408 void copyIntoString(UT_String &str);
00409
00410
00411
00412 void copyIntoString(char *str, int max_length);
00413
00414
00415
00416 std::string toStdString() const
00417 { return std::string(buffer(), length()); }
00418
00419
00420
00421
00422
00423 bool stripComments(char comment_char = '#');
00424
00425
00426 void removeTrailingSpaceLines();
00427
00428
00429 void lower();
00430
00431
00432 void upper();
00433
00434
00435 void makeIndentString(int indent, int tabstop=8);
00436
00437 private:
00438 friend UT_API ostream &operator<<(ostream &os,
00439 const UT_WorkBuffer &buffer);
00440
00441 private:
00442
00443 char *myBuffer;
00444 int myAllocatedSize;
00445 int myLength;
00446
00447 int myLockCount;
00448
00449 char myStackBuffer[UT_INITIAL_BUFFER_SIZE];
00450 };
00451
00452 #endif