modules/up/src/Core/util/Buffer.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- mymalloc
- myfree
- compress
- uncompress
- extend
- append
- appendf
- append
- insert
- flush
- makeString
- contains
- main
1 //
2 // $Id: Buffer.cc,v 1.1.1.1 2000/03/10 16:32:20 engin Exp $
3 //
4 // Author: Ramesh Govindan <govindan@isi.edu>
5 // Cengiz Alaettinoglu
6 // WeeSan Lee <wlee@isi.edu>
7 //
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <string.h>
14 #include <cstdio>
15 #include <cstdlib>
16 #include <cstdarg>
17 #include <cassert>
18 #include <iomanip.h>
19
20 #ifdef NEED_COMPRESSION
21 #include <zlib.h>
22 #include "util/Trail.hh"
23 #endif // NEED_COMPRESSION
24
25 #include "util/Buffer.hh"
26
27 #ifdef NEVER
28 int myallocCnt = 0;
29
30 static void *mymalloc(int opaque, int n, int sz) {
/* [<][>][^][v][top][bottom][index][help] */
31 myallocCnt++;
32 return malloc(n * sz);
33 }
34 static void myfree(int opaque, void *ptr) {
/* [<][>][^][v][top][bottom][index][help] */
35 printf("freeing\n");
36 myallocCnt--;
37 free(ptr);
38 }
39 #else
40 #define mymalloc 0
41 #define myfree 0
42 #endif // never
43
44 ostream &operator<<(ostream &os, const Buffer &b)
45 {
46 os << setw(b.getSize()) << b.getContents() << " (" << b.getSize() << ")";
47 return os;
48 }
49
50 Buffer*
51 Buffer::compress()
/* [<][>][^][v][top][bottom][index][help] */
52 {
53 #ifdef NEED_COMPRESSION
54 z_stream cp;
55 int err;
56 Buffer* nbuf;
57
58 // Need at most 1.1 * length for the decompressed buffer
59 nbuf = new Buffer((unsigned long) ((1.1 * size) + 12));
60
61 // Compress the incoming data
62 cp.zalloc = (alloc_func) mymalloc;
63 cp.zfree = (free_func) myfree;
64 cp.opaque = (voidpf) 0;
65
66 err = deflateInit(&cp, Z_BEST_COMPRESSION);
67 if (err != Z_OK) {
68 ERROR("zlib error %d while initializing stream\n", err);
69 delete nbuf;
70 return NULL;
71 }
72
73 cp.next_in = (unsigned char*) contents;
74 cp.avail_in = size;
75 cp.next_out = (unsigned char*) nbuf->contents;
76 cp.avail_out = nbuf->capacity;
77
78 err = deflate(&cp, Z_FINISH);
79 if (err != Z_STREAM_END) {
80 ERROR("zlib error %d when compressing data\n", err);
81 delete nbuf;
82 return NULL;
83 }
84
85 err = deflateEnd(&cp);
86 if (err != Z_OK) {
87 ERROR("zlib error %d when closing compression stream\n", err);
88 delete nbuf;
89 return NULL;
90 }
91
92 nbuf->size = cp.total_out;
93 return nbuf;
94 #else
95 return new Buffer(*this);
96 #endif
97 }
98
99 Buffer*
100 Buffer::uncompress()
/* [<][>][^][v][top][bottom][index][help] */
101 {
102 #ifdef NEED_COMPRESSION
103 z_stream decompress;
104 int error;
105 Buffer* nbuf;
106 unsigned int guess;
107
108 guess = size;
109 while (1) {
110 guess <<= 2;
111 nbuf = new Buffer(guess);
112
113 decompress.zalloc = (alloc_func) mymalloc;
114 decompress.zfree = (free_func) myfree;
115 decompress.opaque = (voidpf) 0;
116 decompress.next_in = (unsigned char*) contents;
117 decompress.avail_in = size;
118 decompress.next_out = (unsigned char*) nbuf->contents;
119 decompress.avail_out = nbuf->capacity;
120
121 error = inflateInit(&decompress);
122 if (error != Z_OK) {
123 ERROR("error number %d while initializing decompression stream\n",
124 error);
125 delete nbuf;
126 return NULL;
127 }
128
129 error = inflate(&decompress, Z_FINISH);
130 if (error == Z_STREAM_END) {
131 error = inflateEnd(&decompress);
132 if (error != Z_OK) {
133 ERROR("error number %d while closing decompression stream\n",
134 error);
135 delete nbuf;
136 return NULL;
137 }
138 nbuf->size = decompress.total_out;
139 return nbuf;
140 }
141 delete nbuf;
142 }
143 // Not Reached
144 #else
145 return new Buffer(*this);
146 #endif
147 }
148
149 void Buffer::extend(unsigned long minExtend) {
/* [<][>][^][v][top][bottom][index][help] */
150 assert(!callerAllocated); // !!!
151 capacity = (capacity + BufferExtendIncrement) >? (size + minExtend);
152 contents = (char *)realloc(contents, capacity);
153 }
154
155 void
156 Buffer::append(const char *buf, unsigned long sz)
/* [<][>][^][v][top][bottom][index][help] */
157 {
158 if (size + sz > capacity)
159 extend(sz);
160 memcpy(contents + size, buf, sz);
161 size += sz;
162 }
163
164 void Buffer::appendf(const char *format, ...) {
/* [<][>][^][v][top][bottom][index][help] */
165 if (size + BufferExtendIncrement / 2 > capacity)
166 extend();
167
168 va_list ap;
169
170 va_start(ap, format);
171 #ifdef HAVE_VSNPRINTF
172 (void) vsnprintf(contents + size, capacity - size, format, ap);
173 #else
174 (void) vsprintf(contents + size, format, ap);
175 #endif
176 va_end(ap);
177 size += strlen(contents + size);
178 }
179
180 void Buffer::append(Buffer &buf) {
/* [<][>][^][v][top][bottom][index][help] */
181 if (size + buf.size > capacity)
182 extend(buf.size);
183 memcpy(contents + size, buf.contents, buf.size);
184 size += buf.size;
185 }
186
187 void Buffer::insert(Buffer &buf, unsigned long atOffset = 0) {
/* [<][>][^][v][top][bottom][index][help] */
188 if (size + buf.size > capacity)
189 extend(buf.size);
190 memmove(contents + atOffset + buf.size,
191 contents + atOffset,
192 size - atOffset);
193 memcpy(contents + atOffset, buf.contents, buf.size);
194 size += buf.size;
195 }
196
197 void Buffer::flush(unsigned long sz, unsigned long atOffset) {
/* [<][>][^][v][top][bottom][index][help] */
198 if (sz == 0 || size == 0)
199 return;
200
201 assert(atOffset + sz <= size);
202
203 memcpy(contents + atOffset, contents + atOffset + sz, size - atOffset - sz);
204
205 size -= sz;
206 if (offset >= atOffset)
207 offset = (offset - sz) >? 0;
208 }
209
210 char *Buffer::makeString() const {
/* [<][>][^][v][top][bottom][index][help] */
211 char *str = (char *) malloc(size + 1);
212 strncpy(str, contents, size);
213 *(str + size) = 0;
214 return str;
215 }
216
217 bool Buffer::contains(const char *needle) { // search for needle in buffer
/* [<][>][^][v][top][bottom][index][help] */
218 if (capacity > size) {
219 *(contents + size) = 0;
220 return strstr(contents, needle);
221 }
222
223 char last = *(contents + size - 1);
224 *(contents + size - 1) = 0;
225
226 if (strstr(contents, needle)) {
227 *(contents + size - 1) = last;
228 return true;
229 }
230
231 char last2 = *(needle + strlen(needle) - 1);
232 if (last != last2) {
233 *(contents + size - 1) = last;
234 return false;
235 }
236
237 char *needle2 = strdup(needle);
238 *(needle2 + strlen(needle2) - 1) = 0;
239
240 if (strstr(contents + size - strlen(needle), needle2)) {
241 *(contents + size - 1) = last;
242 free(needle2);
243 return true;
244 }
245
246 *(contents + size - 1) = last;
247 free(needle2);
248 return false;
249 }
250
251 #ifdef BUFFER_MAIN
252
253 void main() {
/* [<][>][^][v][top][bottom][index][help] */
254 Buffer buf(4);
255
256 buf.append("foo", 3);
257
258 buf.contains("foo");
259 buf.contains("fo");
260 buf.contains("oo");
261 }
262
263 #endif // BUFFER_MAIN_DEBUG
264
265 //
266 // Copyright (c) 1994 by the University of Southern California.
267 // All rights reserved.
268 //
269 // Permission to use, copy, modify, and distribute this software and
270 // its documentation in source and binary forms for lawful
271 // non-commercial purposes and without fee is hereby granted, provided
272 // that the above copyright notice appear in all copies and that both
273 // the copyright notice and this permission notice appear in supporting
274 // documentation, and that any documentation, advertising materials,
275 // and other materials related to such distribution and use acknowledge
276 // that the software was developed by the University of Southern
277 // California and/or Information Sciences Institute.
278 // The name of the University of Southern California may not
279 // be used to endorse or promote products derived from this software
280 // without specific prior written permission.
281 //
282 // THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
283 // ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
284 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
285 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
286 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
287 // NON-INFRINGEMENT.
288 //
289 // IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
290 // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
291 // TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
292 // THE USE OR PERFORMANCE OF THIS SOFTWARE.
293 //
294 // Questions concerning this software should be directed to
295 // info-ra@isi.edu.
296 //
297 // Author(s): Ramesh Govindan <govindan@isi.edu>
298