00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef StreamBuffer_h
00021 #define StreamBuffer_h
00022
00023 #include <string.h>
00024 #include <stdio.h>
00025
00026 #ifndef __GNUC__
00027 #define __attribute__(x)
00028 #endif
00029
00030 class StreamBuffer
00031 {
00032 char local[64];
00033 long len;
00034 long cap;
00035 long offs;
00036 char* buffer;
00037
00038 void init(const void* s, long minsize);
00039
00040 void check(long size)
00041 {if (len+offs+size >= cap) grow(len+size);}
00042
00043 void grow(long minsize);
00044
00045 public:
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 StreamBuffer()
00056 {init(NULL, 0);}
00057
00058 StreamBuffer(const void* s, long size)
00059 {init(s, size);}
00060
00061 StreamBuffer(const char* s)
00062 {init(s, s?strlen(s):0);}
00063
00064 StreamBuffer(const StreamBuffer& s)
00065 {init(s.buffer+s.offs, s.len);}
00066
00067 StreamBuffer(long size)
00068 {init(NULL, size);}
00069
00070 ~StreamBuffer()
00071 {if (buffer != local) delete buffer;}
00072
00073
00074 const char* operator()(long index=0) const
00075 {return buffer+offs+(index<0?index+len:index);}
00076
00077 char* operator()(long index=0)
00078 {return buffer+offs+(index<0?index+len:index);}
00079
00080
00081 char operator[](long index) const
00082 {return buffer[offs+(index<0?index+len:index)];}
00083
00084 char& operator[](long index)
00085 {return buffer[offs+(index<0?index+len:index)];}
00086
00087
00088 operator bool() const
00089 {return len>0;}
00090
00091
00092 long length() const
00093 {return len;}
00094
00095
00096 long capacity() const
00097 {return cap-1;}
00098
00099
00100 const char* end() const
00101 {return buffer+offs+len;}
00102
00103
00104 StreamBuffer& clear()
00105 {offs+=len; len=0; return *this;}
00106
00107
00108
00109 char* reserve(long size)
00110 {check(size); char* p=buffer+offs+len; len+=size; return p;}
00111
00112
00113 StreamBuffer& append(char c)
00114 {check(1); buffer[offs+len++]=c; return *this;}
00115
00116 StreamBuffer& append(char c, long count)
00117 {if (count < 0) truncate(count);
00118 else {check(count); memset(buffer+offs+len, c, count); len+=count;}
00119 return *this;}
00120
00121 StreamBuffer& append(const void* s, long size);
00122
00123 StreamBuffer& append(const char* s)
00124 {return append(s, s?strlen(s):0);}
00125
00126 StreamBuffer& append(const StreamBuffer& s)
00127 {return append(s.buffer+s.offs, s.len);}
00128
00129
00130 StreamBuffer& operator+=(char c)
00131 {return append(c);}
00132
00133 StreamBuffer& operator+=(const char* s)
00134 {return append(s);}
00135
00136 StreamBuffer& operator+=(const StreamBuffer& s)
00137 {return append(s);}
00138
00139
00140 StreamBuffer& set(const void* s, long size)
00141 {clear(); return append(s, size);}
00142
00143 StreamBuffer& set(const char* s)
00144 {clear(); return append(s, s?strlen(s):0);}
00145
00146 StreamBuffer& set(const StreamBuffer& s)
00147 {clear(); return append(s.buffer+s.offs, s.len);}
00148
00149
00150 StreamBuffer& operator=(const char* s)
00151 {return set(s);}
00152
00153 StreamBuffer& operator=(const StreamBuffer& s)
00154 {return set(s);}
00155
00156
00157 StreamBuffer& replace(
00158 long pos, long length, const void* s, long size);
00159
00160 StreamBuffer& replace(long pos, long length, const char* s)
00161 {return replace(pos, length, s, s?strlen(s):0);}
00162
00163 StreamBuffer& replace(long pos, long length, const StreamBuffer& s)
00164 {return replace(pos, length, s.buffer+s.offs, s.len);}
00165
00166
00167 StreamBuffer& remove(long pos, long length)
00168 {return replace(pos, length, NULL, 0);}
00169
00170
00171 StreamBuffer& remove(long length)
00172 {if (length>len) length=len;
00173 offs+=length; len-=length; return *this;}
00174
00175
00176 StreamBuffer& truncate(long pos)
00177 {return replace(pos, len, NULL, 0);}
00178
00179
00180 StreamBuffer& insert(long pos, const void* s, long size)
00181 {return replace(pos, 0, s, size);}
00182
00183 StreamBuffer& insert(long pos, const char* s)
00184 {return replace(pos, 0, s, s?strlen(s):0);}
00185
00186 StreamBuffer& insert(long pos, const StreamBuffer& s)
00187 {return replace(pos, 0, s.buffer+s.offs, s.len);}
00188
00189 StreamBuffer& insert(long pos, char c)
00190 {return replace(pos, 0, &c, 1);}
00191
00192 StreamBuffer& printf(const char* fmt, ...)
00193 __attribute__ ((format(printf,2,3)));
00194
00195
00196 long find(char c, long start=0) const
00197 {char* p;
00198 return (p = static_cast<char*>(
00199 memchr(buffer+offs+(start<0?start+len:start),
00200 c, start<0?-start:len-start)))?
00201 p-(buffer+offs) : -1;}
00202
00203 long find(const void* s, long size, long start=0) const;
00204
00205 long find(const char* s, long start=0) const
00206 {return find(s, s?strlen(s):0, start);}
00207
00208 long int find(const StreamBuffer& s, long start=0) const
00209 {return find(s.buffer+s.offs, s.len, start);}
00210
00211
00212 bool startswith(const void* s, long size) const
00213 {return len>=size ? memcmp(buffer+offs, s, size) == 0 : false;}
00214
00215
00216 bool startswith(const char* s) const
00217 {return len ? strcmp(buffer+offs, s) == 0 : !s || !*s;}
00218
00219
00220
00221 StreamBuffer expand(long start, long length) const;
00222
00223 StreamBuffer expand(long start=0) const
00224 {return expand(start, len);}
00225
00226
00227
00228 StreamBuffer dump() const;
00229 };
00230
00231 #endif