2 * Copyright (C) 2012-2013 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, if required
52 static inline void increase(private_bio_writer_t
*this, size_t required
)
56 while (this->used
+ required
> this->buf
.len
)
58 this->buf
.len
+= this->increase
;
63 this->buf
.ptr
= realloc(this->buf
.ptr
, this->buf
.len
);
67 METHOD(bio_writer_t
, write_uint8
, void,
68 private_bio_writer_t
*this, u_int8_t value
)
71 this->buf
.ptr
[this->used
] = value
;
75 METHOD(bio_writer_t
, write_uint16
, void,
76 private_bio_writer_t
*this, u_int16_t value
)
79 htoun16(this->buf
.ptr
+ this->used
, value
);
83 METHOD(bio_writer_t
, write_uint24
, void,
84 private_bio_writer_t
*this, u_int32_t value
)
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
)
96 htoun32(this->buf
.ptr
+ this->used
, value
);
100 METHOD(bio_writer_t
, write_uint64
, void,
101 private_bio_writer_t
*this, u_int64_t value
)
104 htoun64(this->buf
.ptr
+ this->used
, value
);
108 METHOD(bio_writer_t
, write_data
, void,
109 private_bio_writer_t
*this, chunk_t value
)
111 increase(this, value
.len
);
112 memcpy(this->buf
.ptr
+ this->used
, value
.ptr
, value
.len
);
113 this->used
+= value
.len
;
116 METHOD(bio_writer_t
, write_data8
, void,
117 private_bio_writer_t
*this, chunk_t value
)
119 increase(this, 1 + value
.len
);
120 write_uint8(this, value
.len
);
121 write_data(this, value
);
124 METHOD(bio_writer_t
, write_data16
, void,
125 private_bio_writer_t
*this, chunk_t value
)
127 increase(this, 2 + value
.len
);
128 write_uint16(this, value
.len
);
129 write_data(this, value
);
132 METHOD(bio_writer_t
, write_data24
, void,
133 private_bio_writer_t
*this, chunk_t value
)
135 increase(this, 3 + value
.len
);
136 write_uint24(this, value
.len
);
137 write_data(this, value
);
140 METHOD(bio_writer_t
, write_data32
, void,
141 private_bio_writer_t
*this, chunk_t value
)
143 increase(this, 4 + value
.len
);
144 write_uint32(this, value
.len
);
145 write_data(this, value
);
148 METHOD(bio_writer_t
, wrap8
, void,
149 private_bio_writer_t
*this)
152 memmove(this->buf
.ptr
+ 1, this->buf
.ptr
, this->used
);
153 this->buf
.ptr
[0] = this->used
;
157 METHOD(bio_writer_t
, wrap16
, void,
158 private_bio_writer_t
*this)
161 memmove(this->buf
.ptr
+ 2, this->buf
.ptr
, this->used
);
162 htoun16(this->buf
.ptr
, this->used
);
166 METHOD(bio_writer_t
, wrap24
, void,
167 private_bio_writer_t
*this)
172 memmove(this->buf
.ptr
+ 3, this->buf
.ptr
, this->used
);
174 len
= htonl(this->used
);
175 memcpy(this->buf
.ptr
, ((char*)&len
) + 1, 3);
179 METHOD(bio_writer_t
, wrap32
, void,
180 private_bio_writer_t
*this)
183 memmove(this->buf
.ptr
+ 4, this->buf
.ptr
, this->used
);
184 htoun32(this->buf
.ptr
, this->used
);
188 METHOD(bio_writer_t
, skip
, chunk_t
,
189 private_bio_writer_t
*this, size_t len
)
194 skipped
= chunk_create(this->buf
.ptr
+ this->used
, len
);
199 METHOD(bio_writer_t
, get_buf
, chunk_t
,
200 private_bio_writer_t
*this)
202 return chunk_create(this->buf
.ptr
, this->used
);
205 METHOD(bio_writer_t
, extract_buf
, chunk_t
,
206 private_bio_writer_t
*this)
208 chunk_t buf
= get_buf(this);
209 this->buf
= chunk_empty
;
214 METHOD(bio_writer_t
, destroy
, void,
215 private_bio_writer_t
*this)
224 bio_writer_t
*bio_writer_create(u_int32_t bufsize
)
226 private_bio_writer_t
*this;
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
,
246 .extract_buf
= _extract_buf
,
249 .increase
= bufsize
? max(bufsize
, 4) : 32,
253 this->buf
= chunk_alloc(bufsize
);
256 return &this->public;