1 /* distcache, Distributed Session Caching technology
2  * Copyright (C) 2000-2003  Geoff Thorpe, and Cryptographic Appliances, Inc.
3  * Copyright (C) 2004       The Distcache.org project
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; using version 2.1 of the License. The copyright holders
8  * may elect to allow the application of later versions of the License to this
9  * software, please contact the author (geoff@distcache.org) if you wish us to
10  * review any later version released by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 #define SYS_GENERATING_LIB
23 
24 #include <libsys/pre.h>
25 #include <libnal/nal.h>
26 #include "nal_internal.h"
27 #include <libsys/post.h>
28 
29 /* Define the NAL_BUFFER structure */
30 
31 struct st_NAL_BUFFER {
32 	unsigned char *data;
33 	unsigned int used, size;
34 };
35 
36 /********************/
37 /* BUFFER FUNCTIONS */
38 /********************/
39 
NAL_BUFFER_new(void)40 NAL_BUFFER *NAL_BUFFER_new(void)
41 {
42 	NAL_BUFFER *b = SYS_malloc(NAL_BUFFER, 1);
43 	if(b) {
44 		b->data = NULL;
45 		b->used = b->size = 0;
46 	}
47 	return b;
48 }
49 
NAL_BUFFER_free(NAL_BUFFER * b)50 void NAL_BUFFER_free(NAL_BUFFER *b)
51 {
52 	if(b->data) SYS_free(unsigned char, b->data);
53 	SYS_free(NAL_BUFFER, b);
54 }
55 
NAL_BUFFER_reset(NAL_BUFFER * b)56 void NAL_BUFFER_reset(NAL_BUFFER *b)
57 {
58 	b->used = 0;
59 }
60 
NAL_BUFFER_set_size(NAL_BUFFER * buf,unsigned int size)61 int NAL_BUFFER_set_size(NAL_BUFFER *buf, unsigned int size)
62 {
63 	unsigned char *next;
64 
65 	/* Saves time, and avoids the degenerate case that fails realloc -
66 	 * namely when ptr is NULL (realloc becomes malloc) *and* size is 0
67 	 * (realloc becomes free). */
68 	if(size == buf->size)
69 		return 1;
70 	if(!nal_check_buffer_size(size)) {
71 #if SYS_DEBUG_LEVEL > 1
72 		SYS_fprintf(SYS_stderr, "Error, NAL_BUFFER_set_size() called with too "
73 				"large a size\n");
74 #endif
75 		return 0;
76 	}
77 	next = SYS_realloc(unsigned char, buf->data, size);
78 	if(size && !next)
79 		return 0;
80 	buf->data = next;
81 	buf->size = size;
82 	buf->used = 0;
83 	return 1;
84 }
85 
NAL_BUFFER_empty(const NAL_BUFFER * buf)86 int NAL_BUFFER_empty(const NAL_BUFFER *buf)
87 {
88 	return (buf->used == 0);
89 }
90 
NAL_BUFFER_full(const NAL_BUFFER * buf)91 int NAL_BUFFER_full(const NAL_BUFFER *buf)
92 {
93 	return (buf->used == buf->size);
94 }
95 
NAL_BUFFER_notempty(const NAL_BUFFER * buf)96 int NAL_BUFFER_notempty(const NAL_BUFFER *buf)
97 {
98 	return (buf->used > 0);
99 }
100 
NAL_BUFFER_notfull(const NAL_BUFFER * buf)101 int NAL_BUFFER_notfull(const NAL_BUFFER *buf)
102 {
103 	return (buf->used < buf->size);
104 }
105 
NAL_BUFFER_used(const NAL_BUFFER * buf)106 unsigned int NAL_BUFFER_used(const NAL_BUFFER *buf)
107 {
108 	return buf->used;
109 }
110 
NAL_BUFFER_unused(const NAL_BUFFER * buf)111 unsigned int NAL_BUFFER_unused(const NAL_BUFFER *buf)
112 {
113 	return (buf->size - buf->used);
114 }
115 
NAL_BUFFER_data(const NAL_BUFFER * buf)116 const unsigned char *NAL_BUFFER_data(const NAL_BUFFER *buf)
117 {
118 	return buf->data;
119 }
120 
NAL_BUFFER_size(const NAL_BUFFER * buf)121 unsigned int NAL_BUFFER_size(const NAL_BUFFER *buf)
122 {
123 	return buf->size;
124 }
125 
NAL_BUFFER_write(NAL_BUFFER * buf,const unsigned char * ptr,unsigned int size)126 unsigned int NAL_BUFFER_write(NAL_BUFFER *buf, const unsigned char *ptr,
127 		                unsigned int size)
128 {
129 	unsigned int towrite = NAL_BUFFER_unused(buf);
130 	if(towrite > size)
131 		towrite = size;
132 	if(towrite == 0)
133 		return 0;
134 	SYS_memcpy_n(unsigned char, buf->data + buf->used, ptr, towrite);
135 	buf->used += towrite;
136 	return towrite;
137 }
138 
NAL_BUFFER_read(NAL_BUFFER * buf,unsigned char * ptr,unsigned int size)139 unsigned int NAL_BUFFER_read(NAL_BUFFER *buf, unsigned char *ptr,
140 		                unsigned int size)
141 {
142 	unsigned int toread = NAL_BUFFER_used(buf);
143 	if(toread > size)
144 		toread = size;
145 	if(toread == 0)
146 		return 0;
147 	if(ptr)
148 		SYS_memcpy_n(unsigned char, ptr, buf->data, toread);
149 	buf->used -= toread;
150 	if(buf->used > 0)
151 		SYS_memmove_n(unsigned char, buf->data,
152 				buf->data + toread, buf->used);
153 	return toread;
154 }
155 
NAL_BUFFER_transfer(NAL_BUFFER * dest,NAL_BUFFER * src,unsigned int max)156 unsigned int NAL_BUFFER_transfer(NAL_BUFFER *dest, NAL_BUFFER *src,
157 				unsigned int max)
158 {
159 	unsigned int tmp = NAL_BUFFER_unused(dest);
160 	if(!max || (max > tmp)) max = tmp;
161 	if(!max) return 0;
162 	tmp = NAL_BUFFER_read(src, NAL_BUFFER_write_ptr(dest), max);
163 	NAL_BUFFER_wrote(dest, tmp);
164 	return tmp;
165 }
166 
NAL_BUFFER_write_ptr(NAL_BUFFER * buf)167 unsigned char *NAL_BUFFER_write_ptr(NAL_BUFFER *buf)
168 {
169 	return (buf->data + buf->used);
170 }
171 
NAL_BUFFER_wrote(NAL_BUFFER * buf,unsigned int size)172 void NAL_BUFFER_wrote(NAL_BUFFER *buf, unsigned int size)
173 {
174 	assert(size <= NAL_BUFFER_unused(buf));
175 	buf->used += size;
176 }
177