188c5f205SDaniel P. Berrange /* 288c5f205SDaniel P. Berrange * QEMU generic buffers 388c5f205SDaniel P. Berrange * 488c5f205SDaniel P. Berrange * Copyright (c) 2015 Red Hat, Inc. 588c5f205SDaniel P. Berrange * 688c5f205SDaniel P. Berrange * This library is free software; you can redistribute it and/or 788c5f205SDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public 888c5f205SDaniel P. Berrange * License as published by the Free Software Foundation; either 961f3c91aSChetan Pant * version 2.1 of the License, or (at your option) any later version. 1088c5f205SDaniel P. Berrange * 1188c5f205SDaniel P. Berrange * This library is distributed in the hope that it will be useful, 1288c5f205SDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 1388c5f205SDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1488c5f205SDaniel P. Berrange * Lesser General Public License for more details. 1588c5f205SDaniel P. Berrange * 1688c5f205SDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public 1788c5f205SDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1888c5f205SDaniel P. Berrange * 1988c5f205SDaniel P. Berrange */ 2088c5f205SDaniel P. Berrange 212a6a4076SMarkus Armbruster #ifndef QEMU_BUFFER_H 222a6a4076SMarkus Armbruster #define QEMU_BUFFER_H 2388c5f205SDaniel P. Berrange 2488c5f205SDaniel P. Berrange 2588c5f205SDaniel P. Berrange typedef struct Buffer Buffer; 2688c5f205SDaniel P. Berrange 2788c5f205SDaniel P. Berrange /** 2888c5f205SDaniel P. Berrange * Buffer: 2988c5f205SDaniel P. Berrange * 3088c5f205SDaniel P. Berrange * The Buffer object provides a simple dynamically resizing 3188c5f205SDaniel P. Berrange * array, with separate tracking of capacity and usage. This 3288c5f205SDaniel P. Berrange * is typically useful when buffering I/O or processing data. 3388c5f205SDaniel P. Berrange */ 3488c5f205SDaniel P. Berrange 3588c5f205SDaniel P. Berrange struct Buffer { 36810082d1SGerd Hoffmann char *name; 3788c5f205SDaniel P. Berrange size_t capacity; 3888c5f205SDaniel P. Berrange size_t offset; 39f14c3d85SPeter Lieven uint64_t avg_size; 4088c5f205SDaniel P. Berrange uint8_t *buffer; 4188c5f205SDaniel P. Berrange }; 4288c5f205SDaniel P. Berrange 4388c5f205SDaniel P. Berrange /** 44810082d1SGerd Hoffmann * buffer_init: 45810082d1SGerd Hoffmann * @buffer: the buffer object 46810082d1SGerd Hoffmann * @name: buffer name 47810082d1SGerd Hoffmann * 48810082d1SGerd Hoffmann * Optionally attach a name to the buffer, to make it easier 49810082d1SGerd Hoffmann * to identify in debug traces. 50810082d1SGerd Hoffmann */ 51810082d1SGerd Hoffmann void buffer_init(Buffer *buffer, const char *name, ...) 52*9edc6313SMarc-André Lureau G_GNUC_PRINTF(2, 3); 53810082d1SGerd Hoffmann 54810082d1SGerd Hoffmann /** 551ff36b5dSGerd Hoffmann * buffer_shrink: 561ff36b5dSGerd Hoffmann * @buffer: the buffer object 571ff36b5dSGerd Hoffmann * 581ff36b5dSGerd Hoffmann * Try to shrink the buffer. Checks current buffer capacity and size 591ff36b5dSGerd Hoffmann * and reduces capacity in case only a fraction of the buffer is 601ff36b5dSGerd Hoffmann * actually used. 611ff36b5dSGerd Hoffmann */ 621ff36b5dSGerd Hoffmann void buffer_shrink(Buffer *buffer); 631ff36b5dSGerd Hoffmann 641ff36b5dSGerd Hoffmann /** 6588c5f205SDaniel P. Berrange * buffer_reserve: 6688c5f205SDaniel P. Berrange * @buffer: the buffer object 6788c5f205SDaniel P. Berrange * @len: the minimum required free space 6888c5f205SDaniel P. Berrange * 6988c5f205SDaniel P. Berrange * Ensure that the buffer has space allocated for at least 7088c5f205SDaniel P. Berrange * @len bytes. If the current buffer is too small, it will 7188c5f205SDaniel P. Berrange * be reallocated, possibly to a larger size than requested. 7288c5f205SDaniel P. Berrange */ 7388c5f205SDaniel P. Berrange void buffer_reserve(Buffer *buffer, size_t len); 7488c5f205SDaniel P. Berrange 7588c5f205SDaniel P. Berrange /** 7688c5f205SDaniel P. Berrange * buffer_reset: 7788c5f205SDaniel P. Berrange * @buffer: the buffer object 7888c5f205SDaniel P. Berrange * 7988c5f205SDaniel P. Berrange * Reset the length of the stored data to zero, but do 8088c5f205SDaniel P. Berrange * not free / reallocate the memory buffer 8188c5f205SDaniel P. Berrange */ 8288c5f205SDaniel P. Berrange void buffer_reset(Buffer *buffer); 8388c5f205SDaniel P. Berrange 8488c5f205SDaniel P. Berrange /** 8588c5f205SDaniel P. Berrange * buffer_free: 8688c5f205SDaniel P. Berrange * @buffer: the buffer object 8788c5f205SDaniel P. Berrange * 8888c5f205SDaniel P. Berrange * Reset the length of the stored data to zero and also 8988c5f205SDaniel P. Berrange * free the internal memory buffer 9088c5f205SDaniel P. Berrange */ 9188c5f205SDaniel P. Berrange void buffer_free(Buffer *buffer); 9288c5f205SDaniel P. Berrange 9388c5f205SDaniel P. Berrange /** 9488c5f205SDaniel P. Berrange * buffer_append: 9588c5f205SDaniel P. Berrange * @buffer: the buffer object 9688c5f205SDaniel P. Berrange * @data: the data block to append 9788c5f205SDaniel P. Berrange * @len: the length of @data in bytes 9888c5f205SDaniel P. Berrange * 9988c5f205SDaniel P. Berrange * Append the contents of @data to the end of the buffer. 10088c5f205SDaniel P. Berrange * The caller must ensure that the buffer has sufficient 10188c5f205SDaniel P. Berrange * free space for @len bytes, typically by calling the 10288c5f205SDaniel P. Berrange * buffer_reserve() method prior to appending. 10388c5f205SDaniel P. Berrange */ 10488c5f205SDaniel P. Berrange void buffer_append(Buffer *buffer, const void *data, size_t len); 10588c5f205SDaniel P. Berrange 10688c5f205SDaniel P. Berrange /** 10788c5f205SDaniel P. Berrange * buffer_advance: 10888c5f205SDaniel P. Berrange * @buffer: the buffer object 10988c5f205SDaniel P. Berrange * @len: the number of bytes to skip 11088c5f205SDaniel P. Berrange * 11188c5f205SDaniel P. Berrange * Remove @len bytes of data from the head of the buffer. 11288c5f205SDaniel P. Berrange * The internal buffer will not be reallocated, so will 11388c5f205SDaniel P. Berrange * have at least @len bytes of free space after this 11488c5f205SDaniel P. Berrange * call completes 11588c5f205SDaniel P. Berrange */ 11688c5f205SDaniel P. Berrange void buffer_advance(Buffer *buffer, size_t len); 11788c5f205SDaniel P. Berrange 11888c5f205SDaniel P. Berrange /** 11988c5f205SDaniel P. Berrange * buffer_end: 12088c5f205SDaniel P. Berrange * @buffer: the buffer object 12188c5f205SDaniel P. Berrange * 12288c5f205SDaniel P. Berrange * Get a pointer to the tail end of the internal buffer 12388c5f205SDaniel P. Berrange * The returned pointer is only valid until the next 12488c5f205SDaniel P. Berrange * call to buffer_reserve(). 12588c5f205SDaniel P. Berrange * 12688c5f205SDaniel P. Berrange * Returns: the tail of the buffer 12788c5f205SDaniel P. Berrange */ 12888c5f205SDaniel P. Berrange uint8_t *buffer_end(Buffer *buffer); 12988c5f205SDaniel P. Berrange 13088c5f205SDaniel P. Berrange /** 13188c5f205SDaniel P. Berrange * buffer_empty: 13288c5f205SDaniel P. Berrange * @buffer: the buffer object 13388c5f205SDaniel P. Berrange * 13488c5f205SDaniel P. Berrange * Determine if the buffer contains any current data 13588c5f205SDaniel P. Berrange * 13688c5f205SDaniel P. Berrange * Returns: true if the buffer holds data, false otherwise 13788c5f205SDaniel P. Berrange */ 13888c5f205SDaniel P. Berrange gboolean buffer_empty(Buffer *buffer); 13988c5f205SDaniel P. Berrange 1404d1eb5fdSGerd Hoffmann /** 1414d1eb5fdSGerd Hoffmann * buffer_move_empty: 1424d1eb5fdSGerd Hoffmann * @to: destination buffer object 1434d1eb5fdSGerd Hoffmann * @from: source buffer object 1444d1eb5fdSGerd Hoffmann * 1454d1eb5fdSGerd Hoffmann * Moves buffer, without copying data. 'to' buffer must be empty. 1464d1eb5fdSGerd Hoffmann * 'from' buffer is empty and zero-sized on return. 1474d1eb5fdSGerd Hoffmann */ 1484d1eb5fdSGerd Hoffmann void buffer_move_empty(Buffer *to, Buffer *from); 1494d1eb5fdSGerd Hoffmann 150830a9583SGerd Hoffmann /** 151830a9583SGerd Hoffmann * buffer_move: 152830a9583SGerd Hoffmann * @to: destination buffer object 153830a9583SGerd Hoffmann * @from: source buffer object 154830a9583SGerd Hoffmann * 155830a9583SGerd Hoffmann * Moves buffer, copying data (unless 'to' buffer happens to be empty). 156830a9583SGerd Hoffmann * 'from' buffer is empty and zero-sized on return. 157830a9583SGerd Hoffmann */ 158830a9583SGerd Hoffmann void buffer_move(Buffer *to, Buffer *from); 159830a9583SGerd Hoffmann 1602a6a4076SMarkus Armbruster #endif /* QEMU_BUFFER_H */ 161