Annotation of embedaddon/strongswan/src/libstrongswan/bio/bio_writer.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012-2013 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (C) 2010 Martin Willi
6: * Copyright (C) 2010 revosec AG
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include "bio_writer.h"
20:
21: typedef struct private_bio_writer_t private_bio_writer_t;
22:
23: /**
24: * Private data of an bio_writer_t object.
25: */
26: struct private_bio_writer_t {
27:
28: /**
29: * Public bio_writer_t interface.
30: */
31: bio_writer_t public;
32:
33: /**
34: * Allocated buffer
35: */
36: chunk_t buf;
37:
38: /**
39: * Used bytes in buffer
40: */
41: size_t used;
42:
43: /**
44: * Number of bytes to increase buffer size
45: */
46: size_t increase;
47: };
48:
49: /**
50: * Increase buffer size, if required
51: */
52: static inline void increase(private_bio_writer_t *this, size_t required)
53: {
54: bool inc = FALSE;
55:
56: while (this->used + required > this->buf.len)
57: {
58: this->buf.len += this->increase;
59: inc = TRUE;
60: }
61: if (inc)
62: {
63: this->buf.ptr = realloc(this->buf.ptr, this->buf.len);
64: }
65: }
66:
67: METHOD(bio_writer_t, write_uint8, void,
68: private_bio_writer_t *this, uint8_t value)
69: {
70: increase(this, 1);
71: this->buf.ptr[this->used] = value;
72: this->used += 1;
73: }
74:
75: METHOD(bio_writer_t, write_uint16, void,
76: private_bio_writer_t *this, uint16_t value)
77: {
78: increase(this, 2);
79: htoun16(this->buf.ptr + this->used, value);
80: this->used += 2;
81: }
82:
83: METHOD(bio_writer_t, write_uint24, void,
84: private_bio_writer_t *this, uint32_t value)
85: {
86: increase(this, 3);
87: value = htonl(value);
88: memcpy(this->buf.ptr + this->used, ((char*)&value) + 1, 3);
89: this->used += 3;
90: }
91:
92: METHOD(bio_writer_t, write_uint32, void,
93: private_bio_writer_t *this, uint32_t value)
94: {
95: increase(this, 4);
96: htoun32(this->buf.ptr + this->used, value);
97: this->used += 4;
98: }
99:
100: METHOD(bio_writer_t, write_uint64, void,
101: private_bio_writer_t *this, uint64_t value)
102: {
103: increase(this, 8);
104: htoun64(this->buf.ptr + this->used, value);
105: this->used += 8;
106: }
107:
108: METHOD(bio_writer_t, write_data, void,
109: private_bio_writer_t *this, chunk_t value)
110: {
111: increase(this, value.len);
112: memcpy(this->buf.ptr + this->used, value.ptr, value.len);
113: this->used += value.len;
114: }
115:
116: METHOD(bio_writer_t, write_data8, void,
117: private_bio_writer_t *this, chunk_t value)
118: {
119: increase(this, 1 + value.len);
120: write_uint8(this, value.len);
121: write_data(this, value);
122: }
123:
124: METHOD(bio_writer_t, write_data16, void,
125: private_bio_writer_t *this, chunk_t value)
126: {
127: increase(this, 2 + value.len);
128: write_uint16(this, value.len);
129: write_data(this, value);
130: }
131:
132: METHOD(bio_writer_t, write_data24, void,
133: private_bio_writer_t *this, chunk_t value)
134: {
135: increase(this, 3 + value.len);
136: write_uint24(this, value.len);
137: write_data(this, value);
138: }
139:
140: METHOD(bio_writer_t, write_data32, void,
141: private_bio_writer_t *this, chunk_t value)
142: {
143: increase(this, 4 + value.len);
144: write_uint32(this, value.len);
145: write_data(this, value);
146: }
147:
148: METHOD(bio_writer_t, wrap8, void,
149: private_bio_writer_t *this)
150: {
151: increase(this, 1);
152: memmove(this->buf.ptr + 1, this->buf.ptr, this->used);
153: this->buf.ptr[0] = this->used;
154: this->used += 1;
155: }
156:
157: METHOD(bio_writer_t, wrap16, void,
158: private_bio_writer_t *this)
159: {
160: increase(this, 2);
161: memmove(this->buf.ptr + 2, this->buf.ptr, this->used);
162: htoun16(this->buf.ptr, this->used);
163: this->used += 2;
164: }
165:
166: METHOD(bio_writer_t, wrap24, void,
167: private_bio_writer_t *this)
168: {
169: uint32_t len;
170:
171: increase(this, 3);
172: memmove(this->buf.ptr + 3, this->buf.ptr, this->used);
173:
174: len = htonl(this->used);
175: memcpy(this->buf.ptr, ((char*)&len) + 1, 3);
176: this->used += 3;
177: }
178:
179: METHOD(bio_writer_t, wrap32, void,
180: private_bio_writer_t *this)
181: {
182: increase(this, 4);
183: memmove(this->buf.ptr + 4, this->buf.ptr, this->used);
184: htoun32(this->buf.ptr, this->used);
185: this->used += 4;
186: }
187:
188: METHOD(bio_writer_t, skip, chunk_t,
189: private_bio_writer_t *this, size_t len)
190: {
191: chunk_t skipped;
192:
193: increase(this, len);
194: skipped = chunk_create(this->buf.ptr + this->used, len);
195: this->used += len;
196: return skipped;
197: }
198:
199: METHOD(bio_writer_t, get_buf, chunk_t,
200: private_bio_writer_t *this)
201: {
202: return chunk_create(this->buf.ptr, this->used);
203: }
204:
205: METHOD(bio_writer_t, extract_buf, chunk_t,
206: private_bio_writer_t *this)
207: {
208: chunk_t buf = get_buf(this);
209: this->buf = chunk_empty;
210: this->used = 0;
211: return buf;
212: }
213:
214: METHOD(bio_writer_t, destroy, void,
215: private_bio_writer_t *this)
216: {
217: free(this->buf.ptr);
218: free(this);
219: }
220:
221: /**
222: * See header
223: */
224: bio_writer_t *bio_writer_create(uint32_t bufsize)
225: {
226: private_bio_writer_t *this;
227:
228: INIT(this,
229: .public = {
230: .write_uint8 = _write_uint8,
231: .write_uint16 = _write_uint16,
232: .write_uint24 = _write_uint24,
233: .write_uint32 = _write_uint32,
234: .write_uint64 = _write_uint64,
235: .write_data = _write_data,
236: .write_data8 = _write_data8,
237: .write_data16 = _write_data16,
238: .write_data24 = _write_data24,
239: .write_data32 = _write_data32,
240: .wrap8 = _wrap8,
241: .wrap16 = _wrap16,
242: .wrap24 = _wrap24,
243: .wrap32 = _wrap32,
244: .skip = _skip,
245: .get_buf = _get_buf,
246: .extract_buf = _extract_buf,
247: .destroy = _destroy,
248: },
249: .increase = bufsize ? max(bufsize, 4) : 32,
250: );
251: if (bufsize)
252: {
253: this->buf = chunk_alloc(bufsize);
254: }
255:
256: return &this->public;
257: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>