00001 /* /% C++ %/ */ 00002 /*********************************************************************** 00003 * cint (C/C++ interpreter) 00004 ************************************************************************ 00005 * Source file FastAllocString.h 00006 ************************************************************************ 00007 * Description: 00008 * String object with fast allocation (pooled memory) 00009 ************************************************************************ 00010 * Copyright(c) 1995~2009 Masaharu Goto 00011 * 00012 * For the licensing terms see the file COPYING 00013 * 00014 ************************************************************************/ 00015 00016 #ifndef G__FASTALLOGSTRING_H 00017 #define G__FASTALLOGSTRING_H 00018 00019 #include <stdarg.h> 00020 #include <stddef.h> 00021 00022 // For G__EXPORT 00023 #include "G__ci.h" 00024 00025 namespace Cint { 00026 namespace Internal { 00027 class G__BufferReservoir; 00028 } 00029 } 00030 00031 //_____________________________________________________________ 00032 // 00033 // A tiny object representing a char array. 00034 // Create it with the desired size of the char array and it 00035 // will try to retrieve a previsouly allocated buffer from 00036 // an internal resrevoir of buffers, or allocate a new one 00037 // if none is available. This is a lot faster than mallocs / 00038 // free calls for each char array, and it considerably reduces 00039 // the used stack size by functions previsouly using static 00040 // size, stack based chart arrays. It also allows to make the 00041 // buffer size dynamic, adopted e.g. to strlen(expression), 00042 // instead of a value defined at compile time (a la G__LONGBUF). 00043 // When the G__FastAllocString object leaves the scope it will put its 00044 // buffer (back) into the internal buffer reservoir for later 00045 // use by a G__FastAllocString object requesting a same of smaller size 00046 // buffer. This class is optimized for both speed and low memory 00047 // use despite the reservoir. 00048 // 00049 class 00050 #ifndef __CINT__ 00051 G__EXPORT 00052 #endif 00053 G__FastAllocString { 00054 public: 00055 G__FastAllocString(int reqsize = 1024): fBuf(0), fCapacity(reqsize) { 00056 // GetBuf takes as parameter the size in bytes 00057 // and modify the parameter (fBucket) to hold the 00058 // bucket number. 00059 fBuf = GetBuf(fCapacity); 00060 } 00061 G__FastAllocString(const char* s); 00062 G__FastAllocString(const G__FastAllocString&); 00063 00064 ~G__FastAllocString(); 00065 00066 // plenty of char* conversion functions: 00067 operator char*() { return fBuf; } 00068 operator const char*() const { return fBuf; } 00069 const char* operator()() const { return fBuf; } 00070 00071 // DON'T: these create ambiguities with ::op[char*, int] etc 00072 //char& operator[](int i) { return fBuf[i]; } 00073 //char operator[](int i) const { return fBuf[i]; } 00074 //char* operator+(int i) { return fBuf + i; } 00075 //const char* operator+(int i) const { return fBuf + i; } 00076 00077 const char* data() const { return fBuf; } 00078 00079 int FormatArgList(const char *fmt, va_list args); 00080 int FormatArgList(size_t offset, const char *fmt, va_list args); 00081 G__FastAllocString& Format(const char *fmt, ...); 00082 G__FastAllocString& Format(size_t offset, const char *fmt, ...); 00083 00084 size_t Capacity() const { return fCapacity; } 00085 00086 G__FastAllocString& operator=(const G__FastAllocString& s) { 00087 // Copy s into *this. 00088 // Cannot rely on operator=(const char*) overload - compiler-generated one wins resolution! 00089 return operator=(s.data()); 00090 } 00091 G__FastAllocString& operator=(const char*); 00092 G__FastAllocString& operator+=(const char*); 00093 G__FastAllocString& Swap(G__FastAllocString&); 00094 void Resize(size_t cap); 00095 00096 void Set(size_t pos, char c) { 00097 // Set character at position pos to c; resize if needed. 00098 Resize(pos + 1); 00099 fBuf[pos] = c; 00100 } 00101 /* 00102 size_t Set(size_t& pos, const char* s) { 00103 // Overwrite string at position pos with s; resize if needed. 00104 // Return pos incremented by strlen(s) 00105 size_t len = strlen(s); 00106 Resize(pos + len + 1); 00107 memcpy(fBuf + pos, s, len + 1); 00108 return pos + len; 00109 }*/ 00110 00111 void Replace(size_t where, const char *replacement); 00112 00113 protected: 00114 static char* GetBuf(size_t &size); 00115 00116 void ResizeToBucketNoCopy(int newbucket); 00117 void ResizeNoCopy(size_t cap); 00118 00119 private: 00120 char* fBuf; // the buffer 00121 size_t fCapacity; // measure representing the buffer's size, used by the internal reservoir 00122 }; 00123 00124 // Those 6 functions are intentionally not implemented as their are 'illegal' 00125 // and we should call the equivalent member function instead. 00126 void G__strlcpy(G__FastAllocString&, const char *, size_t); 00127 void G__strlcat(G__FastAllocString&, const char *, size_t); 00128 void G__snprintf(G__FastAllocString&, size_t, const char *, ...); 00129 void strcpy(G__FastAllocString&, const char *); 00130 void strcat(G__FastAllocString&, const char *); 00131 void sprintf(G__FastAllocString&, const char *, ...); 00132 00133 #endif // G__FASTALLOGSTRING_H