xref: /openbsd-src/usr.sbin/npppd/common/bytebuf.c (revision 900232727d8ca397407d77938b18bd68e2f1189b)
1*90023272Smmcc /*	$OpenBSD: bytebuf.c,v 1.8 2015/12/05 18:43:36 mmcc Exp $ */
20fbf3537Syasuoka /*-
30fbf3537Syasuoka  * Copyright (c) 2009 Internet Initiative Japan Inc.
40fbf3537Syasuoka  * All rights reserved.
50fbf3537Syasuoka  *
60fbf3537Syasuoka  * Redistribution and use in source and binary forms, with or without
70fbf3537Syasuoka  * modification, are permitted provided that the following conditions
80fbf3537Syasuoka  * are met:
90fbf3537Syasuoka  * 1. Redistributions of source code must retain the above copyright
100fbf3537Syasuoka  *    notice, this list of conditions and the following disclaimer.
110fbf3537Syasuoka  * 2. Redistributions in binary form must reproduce the above copyright
120fbf3537Syasuoka  *    notice, this list of conditions and the following disclaimer in the
130fbf3537Syasuoka  *    documentation and/or other materials provided with the distribution.
140fbf3537Syasuoka  *
150fbf3537Syasuoka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
160fbf3537Syasuoka  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
170fbf3537Syasuoka  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
180fbf3537Syasuoka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
190fbf3537Syasuoka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
200fbf3537Syasuoka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
210fbf3537Syasuoka  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
220fbf3537Syasuoka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
230fbf3537Syasuoka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
240fbf3537Syasuoka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
250fbf3537Syasuoka  * SUCH DAMAGE.
260fbf3537Syasuoka  */
270fbf3537Syasuoka /**@file
280fbf3537Syasuoka  * bytebuffer provides 'byte buffer' helper methods.
290fbf3537Syasuoka  *
300fbf3537Syasuoka  * Example:<pre>
310fbf3537Syasuoka  *	bytebuffer *buf = bytebuffer_create(BUFSIZ);
320fbf3537Syasuoka  *	int sz = read(STDIN_FILENO, bytebuffer_pointer(buf),
330fbf3537Syasuoka  *	    bytebuffer_remaining(buf));
340fbf3537Syasuoka  *	if (sz > 0) {
350fbf3537Syasuoka  *	    bytebuffer_put(buf, BYTEBUFFER_PUT_DIRECT, sz);
360fbf3537Syasuoka  *	    bytebuffer_flip(buf);
370fbf3537Syasuoka  *
380fbf3537Syasuoka  *	    sz = write(STDOUT_FILENO, bytebuffer_pointer(buf),
390fbf3537Syasuoka  *		bytebuffer_remaining(buf));
400fbf3537Syasuoka  *	    bytebuffer_compact(buf);
410fbf3537Syasuoka  *	}</pre>
420fbf3537Syasuoka  *
430fbf3537Syasuoka  * @author Yasuoka Masahiko
44*90023272Smmcc  * $Id: bytebuf.c,v 1.8 2015/12/05 18:43:36 mmcc Exp $
450fbf3537Syasuoka  */
460fbf3537Syasuoka #include <stdlib.h>
470fbf3537Syasuoka #include <string.h>
480fbf3537Syasuoka #include <errno.h>
490fbf3537Syasuoka 
500fbf3537Syasuoka #ifdef	BYTEBUF_DEBUG
510fbf3537Syasuoka #include <stdio.h>
520fbf3537Syasuoka #endif
530fbf3537Syasuoka 
540fbf3537Syasuoka #ifndef	BYTEBUF_ASSERT
550fbf3537Syasuoka #ifdef	BYTEBUF_DEBUG
560fbf3537Syasuoka #define	BYTEBUF_ASSERT(cond)						\
570fbf3537Syasuoka 	if (!(cond)) {						\
580fbf3537Syasuoka 	    fprintf(stderr,					\
590fbf3537Syasuoka 		"\nASSERT(" #cond ") failed on %s() at %s:%d.\n"\
600fbf3537Syasuoka 		, __func__, __FILE__, __LINE__);		\
610fbf3537Syasuoka 	    abort(); 						\
620fbf3537Syasuoka 	}
630fbf3537Syasuoka #else
640fbf3537Syasuoka #define	BYTEBUF_ASSERT(cond)
650fbf3537Syasuoka #endif
660fbf3537Syasuoka #endif
670fbf3537Syasuoka 
680fbf3537Syasuoka #include "bytebuf.h"
690fbf3537Syasuoka 
700fbf3537Syasuoka struct _bytebuffer {
710fbf3537Syasuoka 	/** current position */
720fbf3537Syasuoka 	int 	position;
730fbf3537Syasuoka 	/** current limit */
740fbf3537Syasuoka 	int	limit;
750fbf3537Syasuoka 	/** position mark*/
760fbf3537Syasuoka 	int 	mark;
770fbf3537Syasuoka 	/** capacity of buffer */
780fbf3537Syasuoka 	size_t 	capacity;
790fbf3537Syasuoka 	/** allocated memory area */
800fbf3537Syasuoka 	void	*data;
810fbf3537Syasuoka };
820fbf3537Syasuoka 
830fbf3537Syasuoka /**
840fbf3537Syasuoka  * Create a bytebuffer and allocate memory area.
850fbf3537Syasuoka  *
860fbf3537Syasuoka  * @param	capacity	Capacity of allocating memory.  If zero or
870fbf3537Syasuoka  *		    negative value is specified, this function don't allocate
880fbf3537Syasuoka  *		    memory.
890fbf3537Syasuoka  */
900fbf3537Syasuoka bytebuffer *
bytebuffer_create(size_t capacity)910fbf3537Syasuoka bytebuffer_create(size_t capacity)
920fbf3537Syasuoka {
930fbf3537Syasuoka 	bytebuffer *_this = NULL;
940fbf3537Syasuoka 
951f03f1b3Syasuoka 	if ((_this = calloc(1, sizeof(bytebuffer))) == NULL)
960fbf3537Syasuoka 		return NULL;
970fbf3537Syasuoka 
980fbf3537Syasuoka 	if (capacity > 0) {
991f03f1b3Syasuoka 		if ((_this->data = calloc(1, capacity)) == NULL)
100f0a4e295Syasuoka 			goto fail;
1010fbf3537Syasuoka 		_this->capacity = capacity;
1020fbf3537Syasuoka 	} else
1030fbf3537Syasuoka 		_this->capacity = 0;
1040fbf3537Syasuoka 
1050fbf3537Syasuoka 	_this->limit = _this->capacity;
1060fbf3537Syasuoka 	_this->mark = -1;
1070fbf3537Syasuoka 	return _this;
108f0a4e295Syasuoka fail:
1090fbf3537Syasuoka 	free(_this);
1100fbf3537Syasuoka 	return NULL;
1110fbf3537Syasuoka }
1120fbf3537Syasuoka 
1130fbf3537Syasuoka /**
1140fbf3537Syasuoka  * Create a bytebuffer using existing memory area.  This memory area will
1150fbf3537Syasuoka  * be freed by bytebuffer's destructor.
1160fbf3537Syasuoka  *
1170fbf3537Syasuoka  * @data		the pointer to existing memory area
1180fbf3537Syasuoka  * @param capacity	capacity of 'data'.
1190fbf3537Syasuoka  */
1200fbf3537Syasuoka bytebuffer *
bytebuffer_wrap(void * data,size_t capacity)1210fbf3537Syasuoka bytebuffer_wrap(void *data, size_t capacity)
1220fbf3537Syasuoka {
1230fbf3537Syasuoka 	bytebuffer *_this;
1240fbf3537Syasuoka 
1250fbf3537Syasuoka 	if ((_this = bytebuffer_create(0)) == NULL)
1260fbf3537Syasuoka 		return NULL;
1270fbf3537Syasuoka 
1280fbf3537Syasuoka 	_this->data = data;
1290fbf3537Syasuoka 	_this->capacity = capacity;
1300fbf3537Syasuoka 	_this->mark = -1;
1310fbf3537Syasuoka 
1320fbf3537Syasuoka 	return _this;
1330fbf3537Syasuoka }
1340fbf3537Syasuoka 
1350fbf3537Syasuoka /**
1360fbf3537Syasuoka  * Unwrap memory from bytebuffer.
1370fbf3537Syasuoka  *
1380fbf3537Syasuoka  * @param _this		the bytebuffer object.
1390fbf3537Syasuoka  */
1400fbf3537Syasuoka void *
bytebuffer_unwrap(bytebuffer * _this)1410fbf3537Syasuoka bytebuffer_unwrap(bytebuffer *_this)
1420fbf3537Syasuoka {
1430fbf3537Syasuoka 	void *rval;
1440fbf3537Syasuoka 
1450fbf3537Syasuoka 	rval = _this->data;
1460fbf3537Syasuoka 	_this->data = NULL;
1470fbf3537Syasuoka 	_this->capacity = 0;
1480fbf3537Syasuoka 	_this->position = 0;
1490fbf3537Syasuoka 	_this->limit = 0;
1500fbf3537Syasuoka 	_this->mark = -1;
1510fbf3537Syasuoka 
1520fbf3537Syasuoka 	return rval;
1530fbf3537Syasuoka }
1540fbf3537Syasuoka 
1550fbf3537Syasuoka /**
1560fbf3537Syasuoka  * Change capacity of this buffer.
1570fbf3537Syasuoka  *
1580fbf3537Syasuoka  * @param _this		the bytebuffer object.
1590fbf3537Syasuoka  * @param capacity	new capacity.
1600fbf3537Syasuoka  */
1610fbf3537Syasuoka int
bytebuffer_realloc(bytebuffer * _this,size_t capacity)1620fbf3537Syasuoka bytebuffer_realloc(bytebuffer *_this, size_t capacity)
1630fbf3537Syasuoka {
1640fbf3537Syasuoka 	void *new_data;
1650fbf3537Syasuoka 
1660fbf3537Syasuoka 	BYTEBUF_ASSERT(_this->limit <= capacity);
1670fbf3537Syasuoka 
1680fbf3537Syasuoka 	if (_this->limit > capacity) {
1690fbf3537Syasuoka 		errno = EINVAL;
1700fbf3537Syasuoka 		return -1;
1710fbf3537Syasuoka 	}
1720fbf3537Syasuoka 
1730fbf3537Syasuoka 	if ((new_data = realloc(_this->data, capacity)) == NULL)
1740fbf3537Syasuoka 		return -1;
1750fbf3537Syasuoka 
1760fbf3537Syasuoka 	_this->data = new_data;
1770fbf3537Syasuoka 	if (_this->limit == _this->capacity)
1780fbf3537Syasuoka 		_this->limit = capacity;
1790fbf3537Syasuoka 	_this->capacity = capacity;
1800fbf3537Syasuoka 
1810fbf3537Syasuoka 	return 0;
1820fbf3537Syasuoka }
1830fbf3537Syasuoka 
1840fbf3537Syasuoka /**
1850fbf3537Syasuoka  * Compact this buffer.  the bytes between position and limit are copied
1860fbf3537Syasuoka  * to the beginning of the buffer.
1870fbf3537Syasuoka  *
1880fbf3537Syasuoka  * @param _this		the bytebuffer object.
1890fbf3537Syasuoka  */
1900fbf3537Syasuoka void
bytebuffer_compact(bytebuffer * _this)1910fbf3537Syasuoka bytebuffer_compact(bytebuffer *_this)
1920fbf3537Syasuoka {
1930fbf3537Syasuoka 	int len;
1940fbf3537Syasuoka 
1950fbf3537Syasuoka 	len = bytebuffer_remaining(_this);
1960fbf3537Syasuoka 
1970fbf3537Syasuoka 	if (len <= 0)
1980fbf3537Syasuoka 		len = 0;
1990fbf3537Syasuoka 	else if (_this->position != 0)
2000fbf3537Syasuoka 		memmove(_this->data,
2010fbf3537Syasuoka 		    (const char *)_this->data + _this->position, (size_t)len);
2020fbf3537Syasuoka 
2030fbf3537Syasuoka 	_this->position = len;
2040fbf3537Syasuoka 	_this->limit = _this->capacity;
2050fbf3537Syasuoka 	_this->mark = -1;
2060fbf3537Syasuoka }
2070fbf3537Syasuoka 
2080fbf3537Syasuoka static int bytebuffer_direct0;
2090fbf3537Syasuoka /**
2100fbf3537Syasuoka  * BYTEBUFFER_PUT_DIRECT specifies the data that has been written already by
2110fbf3537Syasuoka  * direct access.
2120fbf3537Syasuoka  */
2130fbf3537Syasuoka const void * BYTEBUFFER_PUT_DIRECT = &bytebuffer_direct0;
2140fbf3537Syasuoka 
2150fbf3537Syasuoka /**
2160fbf3537Syasuoka  * BYTEBUFFER_GET_DIRECT specifies the data that has been read already by
2170fbf3537Syasuoka  * direct access.
2180fbf3537Syasuoka  */
2190fbf3537Syasuoka void * BYTEBUFFER_GET_DIRECT = &bytebuffer_direct0;
2200fbf3537Syasuoka 
2210fbf3537Syasuoka /**
2220fbf3537Syasuoka  * Write the given data to the buffer.
2230fbf3537Syasuoka  * If buffer is too small, this function returns <code>NULL</code> and
2240fbf3537Syasuoka  * <code>errno</code> is <code>ENOBUFS</code>
2250fbf3537Syasuoka  *
2260fbf3537Syasuoka  * @param _this		the bytebuffer object.
2270fbf3537Syasuoka  * @param src		source data.  To specify the data that has been
2280fbf3537Syasuoka  *			written already by direct access, use
2290fbf3537Syasuoka  *			{@link ::BYTEBUFFER_PUT_DIRECT} for putting the data.
2300fbf3537Syasuoka  *			NULL is the same {@link ::BYTEBUFFER_PUT_DIRECT}
2310fbf3537Syasuoka  *			at least on this version, but using NULL is deprecated.
2320fbf3537Syasuoka  * @param srclen	length of the source data.
2330fbf3537Syasuoka  * @see ::BYTEBUFFER_PUT_DIRECT
2340fbf3537Syasuoka  */
2350fbf3537Syasuoka void *
bytebuffer_put(bytebuffer * _this,const void * src,size_t srclen)2360fbf3537Syasuoka bytebuffer_put(bytebuffer *_this, const void *src, size_t srclen)
2370fbf3537Syasuoka {
2380fbf3537Syasuoka 	void *rval;
2390fbf3537Syasuoka 
2400fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
2410fbf3537Syasuoka 	BYTEBUF_ASSERT(srclen > 0);
2420fbf3537Syasuoka 
2430fbf3537Syasuoka 	if (srclen > bytebuffer_remaining(_this)) {
2440fbf3537Syasuoka 		errno = ENOBUFS;
2450fbf3537Syasuoka 		return NULL;
2460fbf3537Syasuoka 	}
2470fbf3537Syasuoka 	rval = (char *)_this->data + _this->position;
2480fbf3537Syasuoka 
2490fbf3537Syasuoka 	if (src != NULL && src != BYTEBUFFER_PUT_DIRECT)
2500fbf3537Syasuoka 		memcpy(rval, src, srclen);
2510fbf3537Syasuoka 
2520fbf3537Syasuoka 	_this->position += srclen;
2530fbf3537Syasuoka 
2540fbf3537Syasuoka 	return rval;
2550fbf3537Syasuoka }
2560fbf3537Syasuoka 
2570fbf3537Syasuoka /*
2580fbf3537Syasuoka  * Transfer data from this buffer to the given destination memory.
2590fbf3537Syasuoka  * If the given buffer is too small, this function returns <code>NULL</code>
2600fbf3537Syasuoka  * and <code>errno</code> is <code>ENOBUFS</code>
2610fbf3537Syasuoka  *
2620fbf3537Syasuoka  * @param	dst	pointer of the destination memory.  Specify NULL
26398c26657Sguenther  *			to skip transferring the data.
2640fbf3537Syasuoka  * @param	dstlne	memory size of the destination.
2650fbf3537Syasuoka  */
2660fbf3537Syasuoka void *
bytebuffer_get(bytebuffer * _this,void * dst,size_t dstlen)2670fbf3537Syasuoka bytebuffer_get(bytebuffer *_this, void *dst, size_t dstlen)
2680fbf3537Syasuoka {
2690fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
2700fbf3537Syasuoka 	BYTEBUF_ASSERT(dstlen > 0);
2710fbf3537Syasuoka 
2720fbf3537Syasuoka 	if (dstlen > bytebuffer_remaining(_this)) {
2730fbf3537Syasuoka 		errno = ENOBUFS;
2740fbf3537Syasuoka 		return NULL;
2750fbf3537Syasuoka 	}
2760fbf3537Syasuoka 	if (dst != NULL && dst != BYTEBUFFER_GET_DIRECT)
2770fbf3537Syasuoka 		memcpy(dst, (char *)_this->data + _this->position, dstlen);
2780fbf3537Syasuoka 
2790fbf3537Syasuoka 	_this->position += dstlen;
2800fbf3537Syasuoka 
2810fbf3537Syasuoka 	return dst;
2820fbf3537Syasuoka }
2830fbf3537Syasuoka 
2840fbf3537Syasuoka /** Returns this buffer's position */
2850fbf3537Syasuoka int
bytebuffer_position(bytebuffer * _this)2860fbf3537Syasuoka bytebuffer_position(bytebuffer *_this)
2870fbf3537Syasuoka {
2880fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
2890fbf3537Syasuoka 
2900fbf3537Syasuoka 	return _this->position;
2910fbf3537Syasuoka }
2920fbf3537Syasuoka 
2930fbf3537Syasuoka /** Returns this buffer's limit */
2940fbf3537Syasuoka int
bytebuffer_limit(bytebuffer * _this)2950fbf3537Syasuoka bytebuffer_limit(bytebuffer *_this)
2960fbf3537Syasuoka {
2970fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
2980fbf3537Syasuoka 
2990fbf3537Syasuoka 	return _this->limit;
3000fbf3537Syasuoka }
3010fbf3537Syasuoka 
3020fbf3537Syasuoka /** Returns this buffer's capacity */
3030fbf3537Syasuoka int
bytebuffer_capacity(bytebuffer * _this)3040fbf3537Syasuoka bytebuffer_capacity(bytebuffer *_this)
3050fbf3537Syasuoka {
3060fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3070fbf3537Syasuoka 
3080fbf3537Syasuoka 	return _this->capacity;
3090fbf3537Syasuoka }
3100fbf3537Syasuoka 
3110fbf3537Syasuoka /** Returns a pointer to current position */
3120fbf3537Syasuoka void *
bytebuffer_pointer(bytebuffer * _this)3130fbf3537Syasuoka bytebuffer_pointer(bytebuffer *_this)
3140fbf3537Syasuoka {
3150fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3160fbf3537Syasuoka 
3170fbf3537Syasuoka 	return (char *)_this->data + _this->position;
3180fbf3537Syasuoka }
3190fbf3537Syasuoka 
3200fbf3537Syasuoka /** Returns the number of byte between current position and the limit*/
3210fbf3537Syasuoka size_t
bytebuffer_remaining(bytebuffer * _this)3220fbf3537Syasuoka bytebuffer_remaining(bytebuffer *_this)
3230fbf3537Syasuoka {
3240fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3250fbf3537Syasuoka 	BYTEBUF_ASSERT(_this->limit >= _this->position);
3260fbf3537Syasuoka 
3270fbf3537Syasuoka 	return _this->limit - _this->position;
3280fbf3537Syasuoka }
3290fbf3537Syasuoka 
3300fbf3537Syasuoka /** Returns whether there are data between current position and the limit */
3310fbf3537Syasuoka int
bytebuffer_has_remaining(bytebuffer * _this)3320fbf3537Syasuoka bytebuffer_has_remaining(bytebuffer *_this)
3330fbf3537Syasuoka {
3340fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3350fbf3537Syasuoka 
3360fbf3537Syasuoka 	return bytebuffer_remaining(_this) > 0;
3370fbf3537Syasuoka }
3380fbf3537Syasuoka 
3390fbf3537Syasuoka /**
3400fbf3537Syasuoka  * Flip this buffer.
3410fbf3537Syasuoka  * The limit is set to the position and the position is set zero.
3420fbf3537Syasuoka  */
3430fbf3537Syasuoka void
bytebuffer_flip(bytebuffer * _this)3440fbf3537Syasuoka bytebuffer_flip(bytebuffer *_this)
3450fbf3537Syasuoka {
3460fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3470fbf3537Syasuoka 
3480fbf3537Syasuoka 	_this->limit = _this->position;
3490fbf3537Syasuoka 	_this->position = 0;
3500fbf3537Syasuoka 	_this->mark = -1;
3510fbf3537Syasuoka }
3520fbf3537Syasuoka 
3530fbf3537Syasuoka /**
3540fbf3537Syasuoka  * Rewind this buffer.
3550fbf3537Syasuoka  * The position is set to zero.
3560fbf3537Syasuoka  */
3570fbf3537Syasuoka void
bytebuffer_rewind(bytebuffer * _this)3580fbf3537Syasuoka bytebuffer_rewind(bytebuffer *_this)
3590fbf3537Syasuoka {
3600fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3610fbf3537Syasuoka 
3620fbf3537Syasuoka 	_this->position = 0;
3630fbf3537Syasuoka 	_this->mark = -1;
3640fbf3537Syasuoka }
3650fbf3537Syasuoka 
3660fbf3537Syasuoka /**
3670fbf3537Syasuoka  * Clear this buffer.
3680fbf3537Syasuoka  * The position is set to zero.
3690fbf3537Syasuoka  */
3700fbf3537Syasuoka void
bytebuffer_clear(bytebuffer * _this)3710fbf3537Syasuoka bytebuffer_clear(bytebuffer *_this)
3720fbf3537Syasuoka {
3730fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3740fbf3537Syasuoka 
3750fbf3537Syasuoka 	_this->limit = _this->capacity;
3760fbf3537Syasuoka 	_this->position = 0;
3770fbf3537Syasuoka 	_this->mark = -1;
3780fbf3537Syasuoka }
3790fbf3537Syasuoka 
3800fbf3537Syasuoka /** mark the current position.  */
3810fbf3537Syasuoka void
bytebuffer_mark(bytebuffer * _this)3820fbf3537Syasuoka bytebuffer_mark(bytebuffer *_this)
3830fbf3537Syasuoka {
3840fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3850fbf3537Syasuoka 
3860fbf3537Syasuoka 	_this->mark = _this->position;
3870fbf3537Syasuoka }
3880fbf3537Syasuoka 
3890fbf3537Syasuoka /** reset the position to the mark.  */
3900fbf3537Syasuoka void
bytebuffer_reset(bytebuffer * _this)3910fbf3537Syasuoka bytebuffer_reset(bytebuffer *_this)
3920fbf3537Syasuoka {
3930fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
3940fbf3537Syasuoka 	BYTEBUF_ASSERT(_this->mark >= 0);
3950fbf3537Syasuoka 
3960fbf3537Syasuoka 	if (_this->mark >= 0)
3970fbf3537Syasuoka 		_this->position = _this->mark;
3980fbf3537Syasuoka }
3990fbf3537Syasuoka 
4000fbf3537Syasuoka /**
4010fbf3537Syasuoka  * Destroy bytebuffer object.
4020fbf3537Syasuoka  */
4030fbf3537Syasuoka void
bytebuffer_destroy(bytebuffer * _this)4040fbf3537Syasuoka bytebuffer_destroy(bytebuffer *_this)
4050fbf3537Syasuoka {
4060fbf3537Syasuoka 	BYTEBUF_ASSERT(_this != NULL);
4070fbf3537Syasuoka 
4080fbf3537Syasuoka 	if (_this != NULL) {
4090fbf3537Syasuoka 		free(_this->data);
4100fbf3537Syasuoka 		free(_this);
4110fbf3537Syasuoka 	}
4120fbf3537Syasuoka }
413