Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Copyright 1995, Brown University, Providence, RI
3
 *
4
 * Permission to use and modify this software and its documentation for
5
 * any purpose other than its incorporation into a commercial product is
6
 * hereby granted without fee.  Permission to copy and distribute this
7
 * software and its documentation only for non-commercial use is also
8
 * granted without fee, provided, however, that the above copyright notice
9
 * appear in all copies, that both that copyright notice and this permission
10
 * notice appear in supporting documentation, that the name of Brown
11
 * University not be used in advertising or publicity pertaining to
12
 * distribution of the software without specific, written prior permission,
13
 * and that the person doing the distribution notify Brown University of
14
 * such distributions outside of his or her organization. Brown University
15
 * makes no representations about the suitability of this software for
16
 * any purpose.  It is provided "as is" without express or implied warranty.
17
 * Brown University requests notification of any modifications to this
18
 * software or its documentation.
19
 *
20
 * Send the following redistribution information:
21
 *
22
 *      Name:
23
 *      Organization:
24
 *      Address (postal and/or electronic):
25
 *
26
 * To:
27
 *      Software Librarian
28
 *      Computer Science Department, Box 1910
29
 *      Brown University
30
 *      Providence, RI 02912
31
 *
32
 *              or
33
 *
34
 *      brusd@cs.brown.edu
35
 *
36
 * We will acknowledge all electronic notifications.
37
 */
38
 
39
#include "buffer.H"
40
#include <stdlib.h>
41
#include <string.h>
42
#include <assert.h>
43
#include <stdio.h>
44
 
45
long BUFFER::totalAllocated=0;
46
 
47
// Constructor
48
//     Default:  bytesGet=4, bytesSave=3, stepSize=25
49
//
50
BUFFER::BUFFER(int itemSize, int bytesGet, int bytesSave,int stepSize)
51
:
52
     _size(0),
53
     bufferSize(stepSize),
54
     location(0),
55
     firstRetrieve(1),
56
     _bytesGet(bytesGet),
57
     _bytesSave(bytesSave),
58
     _stepSize(stepSize),
59
     sizeGet(itemSize),
60
     sizeSave(itemSize),
61
     tmpBlock(NULL)
62
{
63
        buffer=new char*[stepSize];
64
        if (!buffer) {
65
                // Should not die, but return a result code...
66
                bufferSize=0;
67
                return;
68
        }
69
 
70
        // Should add checking for bytesSave, bytesGet
71
        // only supported value for bytesGet [4]
72
        // only supported value for bytesSave [3,4]
73
 
74
        //Initialize pointers to buffer blocks
75
        for (int i=0;i<stepSize;i++) {
76
                buffer[i]=NULL;
77
        }
78
 
79
        //If we are trying to compress
80
        if (bytesGet!=bytesSave) {
81
                sizeSave=sizeGet/bytesGet*bytesSave;
82
                tmpBlock=(char *) malloc(sizeGet);
83
        }
84
}
85
 
86
// Destructor
87
//
88
//
89
BUFFER::~BUFFER()
90
{
91
        if (tmpBlock) free(tmpBlock);
92
        for (int i=0;i<_size;i++) {
93
           free(buffer[i]);
94
        }
95
        delete [] buffer;
96
}
97
 
98
// addToBuffer
99
//    buffer an item, compressing if need be
100
//
101
int
102
BUFFER::addToBuffer(void *item)
103
{
104
        // Enlarge the buffer if need be
105
        if (_size>=bufferSize) {
106
           int oldSize=bufferSize;
107
           bufferSize+=_stepSize;
108
           char **tmpBuffer=buffer;
109
           buffer=(char **) realloc(buffer,sizeof(char *)*bufferSize);
110
           if (!buffer) {
111
               //can't get more memory
112
               //set buffer to point to old buffer;
113
               buffer=tmpBuffer;
114
               bufferSize=oldSize;
115
               return 0;
116
           }
117
           for (int i=oldSize;i<bufferSize;i++) {
118
               buffer[i]=NULL;
119
           }
120
        }
121
        if ( !(buffer[_size]=(char *)malloc(sizeGet)) ) {
122
               //can't get more memory
123
               return 0;
124
        }
125
        if (sizeGet==sizeSave) {
126
           // No compressing, straight copy
127
           memcpy(buffer[_size],item,sizeGet);
128
        } else {
129
           // Compressing, copy 3 out of 4 bytes
130
           char *ptrTo, *ptrFrom;
131
           int x;
132
           for (ptrTo=buffer[_size],ptrFrom=(char *) item,x=0;
133
                x<sizeGet;
134
                ptrFrom+=_bytesGet,ptrTo+=_bytesSave,x+=_bytesGet) {
135
                *(ptrTo+0)=*(ptrFrom+3);
136
                *(ptrTo+1)=*(ptrFrom+2);
137
                *(ptrTo+2)=*(ptrFrom+1);
138
           }
139
        }
140
        _size++;
141
        return 1;
142
}
143
 
144
const char * const BUFFER::nextBufferItem(int *looped)
145
{
146
        int tmpLoc=location;
147
 
148
        // If first time we are retrieving
149
        if (firstRetrieve) {
150
           // shrink buffer array down to size
151
           char **oldLoc=buffer;
152
           buffer=(char **) realloc(buffer,sizeof(char*)*_size);  
153
           if (!buffer) {
154
                //since we are shortening the size of a memory block
155
                //  we shouldn't get here...
156
                buffer=oldLoc;
157
           }
158
           firstRetrieve=0;
159
           long allocated=sizeSave * _size;
160
 
161
           printf("Data allocated for buffer: %d (%dk)\n",
162
              allocated, (int) allocated/1024);
163
           totalAllocated+=allocated;
164
           printf("Running total: %d (%dk)\n",
165
              totalAllocated, (int) totalAllocated/1024);
166
        }
167
 
168
        location++;
169
 
170
        //Tell the caller if we have looped around
171
        if (looped) {
172
                *looped  =(location==_size);
173
        }
174
 
175
        location %= _size;
176
        if (_bytesGet==_bytesSave) {
177
           // No compressing, straight return
178
           return buffer[tmpLoc];
179
        } else {
180
           // Compressing, copy 3 out of 4 bytes
181
           char *ptrTo, *ptrFrom;
182
           int x;
183
           for (ptrTo=tmpBlock,ptrFrom=buffer[tmpLoc],x=0;
184
                x<sizeGet;ptrFrom+=_bytesSave,ptrTo+=_bytesGet,x+=_bytesGet) {
185
                *(ptrTo+3)=*(ptrFrom+0);
186
                *(ptrTo+2)=*(ptrFrom+1);
187
                *(ptrTo+1)=*(ptrFrom+2);
188
           }
189
           return tmpBlock;
190
        }
191
}