windows-nt/Source/XPSP1/NT/enduser/stuff/itircl/common/util/bfnew.c
2020-09-26 16:20:57 +08:00

195 lines
3.9 KiB
C

#include <mvopsys.h>
#include <orkin.h>
#include <mem.h>
#include "bfnew.h"
#if defined(_DEBUG)
static char * s_aszModule = __FILE__; /* For error report */
#endif
#ifndef MAXWORD
#define MAXWORD ((WORD)0xffff)
#endif
/***************************************************************************
*
- Name DynBufferAlloc
-
* Purpose
* Creates a new buffer.
*
* Arguments
* int cIncr: Minimum increment size for this buffer.
*
* Returns
* Pointer to a new buffer. Returns pNil on OOM.
*
* +++
*
* Notes
*
***************************************************************************/
LPBF DynBufferAlloc( DWORD cIncr )
{
LPBF pbf;
HANDLE hnd;
if ((hnd = _GLOBALALLOC ((GMEM_MOVEABLE|GMEM_ZEROINIT), sizeof (BF) )) == NULL)
return NULL;
pbf = (LPBF)_GLOBALLOCK (hnd);
pbf->hnd = hnd;
pbf->cIncr = cIncr;
pbf->cbMax = cIncr;
pbf->cbSize = 0;
if ((pbf->hBuf = _GLOBALALLOC (GMEM_MOVEABLE | GMEM_ZEROINIT,
(LONG)cIncr)) == 0) {
_GLOBALUNLOCK( hnd);
_GLOBALFREE (hnd);
return NULL;
}
pbf->qBuffer = _GLOBALLOCK (pbf->hBuf);
return pbf;
}
// inserts the given data at the byte position given by the argument.
// returns a pointer to the buffer at that byte position if successful.
LPBYTE DynBufferInsert(LPBF lpbf, DWORD lib, LPBYTE qbData, SHORT cbData)
{
LPBYTE lpbInsert;
//LPBYTE lpbCur;
int cbSizeOld = lpbf->cbSize;
// grow the buffer by cbData bytes
if ((cbData == 0) || !DynBufferEnsureAdd(lpbf, cbData))
return NULL;
assert( lpbf->cbMax >= lpbf->cbSize + cbData );
// note that we set these vars here, since DynBufferEnsure may cause a resize
lpbInsert = (LPBYTE)(lpbf->qBuffer) + lib;
//lpbCur = (LPBYTE)(lpbf->qBuffer) + cbSizeOld; // first byte of expanded buffer
// shift the existing data down if necessary
//if (lpbCur != lpbInsert)
MEMMOVE(lpbInsert + cbData, lpbInsert, cbSizeOld - lib);
// bring in new stuff if necessary
if (qbData)
MEMCPY(lpbInsert, qbData, cbData);
lpbf->cbSize += cbData;
return lpbInsert;
}
/***************************************************************************
*
- Name DynBufferAppend
-
* Purpose
* Adds data to a buffer.
*
* Arguments
* PBF -- pointer to buffer.
* QV -- pointer to data to copy.
* WORD -- amount of data to copy.
*
* Returns
* rcOutOfMemory if we run out of memory
* rcFailure if we try to add more than 64K bytes of data to the
* buffer
* rcSuccess otherwise.
*
* +++
*
* Notes
*
***************************************************************************/
LPBYTE DynBufferAppend(LPBF lpbf, LPBYTE qData, DWORD cb )
{
if (!DynBufferEnsureAdd(lpbf, cb))
return NULL;
assert( lpbf->cbMax >= lpbf->cbSize + cb );
if (qData)
MEMCPY ((LPBYTE)lpbf->qBuffer + lpbf->cbSize, qData, cb);
lpbf->cbSize += cb;
return((LPBYTE)(lpbf->qBuffer));
}
// Ensures that there is space in the buffer to
// add <w> bytes
BOOL InternalEnsureAdd(LPBF lpbf, DWORD w)
{
#ifndef _WIN32
if (lpbf->cbSize > 0xffff - w)
return FALSE;
#endif
if (w > lpbf->cIncr)
lpbf->cbMax += w;
else
lpbf->cbMax += lpbf->cIncr;
_GLOBALUNLOCK (lpbf->hBuf);
if ((lpbf->hBuf =_GLOBALREALLOC (lpbf->hBuf,
(LONG)lpbf->cbMax, GMEM_MOVEABLE | GMEM_ZEROINIT)) == 0)
{
lpbf->qBuffer = NULL;
return FALSE;
}
lpbf->qBuffer = _GLOBALLOCK (lpbf->hBuf);
return TRUE;
}
/***************************************************************************
*
- Name DynBufferFree
-
* Purpose
* Frees an allocated buffer.
*
* Arguments
* Pointer to buffer.
*
* Returns
* nothing.
*
* +++
*
* Notes
* See also EmptyPbf, which empties the buffer but leaves it available
* for re-use.
*
***************************************************************************/
VOID DynBufferFree( LPBF pbf )
{
HANDLE hnd;
if (pbf == 0)
return;
if (hnd = pbf->hBuf)
{
_GLOBALUNLOCK (hnd);
_GLOBALFREE(hnd);
}
if (hnd = pbf->hnd)
{
_GLOBALUNLOCK(hnd);
_GLOBALFREE (hnd);
}
}