2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2010 Martin Willi
6 * Copyright (C) 2010 revosec AG
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>.
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
19 #include "bio_writer.h"
21 typedef struct private_bio_writer_t private_bio_writer_t
;
24 * Private data of an bio_writer_t object.
26 struct private_bio_writer_t
{
29 * Public bio_writer_t interface.
39 * Used bytes in buffer
44 * Number of bytes to increase buffer size
50 * Increase buffer size
52 static void increase(private_bio_writer_t
*this)
54 this->buf
.len
+= this->increase
;
55 this->buf
.ptr
= realloc(this->buf
.ptr
, this->buf
.len
);
58 METHOD(bio_writer_t
, write_uint8
, void,
59 private_bio_writer_t
*this, u_int8_t value
)
61 if (this->used
+ 1 > this->buf
.len
)
65 this->buf
.ptr
[this->used
] = value
;
69 METHOD(bio_writer_t
, write_uint16
, void,
70 private_bio_writer_t
*this, u_int16_t value
)
72 if (this->used
+ 2 > this->buf
.len
)
76 htoun16(this->buf
.ptr
+ this->used
, value
);
80 METHOD(bio_writer_t
, write_uint24
, void,
81 private_bio_writer_t
*this, u_int32_t value
)
83 if (this->used
+ 3 > this->buf
.len
)
88 memcpy(this->buf
.ptr
+ this->used
, ((char*)&value
) + 1, 3);
92 METHOD(bio_writer_t
, write_uint32
, void,
93 private_bio_writer_t
*this, u_int32_t value
)
95 if (this->used
+ 4 > this->buf
.len
)
99 htoun32(this->buf
.ptr
+ this->used
, value
);
103 METHOD(bio_writer_t
, write_uint64
, void,
104 private_bio_writer_t
*this, u_int64_t value
)
106 if (this->used
+ 8 > this->buf
.len
)
110 htoun64(this->buf
.ptr
+ this->used
, value
);
114 METHOD(bio_writer_t
, write_data
, void,
115 private_bio_writer_t
*this, chunk_t value
)
117 while (this->used
+ value
.len
> this->buf
.len
)
121 memcpy(this->buf
.ptr
+ this->used
, value
.ptr
, value
.len
);
122 this->used
+= value
.len
;
125 METHOD(bio_writer_t
, write_data8
, void,
126 private_bio_writer_t
*this, chunk_t value
)
128 write_uint8(this, value
.len
);
129 write_data(this, value
);
132 METHOD(bio_writer_t
, write_data16
, void,
133 private_bio_writer_t
*this, chunk_t value
)
135 write_uint16(this, value
.len
);
136 write_data(this, value
);
139 METHOD(bio_writer_t
, write_data24
, void,
140 private_bio_writer_t
*this, chunk_t value
)
142 write_uint24(this, value
.len
);
143 write_data(this, value
);
146 METHOD(bio_writer_t
, write_data32
, void,
147 private_bio_writer_t
*this, chunk_t value
)
149 write_uint32(this, value
.len
);
150 write_data(this, value
);
153 METHOD(bio_writer_t
, wrap8
, void,
154 private_bio_writer_t
*this)
156 if (this->used
+ 1 > this->buf
.len
)
160 memmove(this->buf
.ptr
+ 1, this->buf
.ptr
, this->used
);
161 this->buf
.ptr
[0] = this->used
;
165 METHOD(bio_writer_t
, wrap16
, void,
166 private_bio_writer_t
*this)
168 if (this->used
+ 2 > this->buf
.len
)
172 memmove(this->buf
.ptr
+ 2, this->buf
.ptr
, this->used
);
173 htoun16(this->buf
.ptr
, this->used
);
177 METHOD(bio_writer_t
, wrap24
, void,
178 private_bio_writer_t
*this)
182 if (this->used
+ 3 > this->buf
.len
)
186 memmove(this->buf
.ptr
+ 3, this->buf
.ptr
, this->used
);
188 len
= htonl(this->used
);
189 memcpy(this->buf
.ptr
, ((char*)&len
) + 1, 3);
193 METHOD(bio_writer_t
, wrap32
, void,
194 private_bio_writer_t
*this)
196 if (this->used
+ 4 > this->buf
.len
)
200 memmove(this->buf
.ptr
+ 4, this->buf
.ptr
, this->used
);
201 htoun32(this->buf
.ptr
, this->used
);
205 METHOD(bio_writer_t
, skip
, chunk_t
,
206 private_bio_writer_t
*this, size_t len
)
210 while (this->used
+ len
> this->buf
.len
)
214 skipped
= chunk_create(this->buf
.ptr
+ this->used
, len
);
219 METHOD(bio_writer_t
, get_buf
, chunk_t
,
220 private_bio_writer_t
*this)
222 return chunk_create(this->buf
.ptr
, this->used
);
225 METHOD(bio_writer_t
, extract_buf
, chunk_t
,
226 private_bio_writer_t
*this)
228 chunk_t buf
= get_buf(this);
229 this->buf
= chunk_empty
;
234 METHOD(bio_writer_t
, destroy
, void,
235 private_bio_writer_t
*this)
244 bio_writer_t
*bio_writer_create(u_int32_t bufsize
)
246 private_bio_writer_t
*this;
250 .write_uint8
= _write_uint8
,
251 .write_uint16
= _write_uint16
,
252 .write_uint24
= _write_uint24
,
253 .write_uint32
= _write_uint32
,
254 .write_uint64
= _write_uint64
,
255 .write_data
= _write_data
,
256 .write_data8
= _write_data8
,
257 .write_data16
= _write_data16
,
258 .write_data24
= _write_data24
,
259 .write_data32
= _write_data32
,
266 .extract_buf
= _extract_buf
,
269 .increase
= bufsize
? max(bufsize
, 4) : 32,
273 this->buf
= chunk_alloc(bufsize
);
276 return &this->public;