coderbitbuffer.c
来自「基于h323协议的软phone」· C语言 代码 · 共 416 行
C
416 行
/***********************************************************************
Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..
RADVISION Ltd. reserve the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
***********************************************************************/
#include "rvstdio.h"
#include "copybits.h"
#include "coderbitbuffer.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
Desc: Set correct number of bytes in length of bits.
*/
unsigned int
bbSetByte(RvUint32 bitLength)
{
unsigned int bytes = (int)(bitLength/8);
if (bitLength%8) bytes++; /* complete the last byte. */
return bytes;
}
/*_____________________________________________________________________*/
/*_________________________________MODULE______________________________*/
/*_____________________________________________________________________*/
int
bbGetAllocationSize(int maxOctets)
{
return sizeof(bbStruct) + maxOctets;
}
static bbStruct *
bbBuild(IN char *buffer,
IN int maxOctets)
{
bbStruct *bb;
memset(buffer, 0, bbGetAllocationSize(maxOctets));
bb = (bbStruct *)buffer;
bb->maxOctets = maxOctets;
bb->bitsInUse = 0;
bb->isAligned = RV_TRUE;
bb->octets = (RvUint8 *)bb + sizeof(bbStruct);
bb->isOverflowOfBuffer = RV_FALSE;
return bb;
}
/*
Desc: Construct bb from user specified memory location.
Note: user memory size should be at least the size of bb structure!
*/
HBB
bbConstructFrom(IN int maxOctets, /* size of buffer in octetes */
IN char *buffer,
IN int bufferSize)
{
bbStruct *bb;
if (!buffer || bufferSize < bbGetAllocationSize(maxOctets)) return NULL;
bb = bbBuild(buffer, maxOctets);
return (HBB)bb;
}
/*
Desc: Set the octets to be octetBuffer.
Usage: for user allocated buffer.
*/
int
bbSetOctets(IN HBB bbH,
IN int maxOctets, /* size of buffer in octets */
IN RvInt32 bitsInUse, /* number of bits already in use */
IN RvUint8 *octetBuffer) /* octet memory */
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb || !octetBuffer) return RV_ERROR_UNKNOWN;
bb->maxOctets = maxOctets;
bb->bitsInUse = bitsInUse;
bb->isAligned = RV_TRUE;
bb->octets = octetBuffer;
return RV_TRUE;
}
int
bbDestruct(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
return RV_TRUE;
}
/* set buffer to zeros */
int
bbClear(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
bb->bitsInUse = 0;
bb->isAligned = RV_TRUE;
memset(bb->octets, 0, bb->maxOctets);
return RV_TRUE;
}
/*_____________________________________________________________________*/
/*_________________________________STATUS______________________________*/
/*_____________________________________________________________________*/
/* returns pointer to the octet array */
RvUint8 *
bbOctets(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return NULL;
return bb->octets;
}
/* RV_TRUE if buffer is aligned */
RvBool
bbIsAligned(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_FALSE;
return bb->isAligned;
}
/* return number of alignment bits (modulu 8) */
int
bbAlignBits(HBB bbH,
IN RvInt32 location)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
return (8 - (int)location%8)%8;
}
/* set buffer alignment */
int
bbSetAligned(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
bb->isAligned = RV_TRUE;
return RV_TRUE;
}
int
bbSetUnaligned(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
bb->isAligned = RV_FALSE;
return RV_TRUE;
}
/*
Desc: Return number of BITS left free in buffer. Meaning you may add
up to this number of bits to buffer.
*/
RvInt32
bbFreeBits(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
return (int)(bb->maxOctets*8l - bb->bitsInUse);
}
/*
Desc: Return number of BYTES left free in buffer. Meaning you may add
up to this number of bytes to buffer. rounded up.
*/
int
bbFreeBytes(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
return (bb->maxOctets - bbSetByte(bb->bitsInUse));
}
/*
Desc: Return number of BITS currently in buffer.
*/
RvUint32
bbBitsInUse(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return (unsigned)RV_ERROR_UNKNOWN;
return bb->bitsInUse;
}
/*
Desc: Return number of BYTES currently in buffer.
*/
unsigned
bbBytesInUse(HBB bbH)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return (unsigned)RV_ERROR_UNKNOWN;
return bbSetByte(bb->bitsInUse);
}
/*_____________________________________________________________________*/
/*_________________________________UPDATE______________________________*/
/*_____________________________________________________________________*/
/* concatate src to buffer */
int
bbAddTail(HBB bbH,
IN RvUint8 *src,
IN RvUint32 srcBitsLength,
IN RvBool isAligned) /* true if src is aligned */
{
bbStruct *bb = (bbStruct *)bbH;
RvInt32 bbPos, align;
RvUint8 ch=0;
if (!bb || (!src && srcBitsLength!=0)) return RV_ERROR_UNKNOWN;
bbPos = bb->bitsInUse;
if (isAligned) { /* align to octet boundery. 0 padding */
align = bbAlignBits(bbH, bbPos);
memcpyb(bb->octets, bbPos, &ch, 0, align);
bbPos += align;
}
if (bbPos + srcBitsLength > bb->maxOctets*8l)
{
bb->isOverflowOfBuffer=RV_TRUE;
return RV_ERROR_UNKNOWN; /* no place */
}
memcpyb(bb->octets, bbPos, src, 0, srcBitsLength);
bb->bitsInUse = bbPos + srcBitsLength;
return RV_TRUE;
}
/* concatate src to buffer */
int
bbAddTailFrom(HBB bbH,
IN RvUint8 *src,
IN RvUint32 srcFrom, /* offset for beginning of data in src, in bits */
IN RvUint32 srcBitsLength,
IN RvBool isAligned) /* true if src is aligned */
{
bbStruct *bb = (bbStruct *)bbH;
RvInt32 bbPos, align;
RvUint8 ch=0;
if (!bb || !src) return RV_ERROR_UNKNOWN;
bbPos = bb->bitsInUse;
if (isAligned) { /* align to octet boundery. 0 padding */
align = bbAlignBits(bbH, bbPos);
memcpyb(bb->octets, bbPos, &ch, 0, align);
bbPos += align;
}
if (bbPos + srcBitsLength > bb->maxOctets*8l)
{
bb->isOverflowOfBuffer=RV_TRUE;
return RV_ERROR_UNKNOWN; /* no place */
}
memcpyb(bb->octets, bbPos, src, srcFrom, srcBitsLength);
bb->bitsInUse = bbPos + srcBitsLength;
return RV_TRUE;
}
/* move bits within buffer
bitLength bits starting at fromOffset shall be moved to position starting at toOffset */
int
bbMove(HBB bbH,
RvUint32 fromOffset,
RvUint32 bitLength,
RvUint32 toOffset)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
if (fromOffset + bitLength > bbBitsInUse(bbH) ||
toOffset + bitLength > bb->maxOctets*8l)
{ /* no place to hold bits */
bb->isOverflowOfBuffer=RV_TRUE;
return RV_ERROR_UNKNOWN;
}
memcpyb(bb->octets, toOffset, bb->octets, fromOffset, bitLength);
/* update current size */
bb->bitsInUse = RvMax(bb->bitsInUse, toOffset+bitLength);
return RV_TRUE;
}
/*
Desc: Set bits within buffer.
*/
int
bbSet(HBB bbH,
IN RvUint32 fromOffset,
IN RvUint32 bitLength,
IN RvUint8 *src)
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb || !src) return RV_ERROR_UNKNOWN;
if (fromOffset + bitLength > bb->maxOctets*8l)
{ /* no place to hold bits */
bb->isOverflowOfBuffer=RV_TRUE;
return RV_ERROR_UNKNOWN;
}
memcpyb(bb->octets, fromOffset, src, 0, bitLength);
/* update current size */
bb->bitsInUse = RvMax(bb->bitsInUse, fromOffset+bitLength);
return RV_TRUE;
}
int
bbDelTail(HBB bbH,
IN RvUint32 numOfBits) /* to delete from tail of buffer */
{
bbStruct *bb = (bbStruct *)bbH;
int bytes;
RvInt32 newLength, bits;
if (!bb) return RV_ERROR_UNKNOWN;
if (bb->bitsInUse < numOfBits) return RV_ERROR_UNKNOWN;
if (numOfBits == 0) return RV_TRUE;
newLength = bb->bitsInUse - numOfBits;
bytes = bbSetByte(newLength);
bits = (8-newLength%8)%8;
memset(bb->octets+bytes, 0, bb->maxOctets - bytes);
bb->octets[bytes-1] = (RvUint8)(bb->octets[bytes-1] >> bits);
bb->octets[bytes-1] = (RvUint8)(bb->octets[bytes-1] << bits);
bb->bitsInUse = newLength;
return RV_TRUE;
}
/*
Desc: delete bits from head of buffer.
Note: copies, than deletes tail of buffer.
*/
int
bbDelHead(HBB bbH,
IN RvUint32 numOfBits) /* to delete from HEAD of buffer */
{
bbStruct *bb = (bbStruct *)bbH;
if (!bb) return RV_ERROR_UNKNOWN;
if (bb->bitsInUse < numOfBits) return RV_ERROR_UNKNOWN;
memcpyb(bb->octets, 0, bb->octets, numOfBits, bb->bitsInUse-numOfBits);
return bbDelTail(bbH, numOfBits);
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?