1 /* 2 * QEMU generic buffers 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/buffer.h" 22 23 #define BUFFER_MIN_INIT_SIZE 4096 24 25 void buffer_init(Buffer *buffer, const char *name, ...) 26 { 27 va_list ap; 28 29 va_start(ap, name); 30 buffer->name = g_strdup_vprintf(name, ap); 31 va_end(ap); 32 } 33 34 void buffer_reserve(Buffer *buffer, size_t len) 35 { 36 if ((buffer->capacity - buffer->offset) < len) { 37 buffer->capacity = pow2ceil(buffer->offset + len); 38 buffer->capacity = MAX(buffer->capacity, BUFFER_MIN_INIT_SIZE); 39 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity); 40 } 41 } 42 43 gboolean buffer_empty(Buffer *buffer) 44 { 45 return buffer->offset == 0; 46 } 47 48 uint8_t *buffer_end(Buffer *buffer) 49 { 50 return buffer->buffer + buffer->offset; 51 } 52 53 void buffer_reset(Buffer *buffer) 54 { 55 buffer->offset = 0; 56 } 57 58 void buffer_free(Buffer *buffer) 59 { 60 g_free(buffer->buffer); 61 g_free(buffer->name); 62 buffer->offset = 0; 63 buffer->capacity = 0; 64 buffer->buffer = NULL; 65 buffer->name = NULL; 66 } 67 68 void buffer_append(Buffer *buffer, const void *data, size_t len) 69 { 70 memcpy(buffer->buffer + buffer->offset, data, len); 71 buffer->offset += len; 72 } 73 74 void buffer_advance(Buffer *buffer, size_t len) 75 { 76 memmove(buffer->buffer, buffer->buffer + len, 77 (buffer->offset - len)); 78 buffer->offset -= len; 79 } 80 81 void buffer_move_empty(Buffer *to, Buffer *from) 82 { 83 assert(to->offset == 0); 84 85 g_free(to->buffer); 86 to->offset = from->offset; 87 to->capacity = from->capacity; 88 to->buffer = from->buffer; 89 90 from->offset = 0; 91 from->capacity = 0; 92 from->buffer = NULL; 93 } 94 95 void buffer_move(Buffer *to, Buffer *from) 96 { 97 if (to->offset == 0) { 98 buffer_move_empty(to, from); 99 return; 100 } 101 102 buffer_reserve(to, from->offset); 103 buffer_append(to, from->buffer, from->offset); 104 105 g_free(from->buffer); 106 from->offset = 0; 107 from->capacity = 0; 108 from->buffer = NULL; 109 } 110