~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to prim/tc3/libsrc/buffer.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 1987-2009 European Southern Observatory (ESO)
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Correspondence concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
29
.TYPE           Module
 
30
.IDENTIFICATION buffer.c
 
31
.AUTHOR         Francois Ochsenbein [ESO-IPG]
 
32
.LANGUAGE       C
 
33
.KEYWORDS       Buffer / Stack Management
 
34
.ENVIRONMENT    
 
35
.COMMENTS
 
36
        These routines allow the management of buffers defined
 
37
        as the following BUFFER structure:
 
38
\begin{TeX}
 
39
\begin{itemize}
 
40
\item   {\tt char *buf} is the address of the buffer in memory
 
41
\item   {\tt int allocated}     is the number of bytes allocated to buf
 
42
\item   {\tt int used}  is the present number of bytes used in this
 
43
                buffer
 
44
\item   {\tt int increment}     is the number of bytes for automatic expansions
 
45
\item   {\tt offset}    is an integer, \eg
 
46
                to perform some searches. It is used for stacking and unstacking.
 
47
\end{itemize}
 
48
\end{TeX}
 
49
.VERSION 1.0    03-Feb-1987: Creation
 
50
.VERSION 1.1    20-May-1987: Removed bug in mm_set
 
51
.VERSION 2.0    20-Apr-1988: Changed function names, added stacking facilities.
 
52
.VERSION 2.1    01-Jun-1988: Added mm_zloc (retrieve a zero item),
 
53
                        mm_zindex (retrieve non-zero item)
 
54
                        mm_zfree (free the index)
 
55
.VERSION 2.2    07-Nov-1988: Removed bug in mm_bunst
 
56
.VERSION 2.3    07-Jun-1991: Be sure an EOS is appended in mm_bapp
 
57
 
 
58
 090831         last modif
 
59
----------------------------------------------------------------------------*/
 
60
 
 
61
#define DEBUG           0       /* For debugging purposes       */
 
62
 
 
63
#if DEBUG
 
64
#define PM_LEVEL        LEVEL_STR
 
65
#endif
 
66
 
 
67
#define  PASCAL_DEF     0       /* Don't include pascalisation ... */
 
68
 
 
69
#include <midas_def.h>  /* Standard Definitions */
 
70
#include <stesodef.h>   /* Standard Definitions */
 
71
#include <buffer.h>
 
72
 
 
73
 
 
74
extern int mm_free(), eh_put1(), eh_ed_i();
 
75
 
 
76
 
 
77
 
 
78
#define FINISH          goto FIN
 
79
 
 
80
/*==========================================================================*/
 
81
BUFFER *mm_bopen(size, incr)    
 
82
/*+++
 
83
.PURPOSE Allocation of a buffer of a given size
 
84
.RETURNS Address of allocated buffer, or NULL address if failed,
 
85
.REMARKS If incr is zero, the buffer cannot be automatically expanded.
 
86
-------*/
 
87
        int     size;   /* IN: The required size (bytes)        */
 
88
        int     incr;   /* IN: The increment size for expansion (bytes) */
 
89
{
 
90
        register BUFFER *b;
 
91
 
 
92
  ENTER("*mm_bopen");
 
93
 
 
94
  if (size < 0)         size = 0;
 
95
  b = MEM_GET(BUFFER,1);
 
96
  b->buf        = NULL_PTR(char);
 
97
  b->allocated  = size;
 
98
  b->used       = 0;
 
99
  b->increment  = (incr > 0 ? incr : 0);
 
100
  b->offset     = 0;
 
101
 
 
102
  if (b->allocated)
 
103
        b->buf = MEM_GET(char, b->allocated);
 
104
 
 
105
  EXIT_PTR(BUFFER, b);
 
106
}  
 
107
 
 
108
/*==========================================================================*/
 
109
int     mm_bfree(b)    
 
110
/*+++
 
111
.PURPOSE Free a BUFFER structure --- but ONLY the buffer!
 
112
.RETURNS OK
 
113
.REMARKS 
 
114
---*/
 
115
        BUFFER  *b;     /* IN: The buffer to free       */
 
116
{
 
117
 
 
118
  ENTER("mm_bfree");
 
119
 
 
120
  if (b)
 
121
  {     MEM_FREE(b->buf);
 
122
        b->buf          = NULL_PTR(char);
 
123
        b->allocated    = 0;
 
124
        b->used         = 0;
 
125
        b->offset       = 0;
 
126
  }
 
127
 
 
128
  EXIT(OK);
 
129
}  
 
130
 
 
131
/*==========================================================================*/
 
132
int mm_bexp(b, size)    
 
133
/*+++
 
134
.PURPOSE Expansion of a buffer
 
135
.RETURNS OK (1)/ NOK(0)
 
136
.REMARKS Size of zero implies "use increment"
 
137
---*/
 
