A LOT updates. Cannot separate. :)
[silc.git] / lib / silcutil / silcbuffer.c
1 /*
2
3   silcbuffer.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1998 - 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * $Id$
22  * $Log$
23  * Revision 1.2  2000/10/31 19:48:32  priikone
24  *      A LOT updates. Cannot separate. :)
25  *
26  * Revision 1.1  2000/09/13 17:45:15  priikone
27  *      Splitted SILC core library. Core library includes now only
28  *      SILC protocol specific stuff. New utility library includes the
29  *      old stuff from core library that is more generic purpose stuff.
30  *
31  * Revision 1.2  2000/07/05 06:06:35  priikone
32  *      Global cosmetic change.
33  *
34  * Revision 1.1.1.1  2000/06/27 11:36:55  priikone
35  *      Imported from internal CVS/Added Log headers.
36  *
37  *
38  */
39
40 #include "silcincludes.h"
41 #include "silcbuffer.h"
42
43 #ifdef SILC_DEBUG               /* If we are doing debugging we won't
44                                    have the optimized inline buffer functions
45                                    available as optimization is not set
46                                    to compiler. These normal routines are
47                                    used in debugging mode. */
48
49 /* XXX These are currenly obsolete as SILC is compiled always with -O
50    flag thus inline functions maybe used always. So, fix these. */
51
52 /* Allocates a new SilcBuffer and returns a pointer to it. The data
53    area of the new buffer is set to the real beginning of the buffer. 
54
55    Buffer after allocation:
56    ---------------------------------
57    |                               |
58    ---------------------------------
59    ^ head, data, tail              ^ end
60
61 */
62
63 SilcBuffer silc_buffer_alloc(unsigned int len)
64 {
65   SilcBuffer sb;
66   unsigned char *data;
67
68   /* Allocate new SilcBuffer */
69   sb = silc_calloc(1, sizeof(*sb));
70
71   /* Allocate the actual data area */
72   data = silc_calloc(len, sizeof(*data));
73   memset(data, 0, len);
74
75   /* Set pointers to the new buffer */
76   sb->truelen = len;
77   sb->len = 0;
78   sb->head = data;
79   sb->data = data;
80   sb->tail = data;
81   sb->end = data + sb->truelen;
82
83   return sb;
84 }
85
86 /* Free's a SilcBuffer */
87
88 void silc_buffer_free(SilcBuffer sb)
89 {
90   if (sb) {
91     memset(sb->head, 'F', sb->truelen);
92     silc_free(sb->head);
93     silc_free(sb);
94   }
95 }
96
97 /* Pulls current data area towards end. The length of the currently
98    valid data area is also decremented. Returns pointer to the data
99    area before pulling. 
100
101    Example:
102    ---------------------------------
103    | head  | data       | tail     |
104    ---------------------------------
105            ^
106            Pulls the start of the data area.
107
108    ---------------------------------
109    | head     | data    | tail     |
110    ---------------------------------
111            ^
112 */
113
114 unsigned char *silc_buffer_pull(SilcBuffer sb, unsigned int len)
115 {
116   unsigned char *old_data = sb->data;
117
118   assert(len <= (sb->tail - sb->data));
119
120   sb->data += len;
121   sb->len -= len;
122
123   return old_data;
124 }
125
126 /* Pushes current data area towards beginning. Length of the currently
127    valid data area is also incremented. Returns a pointer to the 
128    data area before pushing. 
129
130    Example:
131    ---------------------------------
132    | head     | data    | tail     |
133    ---------------------------------
134               ^
135               Pushes the start of the data area.
136
137    ---------------------------------
138    | head  | data       | tail     |
139    ---------------------------------
140               ^
141 */
142
143 unsigned char *silc_buffer_push(SilcBuffer sb, unsigned int len)
144 {
145   unsigned char *old_data = sb->data;
146
147   assert((sb->data - len) >= sb->head);
148
149   sb->data -= len;
150   sb->len += len;
151
152   return old_data;
153 }
154
155 /* Pulls current tail section towards end. Length of the current valid
156    data area is also incremented. Returns a pointer to the data area 
157    before pulling.
158
159    Example:
160    ---------------------------------
161    | head  | data       | tail     |
162    ---------------------------------
163                         ^
164                         Pulls the start of the tail section.
165
166    ---------------------------------
167    | head  | data           | tail |
168    ---------------------------------
169                         ^
170 */
171
172 unsigned char *silc_buffer_pull_tail(SilcBuffer sb, unsigned int len)
173 {
174   unsigned char *old_tail = sb->tail;
175
176   assert((sb->end - sb->tail) >= len);
177
178   sb->tail += len;
179   sb->len += len;
180
181   return old_tail;
182 }
183
184 /* Pushes current tail section towards beginning. Length of the current
185    valid data area is also decremented. Returns a pointer to the 
186    tail section before pushing. 
187
188    Example:
189    ---------------------------------
190    | head  | data           | tail |
191    ---------------------------------
192                             ^
193                             Pushes the start of the tail section.
194
195    ---------------------------------
196    | head  | data       | tail     |
197    ---------------------------------
198                             ^
199 */
200
201 unsigned char *silc_buffer_push_tail(SilcBuffer sb, unsigned int len)
202 {
203   unsigned char *old_tail = sb->tail;
204
205   assert((sb->tail - len) >= sb->data);
206
207   sb->tail -= len;
208   sb->len -= len;
209
210   return old_tail;
211 }
212
213 /* Puts data at the head of the buffer. Returns pointer to the copied
214    data area. 
215    
216    Example:
217    ---------------------------------
218    | head  | data       | tail     |
219    ---------------------------------
220    ^
221    Puts data to the head section. 
222 */
223
224 unsigned char *silc_buffer_put_head(SilcBuffer sb, 
225                                     unsigned char *data,
226                                     unsigned int len)
227 {
228   assert((sb->data - sb->head) >= len);
229   return memcpy(sb->head, data, len);
230 }
231
232 /* Puts data at the start of the valid data area. Returns a pointer 
233    to the copied data area. 
234
235    Example:
236    ---------------------------------
237    | head  | data       | tail     |
238    ---------------------------------
239            ^
240            Puts data to the data section.
241 */
242
243 unsigned char *silc_buffer_put(SilcBuffer sb, 
244                                unsigned char *data,
245                                unsigned int len)
246 {
247   assert((sb->tail - sb->data) >= len);
248   return memcpy(sb->data, data, len);
249 }
250
251 /* Puts data at the tail of the buffer. Returns pointer to the copied
252    data area. 
253
254    Example:
255    ---------------------------------
256    | head  | data           | tail |
257    ---------------------------------
258                             ^
259                             Puts data to the tail section.
260 */
261
262 unsigned char *silc_buffer_put_tail(SilcBuffer sb, 
263                                     unsigned char *data,
264                                     unsigned int len)
265 {
266   assert((sb->end - sb->tail) >= len);
267   return memcpy(sb->tail, data, len);
268 }
269
270 #endif