]> Git Repo - qemu.git/blame - util/buffer.c
buffer: factor out buffer_adj_size
[qemu.git] / util / buffer.c
CommitLineData
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"
d2b90718 22#include "trace.h"
88c5f205 23
1ff36b5d
GH
24#define BUFFER_MIN_INIT_SIZE 4096
25#define BUFFER_MIN_SHRINK_SIZE 65536
5c10dbb7 26
fd952433
PL
27static size_t buffer_req_size(Buffer *buffer, size_t len)
28{
29 return MAX(BUFFER_MIN_INIT_SIZE,
30 pow2ceil(buffer->offset + len));
31}
32
4ec5ba15
PL
33static void buffer_adj_size(Buffer *buffer, size_t len)
34{
35 size_t old = buffer->capacity;
36 buffer->capacity = buffer_req_size(buffer, len);
37 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
38 trace_buffer_resize(buffer->name ?: "unnamed",
39 old, buffer->capacity);
40}
fd952433 41
810082d1
GH
42void buffer_init(Buffer *buffer, const char *name, ...)
43{
44 va_list ap;
45
46 va_start(ap, name);
47 buffer->name = g_strdup_vprintf(name, ap);
48 va_end(ap);
49}
50
1ff36b5d
GH
51void buffer_shrink(Buffer *buffer)
52{
53 /*
54 * Only shrink in case the used size is *much* smaller than the
55 * capacity, to avoid bumping up & down the buffers all the time.
56 * realloc() isn't exactly cheap ...
57 */
58 if (buffer->offset < (buffer->capacity >> 3) &&
59 buffer->capacity > BUFFER_MIN_SHRINK_SIZE) {
60 return;
61 }
62
4ec5ba15 63 buffer_adj_size(buffer, 0);
1ff36b5d
GH
64}
65
88c5f205
DB
66void buffer_reserve(Buffer *buffer, size_t len)
67{
68 if ((buffer->capacity - buffer->offset) < len) {
4ec5ba15 69 buffer_adj_size(buffer, len);
88c5f205
DB
70 }
71}
72
73gboolean buffer_empty(Buffer *buffer)
74{
75 return buffer->offset == 0;
76}
77
78uint8_t *buffer_end(Buffer *buffer)
79{
80 return buffer->buffer + buffer->offset;
81}
82
83void buffer_reset(Buffer *buffer)
84{
85 buffer->offset = 0;
86}
87
88void buffer_free(Buffer *buffer)
89{
d2b90718 90 trace_buffer_free(buffer->name ?: "unnamed", buffer->capacity);
88c5f205 91 g_free(buffer->buffer);
810082d1 92 g_free(buffer->name);
88c5f205
DB
93 buffer->offset = 0;
94 buffer->capacity = 0;
95 buffer->buffer = NULL;
810082d1 96 buffer->name = NULL;
88c5f205
DB
97}
98
99void buffer_append(Buffer *buffer, const void *data, size_t len)
100{
101 memcpy(buffer->buffer + buffer->offset, data, len);
102 buffer->offset += len;
103}
104
105void buffer_advance(Buffer *buffer, size_t len)
106{
107 memmove(buffer->buffer, buffer->buffer + len,
108 (buffer->offset - len));
109 buffer->offset -= len;
110}
4d1eb5fd
GH
111
112void buffer_move_empty(Buffer *to, Buffer *from)
113{
d2b90718
GH
114 trace_buffer_move_empty(to->name ?: "unnamed",
115 from->offset,
116 from->name ?: "unnamed");
4d1eb5fd
GH
117 assert(to->offset == 0);
118
119 g_free(to->buffer);
120 to->offset = from->offset;
121 to->capacity = from->capacity;
122 to->buffer = from->buffer;
123
124 from->offset = 0;
125 from->capacity = 0;
126 from->buffer = NULL;
127}
830a9583
GH
128
129void buffer_move(Buffer *to, Buffer *from)
130{
131 if (to->offset == 0) {
132 buffer_move_empty(to, from);
133 return;
134 }
135
d2b90718
GH
136 trace_buffer_move(to->name ?: "unnamed",
137 from->offset,
138 from->name ?: "unnamed");
830a9583
GH
139 buffer_reserve(to, from->offset);
140 buffer_append(to, from->buffer, from->offset);
141
142 g_free(from->buffer);
143 from->offset = 0;
144 from->capacity = 0;
145 from->buffer = NULL;
146}
This page took 0.038053 seconds and 4 git commands to generate.