138
        BUFFER *b;      /* IN: The Buffer to Expand             */
 
139
        int     size;   /* IN: The required new size (bytes)    */
 
140
{
 
141
        register char *p;
 
142
        int new_size, status;
 
143
        
 
144
  ENTER("mm_bexp");
 
145
 
 
146
  new_size = (size > 0 ? size : b->allocated + b->increment);
 
147
 
 
148
  p = MEM_EXP(char, b->buf, new_size);
 
149
  if (p)        b->allocated = new_size, b->buf = p, status = OK;
 
150
  else          status = NOK;
 
151
 
 
152
  EXIT(status);
 
153
}
 
154
 
 
155
/*==========================================================================*/
 
156
char *mm_bst(b, record, len)    
 
157
/*+++
 
158
.PURPOSE Stack a record into buffer --- The buffer is
 
159
        expanded if necessary
 
160
.RETURNS Address of stacked record / NULL if error
 
161
.REMARKS Save offset of previous stacked values.
 
162
---*/
 
163
        BUFFER  *b;             /* IN: The buffer to free       */
 
164
        char    *record;        /* IN: record to append         */
 
165
        int     len;            /* IN: Length of record         */
 
166
{
 
167
        char    *a;
 
168
        
 
169
  ENTER("*mm_bst");
 
170
  
 
171
  a = mm_ball(b, len + sizeof(int));
 
172
  if (a)
 
173
  {     a += oscopy(a, (char *)(&(b->offset)), sizeof(int));
 
174
        b->offset = a - b->buf;
 
175
        oscopy(a, record, len);
 
176
  }
 
177
 
 
178
  EXITp(a);
 
179
}
 
180
 
 
181
/*==========================================================================*/
 
182
char *mm_bunst(b)
 
183
/*+++
 
184
.PURPOSE Unstack a record from buffer.
 
185
.RETURNS Address of record / NULL
 
186
.REMARKS 
 
187
---*/
 
188
        BUFFER  *b;             /* IN: The buffer to free       */
 
189
{
 
190
        char    *p;
 
191
        
 
192
  ENTER("*mm_bunst");
 
193
  
 
194
  if (b->used <= 0)     p = NULL_PTR(char);
 
195
  else
 
196
  {     b->used = b->offset - sizeof(int);
 
197
        oscopy((char *)(&(b->offset)), b->buf + b->used, sizeof(int));
 
198
        if (b->used <= 0)       p = NULL_PTR(char);
 
199
        else                    p = b->buf + b->offset;
 
200
  }
 
201
 
 
202
  EXITp(p);
 
203
}
 
204
 
 
205
/*==========================================================================*/
 
206
char *mm_bapp(b, record, len)    
 
207
/*+++
 
208
.PURPOSE Append a record to a buffer --- The buffer is
 
209
        expanded if necessary
 
210
.RETURNS Address of stored record / NULL if error
 
211
.REMARKS 
 
212
---*/
 
213
        BUFFER  *b;             /* IN: The buffer to free       */
 
214
        char    *record;        /* IN: record to append         */
 
215
        int     len;            /* IN: Length of record         */
 
216
{
 
217
        char    *p;
 
218
        
 
219
  ENTER("*mm_bapp");
 
220
 
 
221
        /* Get a pointer in buffer, and then copy string
 
222
         * to this buffer       */
 
223
 
 
224
  p = mm_ball(b, len+1);
 
225
  if (p) {
 
226
        oscopy(p, record, len), p[len] = 0;
 
227
        b->used -= 1;   
 
228
  }
 
229
 
 
230
#if DEBUG
 
231
        TRACE_ED_STR2("Buffer: ",b->buf, b->used);
 
232
#endif
 
233
 
 
234
  EXITp(p);
 
235
}  
 
236
 
 
237
/*==========================================================================*/
 
238
char *mm_ball(b, len)    
 
239
/*+++
 
240
.PURPOSE Set a pointer to next available record in buffer.
 
241
        Buffer is expanded if necessary
 
242
.RETURNS Address of available record / NULL if error
 
243
.REMARKS 
 
244
---*/
 
245
        BUFFER  *b;             /* IN: The buffer to free       */
 
246
        int     len;            /* IN: Length of record         */
 
