buffer.h 5.68 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* Icecast
 *
 * This program is distributed under the GNU General Public License, version 2.
 * A copy of this license is included with this source.
 *
 * Copyright 2018,      Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
 */

/*
 * This file contains the API for a refobject based buffer object.
 * It can be used to store data and allows on the fly re-allocation.
 */

#ifndef __BUFFER_H__
#define __BUFFER_H__

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

21 22
#include <stdarg.h>

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
#include "icecasttypes.h"
#include "compat.h"
#include "refobject.h"

/* About thread safety:
 * This set of functions is intentinally not thread safe.
 */

/* This creates a new buffer object.
 * Parameters:
 *  preallocation
 *      The number of bytes to allocate for use later on. See buffer_preallocate() for details.
 *  userdata, name, associated
 *      See refobject_new().
 */
buffer_t *  buffer_new(ssize_t preallocation, void *userdata, const char *name, refobject_t associated);

/* This creates a new buffer with defaults.
 * This is the same as:
 *  buffer_new(-1, NULL, NULL, REFOBJECT_NULL)
 */
buffer_t *  buffer_new_simple(void);

/* This function preallocates space for later use.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  request
 *      Number of bytes to additionally allocate.
 * Notes:
 *  This function is very usedful when adding a large number of smaller buffers to avoid
 *  internal reallocation calls happening to often. However it is not required to call
 *  this function before adding data to the buffer.
 */
void        buffer_preallocate(buffer_t *buffer, size_t request);

/* Gets data and length of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  data
 *      Pointer to the stored data. If NULL the pointer is not returned.
 *  length
 *      Pointer to the length of how many bytes are in the buffer. If NULL
 *      length is not returned.
 */
int         buffer_get_data(buffer_t *buffer, const void **data, size_t *length);

/* Gets data as a string. The string is '\0'-terminated.
 * Parameters:
 *  buffery
 *      The buffer to operate on.
 *  string
 *      The string representing the data hold by the buffer.
 */
int         buffer_get_string(buffer_t *buffer, const char **string);

/* Sets the length of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  length
 *      New length of the buffer.
 * Notes:
 *  This can only be used to reduce the size of the buffer. To add data to
 *  the buffer use buffer_push_*().
 *
 *  Calling this with length set to 0 clears the buffer but does not deallocate it.
 */
int         buffer_set_length(buffer_t *buffer, size_t length);

/* Shifts data out of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  amount
 *      The amount of bytes to be removed from the begin of the buffer.
 * Notes:
 *  This function can be useful for skipping some small header. However this
 *  must not be used to implement a kind of ring buffer as it will result in
 *  poor performance caused by massive reallocations and memory copies.
 */
int         buffer_shift(buffer_t *buffer, size_t amount);

/* This pushes data to the end of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  data
 *      The data to push.
 *  length
 *      The length of the data to push in byte.
 * Notes:
 *  Consider using buffer_zerocopy_*().
 */
int         buffer_push_data(buffer_t *buffer, const void *data, size_t length);

/* This pushes a string to the end of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  string
 *      The string to be pushed. The tailing '\0'-termination will not be
 *      part of the buffer.
 * Notes:
 *  Consider using buffer_zerocopy_*().
 */
int         buffer_push_string(buffer_t *buffer, const char *string);

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/* This pushes a formated string to the end of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  format
 *      The format string as for printf() family functions.
 *  ...
 *      The parameters according to the format string.
 */
int         buffer_push_printf(buffer_t *buffer, const char *format, ...);

/* This pushes a formated string to the end of the buffer using a va_list.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  format
 *      The format string as for printf() family functions.
 *  ap
 *      The parameters according to the format string as va_list.
 * See also:
 *  vprintf(3).
 */
int         buffer_push_vprintf(buffer_t *buffer, const char *format, va_list ap);

156 157 158 159 160 161 162 163 164
/* This pushes the content of another buffer to the end of the buffer.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  source
 *      The buffer which's content is to be copied.
 */
int         buffer_push_buffer(buffer_t *buffer, buffer_t *source);

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
/* This requests for a memory buffer that can be pushed to without the need for copy.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  data
 *      Pointer to memory that can be written and will become part of the buffer object.
 *  request
 *      Size of the memory area that is returned by data in bytes.
 * Notes:
 *  This is the first step of the zero copy push. After the memory returned by data has been
 *  written (e.g. used in a call to read(2)) buffer_zerocopy_push_complete() must be called.
 */
int         buffer_zerocopy_push_request(buffer_t *buffer, void **data, size_t request);

/* This is the final step of a zero copy push.
 * Parameters:
 *  buffer
 *      The buffer to operate on.
 *  done
 *      Amount of data in bytes that has actually been written into the memory area.
Philipp Schafft's avatar
Philipp Schafft committed
185
 *      May be zero to what has been requested with request.
186 187 188 189
 */
int         buffer_zerocopy_push_complete(buffer_t *buffer, size_t done);

#endif