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