modules/up/src/Core/util/Buffer.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. mymalloc
  2. myfree
  3. compress
  4. uncompress
  5. extend
  6. append
  7. appendf
  8. append
  9. insert
  10. flush
  11. makeString
  12. contains
  13. 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 

/* [<][>][^][v][top][bottom][index][help] */