]>
Commit | Line | Data |
---|---|---|
88c5f205 DB |
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 | ||
5c10dbb7 PL |
23 | #define BUFFER_MIN_INIT_SIZE 4096 |
24 | ||
810082d1 GH |
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 | ||
88c5f205 DB |
34 | void buffer_reserve(Buffer *buffer, size_t len) |
35 | { | |
36 | if ((buffer->capacity - buffer->offset) < len) { | |
5c10dbb7 PL |
37 | buffer->capacity = pow2ceil(buffer->offset + len); |
38 | buffer->capacity = MAX(buffer->capacity, BUFFER_MIN_INIT_SIZE); | |
88c5f205 DB |
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); | |
810082d1 | 61 | g_free(buffer->name); |
88c5f205 DB |
62 | buffer->offset = 0; |
63 | buffer->capacity = 0; | |
64 | buffer->buffer = NULL; | |
810082d1 | 65 | buffer->name = NULL; |
88c5f205 DB |
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 | } | |
4d1eb5fd GH |
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 | } | |
830a9583 GH |
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 | } |