2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "bio_writer.h"
18 typedef struct private_bio_writer_t private_bio_writer_t
;
21 * Private data of an bio_writer_t object.
23 struct private_bio_writer_t
{
26 * Public bio_writer_t interface.
36 * Used bytes in buffer
41 * Number of bytes to increase buffer size
47 * Increase buffer size
49 static void increase(private_bio_writer_t
*this)
51 this->buf
.len
+= this->increase
;
52 this->buf
.ptr
= realloc(this->buf
.ptr
, this->buf
.len
);
55 METHOD(bio_writer_t
, write_uint8
, void,
56 private_bio_writer_t
*this, u_int8_t value
)
58 if (this->used
+ 1 > this->buf
.len
)
62 this->buf
.ptr
[this->used
] = value
;
66 METHOD(bio_writer_t
, write_uint16
, void,
67 private_bio_writer_t
*this, u_int16_t value
)
69 if (this->used
+ 2 > this->buf
.len
)
73 htoun16(this->buf
.ptr
+ this->used
, value
);
77 METHOD(bio_writer_t
, write_uint24
, void,
78 private_bio_writer_t
*this, u_int32_t value
)
80 if (this->used
+ 3 > this->buf
.len
)
85 memcpy(this->buf
.ptr
+ this->used
, ((char*)&value
) + 1, 3);
89 METHOD(bio_writer_t
, write_uint32
, void,
90 private_bio_writer_t
*this, u_int32_t value
)
92 if (this->used
+ 4 > this->buf
.len
)
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
)
103 if (this->used
+ 8 > this->buf
.len
)
107 htoun64(this->buf
.ptr
+ this->used
, value
);
111 METHOD(bio_writer_t
, write_data
, void,
112 private_bio_writer_t
*this, chunk_t value
)
114 while (this->used
+ value
.len
> this->buf
.len
)
118 memcpy(this->buf
.ptr
+ this->used
, value
.ptr
, value
.len
);
119 this->used
+= value
.len
;
122 METHOD(bio_writer_t
, write_data8
, void,
123 private_bio_writer_t
*this, chunk_t value
)
125 write_uint8(this, value
.len
);
126 write_data(this, value
);
129 METHOD(bio_writer_t
, write_data16
, void,
130 private_bio_writer_t
*this, chunk_t value
)
132 write_uint16(this, value
.len
);
133 write_data(this, value
);
136 METHOD(bio_writer_t
, write_data24
, void,
137 private_bio_writer_t
*this, chunk_t value
)
139 write_uint24(this, value
.len
);
140 write_data(this, value
);
143 METHOD(bio_writer_t
, write_data32
, void,
144 private_bio_writer_t
*this, chunk_t value
)
146 write_uint32(this, value
.len
);
147 write_data(this, value
);
150 METHOD(bio_writer_t
, wrap8
, void,
151 private_bio_writer_t
*this)
153 if (this->used
+ 1 > this->buf
.len
)
157 memmove(this->buf
.ptr
+ 1, this->buf
.ptr
, this->used
);
158 this->buf
.ptr
[0] = this->used
;
162 METHOD(bio_writer_t
, wrap16
, void,
163 private_bio_writer_t
*this)
165 if (this->used
+ 2 > this->buf
.len
)
169 memmove(this->buf
.ptr
+ 2, this->buf
.ptr
, this->used
);
170 htoun16(this->buf
.ptr
, this->used
);
174 METHOD(bio_writer_t
, wrap24
, void,
175 private_bio_writer_t
*this)
179 if (this->used
+ 3 > this->buf
.len
)
183 memmove(this->buf
.ptr
+ 3, this->buf
.ptr
, this->used
);
185 len
= htonl(this->used
);
186 memcpy(this->buf
.ptr
, ((char*)&len
) + 1, 3);
190 METHOD(bio_writer_t
, wrap32
, void,
191 private_bio_writer_t
*this)
193 if (this->used
+ 4 > this->buf
.len
)
197 memmove(this->buf
.ptr
+ 4, this->buf
.ptr
, this->used
);
198 htoun32(this->buf
.ptr
, this->used
);
202 METHOD(bio_writer_t
, get_buf
, chunk_t
,
203 private_bio_writer_t
*this)
205 return chunk_create(this->buf
.ptr
, this->used
);
208 METHOD(bio_writer_t
, destroy
, void,
209 private_bio_writer_t
*this)
218 bio_writer_t
*bio_writer_create(u_int32_t bufsize
)
220 private_bio_writer_t
*this;
224 .write_uint8
= _write_uint8
,
225 .write_uint16
= _write_uint16
,
226 .write_uint24
= _write_uint24
,
227 .write_uint32
= _write_uint32
,
228 .write_uint64
= _write_uint64
,
229 .write_data
= _write_data
,
230 .write_data8
= _write_data8
,
231 .write_data16
= _write_data16
,
232 .write_data24
= _write_data24
,
233 .write_data32
= _write_data32
,
241 .increase
= bufsize
? max(bufsize
, 4) : 32,
245 this->buf
= chunk_alloc(bufsize
);
248 return &this->public;