wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,535 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
Reference in New Issue
Block a user