247
{
 
248
        char    *p;
 
249
        int     ex;
 
250
        
 
251
  ENTER("*mm_ball");
 
252
 
 
253
#if DEBUG
 
254
  TRACE_ED_I("Asks for bytes: ",len);
 
255
#endif
 
256
 
 
257
  p = NULL_PTR(char);
 
258
  if_not(b)             { ERROR("Bad Buffer"); FINISH; }
 
259
  if (len < 0)          { ERR_ED_I("Bad Length: ", len); FINISH; }
 
260
 
 
261
  p = (b->buf) + b->used;
 
262
  if (len  ==  0 )              FINISH;
 
263
 
 
264
#if DEBUG
 
265
  TRACE_ED_I("Already in buffer: ",b->used);
 
266
  TRACE_ED_STR2("Already in buffer: ",b->buf, b->used);
 
267
#endif
 
268
 
 
269
  ex = b->used + len - b->allocated;
 
270
  if ( ex > 0)                  /* Doesn't fit. Expand is required */
 
271
  {     if(b->increment)        /* Increment is possible */
 
272
        {       ex = (ex+b->increment-1)/b->increment;
 
273
                ex = ex*b->increment + b->allocated;
 
274
                p = (mm_bexp(b, ex) ? b->buf + b->used : NULL_PTR(char));
 
275
        }
 
276
        else    p = NULL_PTR(char);
 
277
  }
 
278
  else  ;
 
279
 
 
280
  FIN:
 
281
  if(p) b->used += len;
 
282
 
 
283
  EXITp(p);
 
284
}
 
285
 
 
286
/*==========================================================================*/
 
287
char *mm_zfree(b, index, item_len)    
 
288
/*+++
 
289
.PURPOSE Free the indexed item.
 
290
.RETURNS Address of freed item / NULL if bad item
 
291
.REMARKS No tracing.
 
292
---*/
 
293
        BUFFER  *b;             /* IN: The buffer to free       */
 
294
        int     index;          /* IN: Index of item to free    */
 
295
        int     item_len;       /* IN: Size of 1 item           */
 
296
{
 
297
        char    *p;
 
298
        int     o;
 
299
        
 
300
  p = NULL_PTR(char);
 
301
  
 
302
        /* Find first the position */
 
303
 
 
304
  o = index * item_len;
 
305
  if ( (o < 0) || (o >= b->used) )      FINISH;
 
306
  p = b->buf + o;
 
307
  
 
308
  oscfill(p, item_len, '\0');
 
309
 
 
310
  FIN:
 
311
  return(p);
 
312
}
 
313
 
 
314
/*==========================================================================*/
 
315
char *mm_zindex(b, index, item_len)    
 
316
/*+++
 
317
.PURPOSE Finds the position of indexed item. Null item is checked.
 
318
.RETURNS Address of found item / NULL if bad item or is filled
 
319
        with zeroes.
 
320
.REMARKS No tracing.
 
321
---*/
 
322
        BUFFER  *b;             /* IN: The buffer to free       */
 
323
        int     index;          /* IN: Index of item to free    */
 
324
        int     item_len;       /* IN: Size of 1 item           */
 
325
{
 
326
        char    *p;
 
327
        int     o;
 
328
        
 
329
  p = NULL_PTR(char);
 
330
  
 
331
        /* Find first the position */
 
332
 
 
333
  o = index * item_len;
 
334
  if ( (o < 0) || (o >= b->used) )      FINISH;
 
335
  p = b->buf + o;
 
336
  
 
337
  if (oscskip(p, item_len, '\0') == item_len)   /* Filled with zeroes... */
 
338
        p = NULL_PTR(char);
 
339
 
 
340
  FIN:
 
341
  return(p);
 
342
}
 
343
 
 
344
/*==========================================================================*/
 
345
char *mm_zloc(b, item_len)    
 
346
/*+++
 
347
.PURPOSE Finds the position for a new (free) item. The found
 
348
        position is filled with zeroes, and b->offset is initialized.
 
349
.RETURNS Address of found item position / NULL if impossible.
 
350
.REMARKS No tracing.
 
351
---*/
 
352
        BUFFER  *b;             /* IN: The buffer to free       */
 
353
        int     item_len;       /* IN: Size of 1 item           */
 
354
{
 
355
        char    *p;
 
356
        
 
357
 
 
358
        /* Look first if space remains. If yes, use it */
 
359
 
 
360
  if (b->allocated > b->used)
 
361
  {     b->offset = b->used;
 
362
        FINISH;
 
363
  }
 
364
 
 
365
        /* Find an position with only zeroes    */
 
366
 
 
367
  for (b->offset = 0; b->offset < b->used; b->offset += item_len)
 
368
        if (oscskip(b->buf + b->offset, item_len, '\0') == item_len)
 
369
                FINISH;
 
370
 
 
371
        /* Last possibility: Must expand the buffer... 
 
372
         * Remember that b->offset is correctly set to b->used */
 
373
        
 
374
  mm_ball(b, item_len);
 
375
 
 
376
        /* Now, initialize the found item       */
 
377
 
 
378
  FIN:
 
379
  if (b->offset < b->allocated)         /* It's OK... */
 
380
  {     p = b->buf + b->offset;
 
381
        oscfill(p, item_len, '\0');
 
382
        if (b->used <= b->offset)       b->used = b->offset + item_len;
 
383
  }
 
384
  else  
 
385
  {     ERROR("Maximum reached.");
 
386
        p = NULL_PTR(char);
 
387
  }
 
388
 
 
389
  return(p);
 
390
}
 
391