⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mprbuf.c

📁 samba最新软件
💻 C
字号:
/** *	@file 	mprBuf.c *	@brief	Dynamic buffer module *	@overview  *	@remarks  *//******************************************************************************//* *	@copy	default *	 *	Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. *	 *	This software is distributed under commercial and open source licenses. *	You may use the GPL open source license described below or you may acquire  *	a commercial license from Mbedthis Software. You agree to be fully bound  *	by the terms of either license. Consult the LICENSE.TXT distributed with  *	this software for full details. *	 *	This software is open source; you can redistribute it and/or modify it  *	under the terms of the GNU General Public License as published by the  *	Free Software Foundation; either version 2 of the License, or (at your  *	option) any later version. See the GNU General Public License for more  *	details at: http://www.mbedthis.com/downloads/gplLicense.html *	 *	This program is distributed WITHOUT ANY WARRANTY; without even the  *	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  *	 *	This GPL license does NOT permit incorporating this software into  *	proprietary programs. If you are unable to comply with the GPL, you must *	acquire a commercial license to use this software. Commercial licenses  *	for this software and support services are available from Mbedthis  *	Software at http://www.mbedthis.com  *	 *	@end *//********************************** Includes **********************************/#include	"mpr.h"/**************************** Forward Declarations ****************************/static int grow(MprBuf *bp);/*********************************** Code *************************************//* *	Create a new buffer. "maxsize" is the limit to which the buffer can  *	ever grow. -1 means no limit. The buffer can ever only fix maxsize-1 bytes. *	"initialSize" is used to define the amount to increase the size of the  *	buffer each time if it becomes full. (Note: grow() will exponentially  *	increase this number for performance.) */MprBuf *mprCreateBuf(MprCtx ctx, int initialSize, int maxSize){	MprBuf		*bp;		if (initialSize <= 0) {		initialSize = MPR_DEFAULT_ALLOC;	}	bp = mprAllocTypeZeroed(ctx, MprBuf);	bp->growBy = MPR_BUFSIZE;	bp->maxsize = 0;	mprSetBufSize(bp, initialSize, maxSize);	return bp;}/******************************************************************************//* *	Set the initial buffer parameters and create the first buffer */void mprSetBufSize(MprBuf *bp, int initialSize, int max){	mprAssert(initialSize > 0);	if (max > 0 && initialSize > max) {		initialSize = max;	}	if (bp->buf && bp->growBy > 0) {		mprFree(bp->buf);	}	bp->buf = (uchar*) mprAlloc(bp, initialSize);	bp->growBy = initialSize;	bp->maxsize = max;	bp->buflen = initialSize;	bp->endbuf = &bp->buf[bp->buflen];	bp->start = bp->buf;	bp->end = bp->buf;	*bp->start = '\0';}/******************************************************************************/char *mprStealBuf(MprCtx ctx, MprBuf *bp){	char	*str;	str = (char*) bp->start;	mprStealAllocBlock(MPR_LOC_ARGS(ctx), bp->start);	bp->start = bp->end = bp->buf = bp->endbuf = 0;	bp->buflen = 0;	return str;}/******************************************************************************/void mprAddNullToBuf(MprBuf *bp){	*((char*) bp->end) = (char) '\0';}/******************************************************************************/void mprAdjustBufEnd(MprBuf *bp, int size){	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	mprAssert(size < bp->buflen);	bp->end += size;	if (bp->end >= bp->endbuf) {		bp->end -= bp->buflen;	}	if (bp->end < bp->buf) {		bp->end += bp->buflen;	}	if (bp->end >= bp->endbuf) {		mprAssert(bp->end < bp->endbuf);		mprFlushBuf(bp);	}}/******************************************************************************//* *	Adjust the start pointer after a user copy */void mprAdjustBufStart(MprBuf *bp, int size){	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	mprAssert(size < bp->buflen);	bp->start += size;	while (bp->start >= bp->endbuf) {		bp->start -= bp->buflen;	}	while (bp->start < bp->buf) {		bp->start += bp->buflen;	}	/*	 *	Flush the buffer if the start pointer is corrupted via a bad size 	 */	if (bp->start >= bp->endbuf) {		mprAssert(bp->start < bp->endbuf);		mprFlushBuf(bp);	}}/******************************************************************************/void mprFlushBuf(MprBuf *bp){	bp->start = bp->buf;	bp->end = bp->buf;}/******************************************************************************/int mprGetCharFromBuf(MprBuf *bp){	int		c;	if (bp->start == bp->end) {		return -1;	}	c = (uchar) *bp->start++;	if (bp->start >= bp->endbuf) {		bp->start = bp->buf;	}	return c;}/******************************************************************************/int mprGetBlockFromBuf(MprBuf *bp, uchar *buf, int size){	int		thisLen, bytesRead;	mprAssert(buf);	mprAssert(size > 0);	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	/*	 *	Get the max bytes in a straight copy	 */	bytesRead = 0;	while (size > 0) {		thisLen = mprGetBufLinearData(bp);		thisLen = min(thisLen, size);		if (thisLen <= 0) {			break;		}		memcpy(buf, bp->start, thisLen);		buf += thisLen;		bp->start += thisLen;		size -= thisLen;		bytesRead += thisLen;		if (bp->start >= bp->endbuf) {			bp->start = bp->buf;		}	}	return bytesRead;}/******************************************************************************/int mprGetBufLength(MprBuf *bp){	if (bp->start > bp->end) {		return (bp->buflen + (bp->end - bp->start));	} else {		return (bp->end - bp->start);	}}/******************************************************************************/int mprGetBufLinearData(MprBuf *bp){	return min(mprGetBufLength(bp), (bp->endbuf - bp->start));}/******************************************************************************/int mprGetBufLinearSpace(MprBuf *bp){	int len = mprGetBufLength(bp);	int space = bp->buflen - len - 1;	return min((bp->endbuf - bp->end), space);}/******************************************************************************/int mprGetBufSize(MprBuf *bp){	return bp->buflen;}/******************************************************************************/int mprGetBufSpace(MprBuf *bp){	return bp->buflen - mprGetBufLength(bp) - 1;}/******************************************************************************/char *mprGetBufOrigin(MprBuf *bp){	return (char*) bp->buf;}/******************************************************************************/char *mprGetBufStart(MprBuf *bp){	return (char*) bp->start;}/******************************************************************************/char *mprGetBufEnd(MprBuf *bp){	return (char*) bp->end;}/******************************************************************************/int mprInsertCharToBuf(MprBuf *bp, int c){	char	*cp;	int		space;	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	space = bp->buflen - mprGetBufLength(bp) - 1;	if (space < (int) sizeof(char)) {		if (!grow(bp)) {			return -1;		}	}	if (bp->start <= bp->buf) {		bp->start = bp->endbuf;	}	cp = (char*) bp->start;	*--cp = (char) c;	bp->start = (uchar *) cp;	return 0;}/******************************************************************************/int mprLookAtNextCharInBuf(MprBuf *bp){	if (bp->start == bp->end) {		return -1;	}	return *bp->start;}/******************************************************************************/int mprLookAtLastCharInBuf(MprBuf *bp){	if (bp->start == bp->end) {		return -1;	}	return (bp->end == bp->buf) ? bp->endbuf[-1] : bp->end[-1];}/******************************************************************************/int mprPutCharToBuf(MprBuf *bp, int c){	char	*cp;	int		space;	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	space = bp->buflen - mprGetBufLength(bp) - 1;	if (space < (int) sizeof(char)) {		if (! grow(bp)) {			return -1;		}	}	cp = (char*) bp->end;	*cp++ = (char) c;	bp->end = (uchar *) cp;	if (bp->end >= bp->endbuf) {		bp->end = bp->buf;	}	*((char*) bp->end) = (char) '\0';	return 0;}/******************************************************************************/int mprPutBlockToBuf(MprBuf *bp, const char *str, int size){	int		thisLen, bytes, space;	mprAssert(str);	mprAssert(size >= 0);	mprAssert(bp->buflen == (bp->endbuf - bp->buf));	/*	 *	Add the max we can in one copy	 */	bytes = 0;	while (size > 0) {		space = mprGetBufLinearSpace(bp);		thisLen = min(space, size);		if (thisLen <= 0) {			if (! grow(bp)) {				break;			}			space = mprGetBufLinearSpace(bp);			thisLen = min(space, size);		}		memcpy(bp->end, str, thisLen);		str += thisLen;		bp->end += thisLen;		size -= thisLen;		bytes += thisLen;		if (bp->end >= bp->endbuf) {			bp->end = bp->buf;		}	}	*((char*) bp->end) = (char) '\0';	return bytes;}/******************************************************************************/int mprPutStringToBuf(MprBuf *bp, const char *str){	return mprPutBlockToBuf(bp, str, strlen(str));}/******************************************************************************/int mprPutFmtStringToBuf(MprBuf *bp, const char *fmt, ...){	va_list		ap;	char		*buf;	int			rc, len, space;	va_start(ap, fmt);	space = mprGetBufLinearSpace(bp);	/*	 *	Add max that the buffer can grow 	 */	space += (bp->maxsize - bp->buflen - 1);	len = mprAllocVsprintf(MPR_LOC_ARGS(bp), &buf, space, fmt, ap);	rc = mprPutBlockToBuf(bp, buf, len);	mprFree(buf);	va_end(ap);	return rc;}/******************************************************************************//* *	Grow the buffer to fit new data. Return 1 if the buffer can grow.  *	Grow using the growBy size specified when creating the buffer.  */static int grow(MprBuf *bp){	uchar	*newbuf;	if (bp->maxsize > 0 && bp->buflen >= bp->maxsize) {		return 0;	}	newbuf = (uchar*) mprAlloc(bp, bp->buflen + bp->growBy);	if (bp->buf) {		memcpy(newbuf, bp->buf, bp->buflen);		mprFree(bp->buf);	}	bp->buflen += bp->growBy;	bp->end = newbuf + (bp->end - bp->buf);	bp->start = newbuf + (bp->start - bp->buf);	bp->buf = newbuf;	bp->endbuf = &bp->buf[bp->buflen];	/*	 *	Increase growBy to reduce overhead	 */	bp->growBy *= 2;	if (bp->maxsize > 0 && (bp->buflen + bp->growBy) > bp->maxsize) {		bp->growBy = bp->maxsize - bp->buflen;	}	return 1;}/******************************************************************************//* *	Add a number to the buffer (always null terminated). */int mprPutIntToBuf(MprBuf *bp, int i){	char	numBuf[16];	int		rc;	mprItoa(numBuf, sizeof(numBuf), i);	rc = mprPutStringToBuf(bp, numBuf);	*((char*) bp->end) = (char) '\0';	return rc;}/******************************************************************************/void mprCopyBufDown(MprBuf *bp){	if (mprGetBufLength(bp) == 0) {		mprFlushBuf(bp);		return;	}	memmove(bp->buf, bp->start, (bp->end - bp->start));	bp->end -= (bp->start - bp->buf);	bp->start = bp->buf;}/******************************************************************************/MprBufProc mprGetBufRefillProc(MprBuf *bp) {	return bp->refillProc;}/******************************************************************************/void mprSetBufRefillProc(MprBuf *bp, MprBufProc fn, void *arg){ 	bp->refillProc = fn; 	bp->refillArg = arg; }/******************************************************************************/int	mprRefillBuf(MprBuf *bp) { 	return (bp->refillProc) ? (bp->refillProc)(bp, bp->refillArg) : 0; }/******************************************************************************/void mprResetBufIfEmpty(MprBuf *bp){	if (mprGetBufLength(bp) == 0) {		mprFlushBuf(bp);	}}/******************************************************************************//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -