## 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] */