Annotation of embedaddon/strongswan/src/libstrongswan/bio/bio_writer.c, revision 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>